00 — Loot Quickstart¶
Goal: See both halves of Loot in one scene: a table rolling exactly the odds you authored, and the awards it produced trying — and in this scene failing — to reach somebody.
What This Scene Demonstrates¶
Loot splits into two verbs, and the scene gives each its own panel:
Roll answers what did you win. Grant answers where did it go.
LootRollPanel calls LootRoller directly. No service, no owner, no Play Mode — that is not a demo shortcut, it is the design, and it is why drop rates can be checked as arithmetic.
LootDeliveryPanel is where a LootService, an owner and real state come in. It reports which adapters are bound and then names which of the three delivery outcomes each award actually reached, read back from the service's own events rather than assumed from the call.
What Is In The Scene¶
| Object | What it is |
|---|---|
Main Camera, Directional Light, Plane | Ordinary scene furniture |
Characters ▸ Player (Visual Only) | The loot recipient. A capsule; nothing is attached to it |
Loot Service | A LootService with all three adapter slots empty, Default Container Backpack, Spawn Pickups off |
Sample Loot Receiver | A SampleLootReceiver — the smallest possible delivery adapter, a list for items and a dictionary for currency. Not bound to anything; binding it is the exercise |
LootRollPanel | Bound to Chest_Weighted, fixed seed 12345, 5000 samples |
LootDeliveryPanel | Bound to the Loot Service, to Purse_IndependentChance, and to Player (Visual Only) as owner. Container left blank |
No inventory adapter, no currency adapter and no pickup spawner are bound, and that is deliberate. It is also what makes the delivery half honest: a scene wired to succeed would teach you what success looks like and nothing about the failure every project meets first. The receiver that could be bound sits in the scene one drag away, because making that drag is the lesson — see Making It Deliver Something below.
Each panel is on its own GameObject. Two panels sharing one object draw into the same screen rect and open stacked and unreadable.
What To Look For¶
Rolling, without entering Play Mode:
- Roll Once — one pull of the chest. Often nothing, because the
Nothingentry carries the largest weight - Sample — thousands of pulls, measured. Compare the observed rates against the authored weights: 60 / 30 / 12 / 8 is relative, not a percentage, and only the sample states behaviour
- Fixed seed — the same seed replays the same roll exactly, which is what makes a surprising result investigable
Delivery, in Play Mode:
- Bound adapters — the panel lists what is actually bound, not what the inspector shows. In this scene: nothing
- Roll And Grant — the purse always rolls gold, so there is always something to deliver. With no currency adapter, the award reaches nowhere and the panel says so: "Rolled, but nothing could be delivered — check the bound adapters above."
- Roll Only, then Grant Last — this is the case worth watching.
Grantreturnsfalse, and the panel distinguishes why: the roll exists and the owner is assigned, so the message names the unbound adapters rather than sending you to check the two things that are already correct. It also notes thatGrantnever spawns, so there was no fallback to the world
The three outcomes the panel is naming are the system's whole delivery contract: Granted for what reached the owner, Spawned for what was dropped into the world instead, and Undelivered for what reached neither.
Sample Scope¶
This scene covers:
- Both roll models — weighted and independent chance
- Relative weights, seeds and reproducibility
- Sampling a table to measure its real rates
- The roll/grant split, and
Grantapplying a result rolled earlier - Which adapters are bound, and what an unbound one costs
- Delivery outcomes reported from the service's events
- A successful delivery — once you bind the
SampleLootReceiveryourself (see below)
This scene does not cover:
- Pickup spawning,
LootPickupPayload, or collect-time granting ILootModifier— no modifier is demonstrated anywhere in Loot's samplesLootDropOnDeathand the Health integration- Persistence — Loot has no save participant, and an uncollected drop does not survive a load
Making It Deliver Something¶
The fastest way is already in the scene. Select Loot Service and drag Sample Loot Receiver into Inventory Adapter and Currency Adapter, then press Play and roll again. The awards that were refused by name now land — Granted instead of Undelivered, read back from the same events by the same panel. That receiver is the whole adapter seam in about twenty lines (SampleLootReceiver.cs, beside this sample): a list, a dictionary, and the one contract that matters — a refused add leaves the container untouched. It starts refusing once its capacity fills, so the Undelivered path stays demonstrable after the bind.
Delivering into the real systems is the same wiring with real services, and is your own wiring rather than part of the sample:
- Add the service the awards should land in — a
SceneInventoryServicefor items, aSceneCurrencyServicefor currency - Add the matching adapter from Add Component ▸ RevFramework ▸ Integrations ▸ Loot ▸ … and assign it to the
Loot Service. The shipped adapters are components, not API — you wire them, you do not construct them - Point
LootDeliveryPanelat a table whose ids resolve in your project
Step 3 is the one that catches people. The example tables use placeholder ids — sample-potion, sample-blade, gold, gems — which resolve to nothing in a fresh project, and nothing before delivery notices that. The roller awards any id that is not blank, and the debugger counts raw id strings without consulting a database, so a placeholder or a typo looks perfectly healthy in a sample of any size. It fails at the adapter, and surfaces as Undelivered.
Which adapters you can add depends on what you own. LootCurrencyAdapter compiles only where Currency is installed, and the Inventory, Pickups & Crafting SKU does not include it — so in that SKU the currency-only purse table this panel is bound to can never deliver, whatever you wire. That is not a fault in the sample; it is the adapter model being visible.
Failure Behaviour¶
Failures here are teaching signals, not bugs to fix:
- Play Mode required — granting mutates real state, so the grant buttons are disabled outside Play Mode. Rolling is not gated
- Assign an owner — with no owner there is nobody to deliver to, and the grant buttons stay disabled
- Nothing could be delivered — the ordinary case in this scene. An unbound adapter is not an error; the awards it would have handled are reported through
Undeliveredrather than dropped in silence - Nothing to grant — pressing Grant Last before any roll. Distinct from the case above, and the panel says which one it is
Behind The Scenes¶
Both panels are hostile consumers: public surface only, no reflection, no internals, and nothing attached to an object they do not own.
LootRollPanel uses LootRoller.Roll and its buffer overload, plus a local IRandomProvider.
LootDeliveryPanel uses LootService.Roll, RollAndGrant, Grant, TryGetInventoryAdapter, TryGetCurrencyAdapter, SpawnPickups and DefaultContainer, and subscribes to Granted, Spawned and Undelivered for the duration of a call — because RollAndGrant returns what the table produced whether or not any of it could be delivered, so its return value cannot answer where the awards went.
Key Takeaway¶
Rolling is a decision. Granting is a consequence, and it can fail on its own.
A table that rolls perfectly and delivers nothing is the most common confusion in this system, and it is almost always an unbound adapter or an id that does not resolve. This scene shows you both, from the outside, through the same API your game will use.
Panels: LootRollPanel, LootDeliveryPanel Scene Path: Assets/RevFramework/Samples/Systems/Loot/Scenes/00_Loot_Quickstart/