02 — Routing, Space, and Currency¶
Goal¶
Understand how routing, output space, and currency affect whether a craft can actually run.
This scene teaches the decision model:
Routing preview explains → Preflight decides → Enqueue proves → Delivery shows the result
What This Scene Demonstrates¶
This scene focuses on three reasons a recipe can be valid, and a bench can allow it, but the craft can still be blocked in practice:
-
Routing Where do the recipe outputs try to go?
-
Space Can those target containers actually accept the outputs?
-
Currency Can the owner afford the recipe cost right now?
The key lesson is:
A routing preview helps explain the setup, but the
CraftingServiceresult is still the truth.
If routing preview, preflight, and enqueue ever disagree, trust the service result.
Demo Router Disclaimer¶
This scene uses TeachingOutputRouter, a teachables-only helper, to make output routing visible.
It supports simple demo modes such as:
- None — router disabled; outputs fall back to the requested/default container
- All To Container — every output routes to one configured container
- By Prefix — outputs route by item id prefix rules
This is educational routing, not a production recommendation.
In a real project, you would provide your own ICraftingOutputRouter implementation if you need custom routing behaviour.
What To Look For¶
The scene separates context from truth:
- Routing Preview shows where base recipe outputs would go through the current demo router.
- Space Preview shows whether those target containers currently have room.
- Currency shows the base recipe cost and current balance.
- Preflight Summary shows what
CraftingServicecurrently allows. - Probe shows the limiting bounds for items, currency, and space.
- Actions attempt to enqueue real craft requests.
The preview is useful, but it is not the final authority.
CanCraftDetailed(), Probe(), and Enqueue() are the service truth.
Routing Preview Limits¶
The routing preview is diagnostic only.
It previews base recipe outputs through the current demo router.
It does not represent every possible delivery-time outcome.
For example, it does not fully account for:
- modifier-added outputs
- chance outputs
- delivery-time inventory changes
- service rules that run later
- custom production routing implementations
That is intentional.
The preview explains what is configured. The service decides what is valid.
Chance Space Policy¶
This scene includes CraftChanceSpacePolicy controls so you can inspect how preflight can reserve space for chance-based outputs.
The available policies are:
- None — only guaranteed outputs are considered
- ExpectedCeil — reserves based on expected value, rounded up
- WorstCaseAll — reserves for every possible chance output
In this sample scene, the visible recipe set may not show a dramatic difference if the selected recipes do not use chance-based outputs.
The important lesson is what the policy controls:
It affects how conservative
CraftingServicepreflight is when chance outputs are present.
Sample Scope¶
This is a demo scene, not a production setup.
It focuses on:
- output routing
- destination containers
- output space checks
- base currency cost
- current balance
- chance space policy
- preflight/probe limits
- enqueue behaviour
It does not focus on:
- benches
- advanced validators
- modifiers
- offline jobs
- persistence
- real inventory/economy integrations
- networking
Those are covered by later specialised scenes.
Authority Note¶
This scene may include a local sample authority setup configured to allow crafting.
That means:
- crafting behaves permissively in this sample
- authority is not the focus of this scene
- this is not a multiplayer or server-authority implementation
To enforce real authority:
- provide an
ICraftingAuthorityimplementation - wire it into
CraftingService - do not rely on simply adding a component to the scene
Networking Reminder¶
RevFramework does not implement:
- networking
- replication
- prediction
- rollback
- reconciliation
These samples demonstrate local behaviour only.
All networking behaviour is your responsibility.
How To Use¶
- Enter Play Mode.
- Open or view the
CraftingRoutingSpaceCurrencyPanel. - Use the Overview tab to inspect the owner, service, default container, station tag, router mode, and active recipe.
-
Use the Routing tab to switch demo routing modes:
-
None
- All To Container
- By Prefix
- Review the routing preview to see where base recipe outputs would go.
-
Use the Space & Currency tab to inspect:
-
chance space policy
- destination space preview
- per-craft currency cost
- current balance
-
Use the Preflight & Actions tab to inspect:
-
single craft result
- requested count result
- probe limits
- service rejection reasons
- Use CanCraft?, Craft 1, Craft N, or Craft Max to test real service behaviour.
- Compare the fake inventory/currency panels after crafting to see where outputs were delivered.
Failure Behaviour¶
Failures are intentional teaching signals in this scene.
Common examples:
- missing items → item inputs limit the craft
- missing currency → currency limits the craft
- no output space → space limits the craft
- bad route target → routed container cannot accept the output
- missing inventory adapter → service cannot check or deliver outputs
- missing currency adapter → the opposite of a failure: the cost check is skipped and a priced recipe crafts for free (see below)
- invalid owner/container/station → service cannot resolve the required context
The important rule is:
A rejected craft creates no job.
If CanCraftDetailed() or Probe() says the craft is blocked, fix the limiting condition before enqueueing.
The one entry above that is not a block¶
Every other line in that list ends in a refused craft. A missing currency adapter does not.
Preflight only computes a currency bound when there is an adapter to ask, so with none bound the bound stays unlimited, NoCurrency never fires, and Probe() reports currency as no constraint at all. Acceptance then skips the debit for the same reason. The craft runs, and the cost on the recipe is charged to nobody.
That is deliberate — crafting without a currency system is a supported configuration, and the FAQ answers Can I use Crafting without Currency? with yes. The hazard is that an adapter you meant to bind and forgot looks identical to one you never wanted, and the symptom is not a blocked craft you would notice. It is a priced recipe quietly costing nothing.
Crafting reports it once per service the first time a priced recipe is crafted with no adapter — but that warning is compiled out of release builds, so treat it as an editor aid rather than the thing that will catch this for you. To see the whole effect, clear the currency adapter field on CraftingService and craft a priced recipe: the panel's guard note changes, Probe() stops naming currency as a bound, and the craft succeeds with the balance untouched.
Behind The Scenes¶
The panel uses public CraftingService APIs and public routing seams, including:
Probe()CanCraftDetailed()CanCraftCount()Enqueue()TryGetInventoryContext()TryGetCurrencyAdapter()SetOutputRouter()SetChanceSpacePolicy()
The panel may create or use a TeachingOutputRouter so routing can be demonstrated visually.
That router is a teaching helper.
It does not override service truth, patch inventory, or fake successful craft results.
Key Takeaway¶
A craft can be blocked even when the recipe itself is valid.
The real question is:
Can this owner craft this recipe right now, with this routing, this space, and this currency balance?
Routing decides where outputs try to go.
Space decides whether those outputs can fit.
Currency decides whether the cost can be paid.
CraftingService combines those constraints during preflight and enqueue.
That is the point of this scene.
Panel: CraftingRoutingSpaceCurrencyPanel Scene Path: Assets/RevFramework/Samples/Systems/Crafting/Scenes/02_Routing_Space_Currency/