Skip to content

🔌 Crafting System — Integration Surfaces

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
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 doesModifier

📦 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

Crafting is responsible for what the data means. Your game is responsible for when and where it is saved.


⚠ Common Mistakes

Avoid the following:

  • 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.