Skip to content

🧠 Crafting System — Mental Model

This page explains how to think about Crafting in RevFramework.

It is not an API reference.
It is a conceptual map that helps you decide:

  • Where does this behaviour belong?
  • Which extension point should I use?
  • What should I never touch?

If you understand this page, the API will feel obvious.


🎯 The Core Idea

Crafting is a controlled execution pipeline with explicit execution semantics, not a UI action.

A craft is not “press a button and spawn items”.

It is a multi‑stage decision and execution flow designed to guarantee:

  • correct validation
  • deterministic outcomes (when desired)
  • safe failure and refund paths
  • authority‑controlled mutation for multiplayer scenarios

Depending on configuration, execution may be best‑effort or escrow‑based.

Everything in the system exists to protect that pipeline.


🧱 The Single Orchestrator

CraftingService

There is exactly one authority on crafting truth:

CraftingService

It owns:

  • job state
  • scheduling
  • timing
  • lifecycle events
  • persistence and offline recovery

Nothing else should:

  • create jobs
  • mutate job state
  • deliver outputs
  • refund currency or inputs

If something outside the service attempts to perform these actions directly, the design boundaries of the system have likely been violated.


🔄 The Crafting Pipeline (Start to Finish)

Every craft flows through the same conceptual stages:

Preflight
  ↓
Accept
  ↓
Schedule
  ↓
Run / Pause
  ↓
Deliver
  ↓
Complete / Fail / Cancel

Each stage has specific extension points and clear responsibilities.


🔍 Stage 1: Preflight (Pure Decision)

Question: “Can this craft happen right now?”

Preflight:

  • never mutates state
  • never consumes items or currency
  • is safe to call from UI, tools, and teachables

Preflight evaluation order

The system evaluates checks in this order:

  1. Inputs (inventory)
  2. Currency
  3. Space (including routing and chance-space policy)

If these checks do not return early, validators are applied to the proposed result.

Extension points used here

  • ICraftingValidator
  • ICraftingLevelSource
  • Station tag filters
  • Output routing (for space checks)

What does NOT belong here

  • spawning items
  • consuming resources
  • mutating cooldown state
  • creating jobs

Preflight answers possibility, not execution.


✅ Stage 2: Accept (Execution Boundary)

Question: “We are committing — do we proceed?”

Accept is the stage where:

  • authority is checked
  • resources are consumed or reserved
  • a CraftJob may be created

This is the commit boundary for crafting execution.

Execution modes at accept

Accept behaves differently depending on execution mode.

Best‑effort (default)

  • Inputs and currency are consumed immediately
  • Delivery may fail later
  • Failures attempt to compensate with refunds where possible

This mode is designed for typical single‑player or non‑critical economies.

Escrow (opt‑in)

  • Inputs and currency are reserved
  • Nothing is consumed until delivery is guaranteed
  • Commit is intended to be atomic when adapter invariants are honoured

Escrow mode requires adapters that support reservations/holds.

Extension points here

  • ICraftingAuthority
  • ICraftingModifier (first evaluation pass)

Design rule

If something consumes or reserves resources, it belongs here, not in UI or benches.


🗂️ Craft Jobs (The Durable Unit)

A CraftJob represents a durable crafting operation.

It records:

  • the owner performing the craft
  • the recipe
  • execution timing
  • payment state
  • progress and lifecycle state

Jobs are created only through:

CraftingService.Enqueue(...)

Jobs:

  • can be queued
  • can be paused
  • can survive save/load
  • can complete offline

You never “fake” a job. You either create one through the service — or not at all.



💾 Persistence (Save / Load Responsibility)

Crafting supports persistence through job snapshots:

  • SaveActiveJobs(...)
  • RestoreJobs(...)

These APIs define:

  • what data to persist (active jobs)
  • how jobs resume and progress (including offline behaviour)

They do not provide a persistence system.

Crafting defines the job model and lifecycle — your game defines persistence.


🧠 Responsibility Split

  • 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)
  • Ensures identifiers remain stable across sessions
  • Calls restore at the correct time in your lifecycle

🧩 Conceptual Flow

Game Save:
  → SaveActiveJobs(...)
  → Store snapshot

Game Load:
  → Load snapshot
  → RestoreJobs(...)

⚠️ Design Rule

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


🔁 Offline Progress Context

Offline progression is applied during restore using:

  • acceptedAtUtc
  • IWallClockProvider

This means:

  • Jobs may complete while the game is closed
  • Jobs may partially progress
  • Jobs may resume

depending on elapsed real-world time and configuration


⏱️ Stage 3: Scheduling & Time

Scheduling answers questions such as:

  • When can this craft run?
  • How many jobs can run in parallel?
  • Does a station have available capacity?

Time is abstracted through two providers:

  • ITimeProvider → gameplay time
  • IWallClockProvider → real UTC time

Why two time sources exist

Time Source Purpose
Game time (ITimeProvider) Live gameplay ticking
Wall clock (IWallClockProvider) Offline progress calculation

Design rule

Time is data, not a direct call to UnityEngine.Time.

This abstraction enables deterministic testing and offline completion.


▶️ Stage 4: Run / Pause

While running:

  • progress events are emitted
  • no additional resources are consumed
  • modifiers may be re‑evaluated later at delivery

Pausing:

  • freezes remaining time
  • never re‑consumes inputs
  • never re‑debits currency

Job state always lives inside the service.


📦 Stage 5: Delivery (Final Commit)

Delivery attempts to produce the final outputs.

Steps:

  1. Re‑evaluate modifiers
  2. Resolve output routing
  3. Attempt to add outputs
  4. Finalise craft outcome

Delivery semantics

Best‑effort

  • Outputs are attempted
  • Delivery failure refunds currency
  • Inputs may be refunded depending on service policy and container availability.

Escrow

  • Outputs are committed atomically
  • Delivery either fully succeeds or nothing is applied

If delivery fails:

  • currency is refunded or released
  • inputs may be refunded or released (mode‑dependent)
  • the job ends in Failed

Extension points used here

  • ICraftingOutputRouter
  • ICraftingModifier (delivery pass)

🧠 Validators vs Modifiers

Understanding this distinction is critical.

Validators

Validators answer:

“Should this craft be allowed?”

They:

  • modify maxCrafts
  • block crafting with a reason
  • never mutate state

Examples:

  • cooldowns
  • level gates
  • progression locks

Modifiers

Modifiers answer:

“How does this craft behave?”

They:

  • adjust duration
  • scale currency cost
  • add or alter outputs
  • run twice (accept and delivery)

Rule of thumb:

  • If it blocks permission, it is a validator.
  • If it changes numbers, it is a modifier.

🔌 Adapters (External Systems)

Crafting does not talk directly to other gameplay systems.

Instead it integrates through adapters:

  • ICraftingInventoryAdapter
  • ICraftingCurrencyAdapter
  • ICraftingInventoryReservationAdapter
  • ICraftingCurrencyHoldAdapter

Adapters allow Crafting to remain:

  • modular
  • testable
  • multiplayer‑ready

If you feel tempted to access inventory directly from crafting logic, you are bypassing the system’s safety model.


⚖️ Execution Modes

Crafting supports two execution semantics.

Best‑Effort (Default)

Designed for most games.

Characteristics:

  • immediate resource consumption
  • compensating refunds if delivery fails
  • simple and fast execution

Escrow (Opt‑In)

Designed for multiplayer or economy‑critical systems.

Characteristics:

  • resource reservation
  • atomic commit guarantees
  • strict adapter requirements

Both modes use the same pipeline. Only the transaction guarantees differ.


🧰 Built‑in Component Roles

Use this mental map when extending the system.

Component Responsibility
Workbenches Provide input and context
Validators Permission rules
Modifiers Behaviour adjustments
Routers Output destination decisions
Service Execution and truth

If a component crosses these roles, it is probably misplaced.


🚫 What Never Belongs Where

  • Benches should never consume items
  • Validators should never spawn outputs
  • Modifiers should never check authority
  • UI should never mutate job state
  • Anything outside the service should never issue refunds

These boundaries keep the system predictable and safe.


🧠 The One‑Sentence Model

Crafting is a job‑based execution pipeline with strict boundaries and explicit execution semantics.


TL;DR

  • One orchestration service
  • Pipeline: preflight → accept → job → delivery
  • Validators block, modifiers shape
  • Adapters isolate external systems
  • Execution semantics are explicit