Skip to content

Crafting — Workbenches

This folder contains trigger-based crafting benches for both 2D and 3D scenes.

Workbenches allow players to walk up to a station, hold a key, and enqueue crafts directly in-game without any custom UI. They are optional helpers designed for demos, prototypes, and quick testing — not required for production use.

Everything here reflects actual runtime behaviour, with additional Editor-only guardrails and teaching conveniences clearly isolated.

⚠️ These components live in the Integrations layer and are only present when relevant optional systems are installed.


Purpose

Workbench components provide:

  • Ready-made, interactive crafting stations
  • Automatic integration with input, recipes, and CraftingService
  • Separate 2D (Collider2D) and 3D (Collider) variants
  • Hold-to-craft behaviour with configurable repeat cooldown
  • Full respect for:
  • modifiers
  • validators
  • station tags
  • routing
  • XP
  • concurrency limits

Workbenches are thin orchestration helpers — they do not add new crafting rules and are not a core extension surface.

They exist as Unity-facing helpers for integrated usage, not as part of the Crafting runtime API.


Multiplayer & Authority

Workbench components are authority-aware but netcode-agnostic.

By default (serverOnly = true):

  • Preflight (CanCraft / CanCraftDetailed) may run anywhere (client or server)
  • Mutation (Enqueue) is permitted only when authority allows

Authority Resolution Order (Exact)

  1. ICraftingBenchAuthority assigned directly to the bench
  2. ICraftingAuthority assigned to CraftingService
  3. If neither exists → enqueue is denied

This makes workbenches safe for:

  • Single-player projects
  • Server-authoritative multiplayer (NGO, Mirror, Fusion, custom RPCs)

⚠️ Workbenches do not perform networking.
In multiplayer, they should be executed on the server/host or guarded by an authority implementation.


Included Benches

CraftingWorkbench2D

  • Uses OnTriggerStay2D to detect presence
  • Hold the craft key (default: F) to enqueue the selected recipe
  • Supports repeated crafting via repeatCooldown
  • Optional stationTagFilter restricts which recipes may be crafted
  • Uses the entering collider’s GameObject as the craft owner

CraftingWorkbench3D

Identical behaviour to the 2D variant, with additional owner resolution logic:

  1. If preferTaggedPlayerOwner is enabled and a GameObject tagged "Player" exists → it is used as the owner
  2. Otherwise, prefer other.attachedRigidbody.gameObject
  3. Fallback to other.gameObject

This matches common player-controller setups without requiring custom glue code.


Recipe Resolution (Supported API Only)

Workbench recipe fields are typed as:

[SerializeField] ScriptableObject[] recipes;

At runtime, each recipe is resolved exclusively via the supported public API:

RecipeResolve.ResolveOrNull(scriptableObject);

Behaviour:

  • If the asset is a RecipeCore, it is used directly
  • If the asset is a Unity-facing wrapper (e.g. RecipeDefinition):
  • Conversion succeeds only when the relevant optional systems are present
  • Otherwise resolution returns null
  • If resolution fails:
  • The craft is rejected safely
  • Editor warnings may be logged for visibility

Workbenches do not call RecipeCache or ToCore() directly.
All conversion, caching, and optional-system logic is intentionally hidden behind RecipeResolve.


⌨ Input Handling

Craft input is resolved in this order:

  1. If inputServiceComponent implements IInputService
    → that service is used

  2. Otherwise:

  3. In Editor or with RAB_DEMO defined → fallback to DebugKeys
  4. In player builds, with no input service → no input is processed

⚠️ In production builds, an IInputService must be supplied for benches to respond to input.

Input is checked every trigger frame while the player remains inside the collider.


Editor Guardrails

Workbench components include Editor-only validation and warnings:

  • Enforce collider.isTrigger = true
  • Warn if:
  • recipe list is empty
  • recipeIndex is out of range
  • stationTagFilter does not match the selected recipe’s station tag
  • a recipe asset cannot be resolved in the current build configuration

All guardrails run only in the Editor.


Station Tag Behaviour

Workbenches supply explicit preflight options:

var opts = new CraftPreflightOptions(null, stationTagFilter);

This means:

  • ctx.stationTag is forced to stationTagFilter during preflight and enqueue
  • If stationTagFilter is set and does not match the recipe’s own StationTag, the bench rejects the recipe before preflight

This allows benches to act as explicit station-gated crafting points while still respecting recipe metadata.


Usage Flow

  1. Add a 2D or 3D workbench to the scene
  2. Assign (or auto-resolve) a CraftingService
  3. Provide one or more recipe assets
  4. Player enters the trigger and holds the craft key
  5. Bench performs:
  6. CanCraft(owner, recipe, opts)
  7. Authority check
  8. Enqueue(new CraftRequest(...))

All CraftingService behaviour applies automatically:

  • Modifiers
  • Validators
  • Routing
  • Currency rules
  • XP rules
  • Concurrency limits

Notes

  • Workbenches are optional helpers — not required for gameplay
  • Ideal for demos, prototypes, and test scenes
  • Production games typically drive crafting from custom UI
  • Workbenches exercise the entire Crafting pipeline without additional glue code

Workbenches provide a practical, low-friction way to interact with the full Crafting system while keeping all authoritative logic inside CraftingService.