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.
🎯 Purpose¶
Workbench components provide:
- Ready-made, interactive crafting stations
- Automatic integration with input, recipes, and
CraftingServiceCore - 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 an integration or extension surface.
🌐 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)¶
ICraftingBenchAuthorityassigned directly to the benchICraftingAuthorityassigned toCraftingServiceCore- 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
OnTriggerStay2Dto detect presence - Hold the craft key (default: F) to enqueue the selected recipe
- Supports repeated crafting via
repeatCooldown - Optional
stationTagFilterrestricts which recipes may be crafted - Uses the entering collider’s
GameObjectas the craft owner
CraftingWorkbench3D¶
Identical behaviour to the 2D variant, with additional owner resolution logic:
- If
preferTaggedPlayerOwneris enabled and a GameObject tagged"Player"exists → it is used as the owner - Otherwise, prefer
other.attachedRigidbody.gameObject - 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
RecipeCacheorToCore()directly.
All conversion, caching, and optional-system logic is intentionally hidden behindRecipeResolve.
⌨️ Input Handling¶
Craft input is resolved in this order:
-
If
inputServiceComponentimplementsIInputService
→ that service is used -
Otherwise:
- In Editor or with
RAB_DEMOdefined → fallback toDebugKeys - In player builds, with no input service → no input is processed
⚠️ In production builds, an
IInputServicemust 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
recipeIndexis out of rangestationTagFilterdoes 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.stationTagis forced tostationTagFilterduring preflight and enqueue- If
stationTagFilteris set and does not match the recipe’s ownStationTag, 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¶
- Add a 2D or 3D workbench to the scene
- Assign (or auto-resolve) a
CraftingServiceCore - Provide one or more recipe assets
- Player enters the trigger and holds the craft key
- Bench performs:
CanCraft(owner, recipe, opts)- Authority check
Enqueue(new CraftRequest(...))
All CraftingServiceCore 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 CraftingServiceCore.