Crafting System — Integration Surfaces¶
Where new logic goes
This page explains where new gameplay logic should integrate with the RevFramework Crafting system.
If you're adding a new mechanic, start here.
The Crafting architecture is intentionally modular. Each behaviour belongs to a specific extension surface. Choosing the correct surface keeps crafting predictable, testable, and compatible with the rest of the framework.
Extension Surfaces Overview¶
| Goal | Extension Point | Example |
|---|---|---|
| Allow or block crafting | ICraftingValidator | cooldown, level gate, progression lock |
| Change craft behaviour | ICraftingModifier | speed bonus, bonus outputs, currency scaling |
| Connect inventory | ICraftingInventoryAdapter | backpack, chest, custom inventory backend |
| Connect currency | ICraftingCurrencyAdapter | gold, credits, custom wallet service |
| Report a refund the wallet refused | ICraftingCurrencyCreditReporter | cap, ceiling or authority declining a credit |
| Add strong reservation semantics | ICraftingInventoryReservationAdapter / ICraftingCurrencyHoldAdapter | escrow / atomic immediate crafting |
| Route outputs to containers | ICraftingOutputRouter | ore box, herb pouch, overflow container |
| Control mutation authority | ICraftingAuthority | server authority, host-only crafting |
| Provide optional level data | ICraftingLevelSource | progression gate, account level |
| Drive gameplay / UI flow | Your own code calling CraftingService | buttons, workbenches, recipe menus |
Example Decision Flow¶
Cooldown Between Crafts¶
Use:
ICraftingValidator
Cooldowns decide whether crafting is allowed right now, so they belong in validation.
Faster Crafting Bench¶
Use:
ICraftingModifier
A bench that changes craft duration is modifying how the craft behaves, not whether it is permitted.
Bonus Rare Drop¶
Use:
ICraftingModifier
Rare or conditional extra outputs belong in modifier logic through CraftAdjustments.extraOutputs or CraftAdjustments.chanceOutputs.
Route Ores to a Separate Container¶
Use:
ICraftingOutputRouter
Routing decides where outputs go, not whether the craft is allowed.
Server-Authoritative Crafting¶
Use:
ICraftingAuthority
Authority determines who may mutate crafting state. It does not perform replication.
Connect to Your Inventory System¶
Use:
ICraftingInventoryAdapter
Crafting should not know your inventory internals directly.
Atomic Immediate Crafting¶
Use:
ICraftingInventoryReservationAdapter
ICraftingCurrencyHoldAdapter
Escrow crafting requires reservation/hold-capable adapters. Without them, the strong path refuses to run.
Validators vs Modifiers¶
Validators control permission. Modifiers control behaviour.
| Behaviour | Correct Surface |
|---|---|
| Cooldown | Validator |
| Level requirement | Validator |
| Station tag requirement | Validator |
| Craft time scaling | Modifier |
| Currency scaling | Modifier |
| Bonus output | Modifier |
| Chance output | Modifier |
Rule of thumb
- If it changes whether the craft can proceed → Validator
- If it changes what the craft does → Modifier
Routing vs Inventory¶
Routing decides which container should receive outputs. Inventory adapters decide how containers are resolved and mutated.
| Behaviour | Correct Surface |
|---|---|
| Send herbs to HerbPouch | Output Router |
| Count items in Backpack | Inventory Adapter |
| Add crafted item to container | Inventory Adapter |
| Choose destination container for output | Output Router |
If you find yourself writing container-selection logic inside an inventory adapter, the responsibility is probably in the wrong place.
Best-Effort vs Escrow¶
Crafting supports two execution styles.
Best-Effort (Default)¶
Use the normal CraftingService.Enqueue(...) pipeline when:
- immediate consumption is acceptable
- delivery failure can be compensated
- you do not require strict atomicity
Escrow (Opt-In)¶
Use TryCraftImmediateEscrow(...) when:
- the craft is immediate (
duration == 0) - your adapters can reserve inputs and hold currency
- atomic immediate execution matters
Escrow is an adapter capability question, not a validator or modifier concern.
Persistence (Save / Load)¶
Crafting supports snapshot-based persistence via:
SaveActiveJobs(...)
RestoreJobs(...)
These APIs define:
- what data to persist (active jobs)
- how jobs resume (including offline progress)
They do not provide a persistence system.
Responsibility Model¶
-
CraftingService
-
Owns job state
- Owns timing and offline progression
-
Owns how jobs resume and complete
-
Your Game
-
Decides when to save
- Decides where to store data (file, cloud, database)
- Provides ID resolution (owner / recipe)
- Calls restore at the correct time in your lifecycle
Example Integration Flow¶
Game Save:
→ SaveActiveJobs(...)
→ Store snapshot in your save system
Game Load:
→ Load snapshot
→ RestoreJobs(...)
Important Notes¶
-
Snapshots are data only — they do not resolve objects automatically
-
You must provide:
-
ownerResolver -
recipeResolver -
Offline progress depends on:
-
acceptedAtUtc - your configured
IWallClockProvider
Design Rule¶
Design rule
Crafting is responsible for what the data means. Your game is responsible for when and where it is saved.
Common Mistakes¶
Common mistakes to avoid
- Mutating inventory or currency directly from validators
- Performing authority logic inside modifiers
- Treating routing as an inventory concern
- Consuming inputs outside
CraftingService - Using UI or workbenches to fake job state
- Assuming escrow applies to timed crafts
- Assuming validators can override failed space preflight
Architecture Summary¶
Preflight
├─ Inventory Adapter
├─ Currency Adapter
├─ Output Router (space checks)
├─ Modifiers (adjustments)
└─ Validators
↓
Accept / Commit Boundary
├─ Authority
├─ Inputs / Currency consumed or reserved
└─ Job created (standard path only)
↓
Job / Schedule / Time
↓
Delivery
├─ Modifiers (delivery pass)
├─ Output Router
└─ Inventory Adapter
Every extension surface plugs into one of these stages.