Skip to content

Loot — FAQ

My table drops nothing

The table rolls, but nothing appears in the inventory

Check in this order, because they are ordered by how often they are the answer:

  1. Is an Inventory Adapter assigned on the LootService? No adapter means item awards are not delivered. Nothing errors — that is the supported configuration for a project without Inventory.
  2. Are the item GUIDs right? Nothing validates them. A typo'd GUID is an entry that never drops, silently and for ever. Sample the table in the debugger: an authored entry missing from a large sample is telling you its id does not resolve.
  3. Is the quantity what you meant? A row added in the inspector starts at zero, and the roller treats anything below one as one — so a forgotten quantity drops a single item rather than nothing. An entry that should sometimes award nothing is a Nothing row or a chance, never a quantity.
  4. Is the container right? Item awards go to DefaultContainer ("Backpack") unless you pass one. A container name that does not exist on the owner delivers nothing.

It says it delivered, but the player has nothing

Check which event you are listening to. Rolled fires with the whole roll, before anything is granted — driving UI from it announces things the player may never receive.

Granted carries only what actually landed. That is the one to drive a "you received" toast from.

Everything drops except one entry

Almost always a bad id on that entry. See above — sample it rather than reading the weights.

Odds

My weights are not producing the percentages I expect

Weights are relative within one table, not percentages. 1 against 3 is identical to 25 against 75.

If the numbers still look wrong, check whether the table nests. A nested table does not share the parent's weight pool — the nested entry competes at the parent's level, then the nested table rolls its own weights independently. End-to-end odds across nesting are not the product of the printed numbers in any way you can compute by hand, which is why the debugger samples.

How do I make "nothing" a possible outcome?

Add an entry of kind Nothing and give it weight, in a weighted table. Or use an IndependentChance table, where every entry is its own coin flip and all of them can decline.

Do not express it with a zero quantity — the roller treats a quantity below one as one, so that row keeps dropping a single item and reads as a broken table.

How do I add luck, magic find, or a pity counter?

You cannot, today, without editing LootRoller. ILootModifier runs against the result, so it can double a currency award or swap an item, but it cannot make a rare entry more likely.

This is deliberate — a table whose printed weights do not describe its behaviour is very hard to reason about — and it is also the most likely reason a project outgrows this system. Decide whether you need odds-shaping before you design around it.

Are drops reproducible?

UseDeterministicRng(seed) repeats a sequence within a build. It does not survive changes to the table: adding an entry, reordering rows or changing a quantity range changes what that seed produces.

Never store a loot seed as a save-compatible record of "which sword the player got".

Delivery

The player's bag was full — where did the item go?

If a Pickup Spawner is bound, at their feet: spawning is a fallback, not only a mode, so a refused award is dropped into the world even with Spawn Pickups off. That is what most games do with a full bag, and it is recoverable by the player.

If no spawner is bound, the award is reported through Undelivered and is gone. Subscribe to it if that matters — mail it, queue it, or just tell the player their bag is full. Nothing is retried automatically, because where an undeliverable award should go is a design decision.

Grant returned false but I definitely rolled something

Grant returns true only when at least one award actually reached the owner — not when there was merely something to deliver. A false with a non-empty result means nothing landed: no adapter, a full container, or an id that did not resolve.

A collected pickup spawned another pickup

That should be impossible: Grant never spawns, whatever SpawnPickups is set to, precisely so a pickup granting on collect cannot produce another.

If you are seeing it, you are probably calling RollAndGrant on collect rather than Grant. The pickup should apply the award it is already carrying, not roll a new one.

My spawned pickup does nothing when collected

LootPickupPayload must be on the prefab, not added to the instance after Instantiate. TriggerRelay3D resolves its receiver during Awake, which has already run by the time Instantiate returns — a payload added afterwards is never found.

My boss dropped its loot twice

LootDropOnDeath guards against this, because Health can raise Died more than once across a revive cycle. If you are pooling enemies and want a re-killed enemy to drop again, call ResetDropGuard() when you revive it.

Setup and structure

Which package is Loot in?

The Inventory, Pickups & Crafting SKU, and Complete. A drop table's output has to land in a container, so it belongs to the purchase that provides one.

Do I need Inventory and Currency both?

No. Each adapter is optional and independent. Awards of a kind you cannot deliver are simply not delivered, and the roll is unchanged.

Can I roll without a LootService at all?

Yes — LootRoller.Roll(table, rng) is static and dependency-free. You get a LootResult and deliver it yourself. The service exists to run modifiers and adapters, not because rolling needs it.

Where is the sample?

Samples/Systems/Loot/Scenes/00_Loot_Quickstart, with two teaching panels: LootRollPanel for odds and LootDeliveryPanel for where awards land. Open the scene and press Play.

How do I check a table is doing what I think?

Window ▸ RevFramework ▸ Loot ▸ Debugger. It rolls thousands of times against a fixed seed and shows what actually dropped against what you authored.

Do this before shipping any table. Weights describe intent; only sampling describes behaviour.