Skip to content

Crafting / Core / Recipe

Purpose

This folder defines the pure recipe domain for the Crafting system.

Types in Recipe describe what a craft is — inputs, outputs, optional currency, and metadata — without knowing how crafting is executed or which systems are present at runtime.

Recipes are intentionally: - implementation-agnostic - immutable at runtime (by contract) - safe to inspect from any layer

They form the stable data contract between content, gameplay, and the crafting service.


What lives here

RecipeCore

  • RecipeCore
  • A pure ScriptableObject representing a single craft recipe.
  • Contains only:
    • item inputs
    • item outputs
    • optional currency cost
    • optional station tag
    • optional XP metadata
    • optional duration

RecipeCore has no dependency on: - inventory implementations - currency systems - UI - crafting services

At runtime, recipes must be treated as immutable by convention.
Mutating recipe contents during gameplay is not supported.


Supporting value types

  • ItemRef
  • Canonical item GUID + quantity pair.

  • ChanceItemRef

  • Probabilistic output definition (rolled per craft).

  • CurrencyCost

  • Optional currency cost per craft.

These are small, serializable value types with no behaviour.


Recipe resolution seam

  • RecipeResolve
  • The only supported public entry point for resolving a recipe.
  • Accepts a ScriptableObject and attempts to produce a RecipeCore (failure is expected and must be handled).

This exists to: - shield callers from optional systems and compile-time defines - hide internal conversion and caching - provide a stable seam for Teachables and runtime UI

Callers must not rely on internal conversion helpers directly.


What does NOT belong here

  • Inventory logic
  • Currency logic
  • Crafting execution rules
  • Caching strategies (except internal helpers)
  • Game-specific progression or unlock rules

If a type needs to do something, it does not belong here.


Public vs Internal

Public / supported - RecipeCore - ItemRef - ChanceItemRef - CurrencyCost - RecipeResolve

Internal / framework-only - Recipe/Internal/RecipeCache

Only the public surface is guaranteed to remain stable.


Usage rules

For content authors

  • Create recipes as RecipeCore assets.
  • Treat recipe data as immutable once the game is running.
  • Use station tags and metadata; do not encode logic in recipes.

For gameplay code & UI

  • Always resolve recipes via RecipeResolve.
  • Handle resolution failure gracefully (feature not present, optional systems missing).
  • Never assume a recipe can always be resolved in every build.

Public API guarantee

Types in this folder are part of the supported public API.

  • Fields may be added over time.
  • Existing semantics will not silently change.
  • Removal or breaking changes require a major version bump.

Teachables compile against this surface to enforce discipline.


Design notes

  • Recipes are data, not behaviour.
  • Behaviour lives in services, modifiers, and validators.
  • Resolution is explicit and failure-aware.

If you need conditional behaviour, add a validator or modifier — not logic inside the recipe.