diff options
| author | historia <[not public]> | 2026-07-09 16:09:35 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-09 16:09:35 -0400 |
| commit | b8c90886ef1f3afb8d908aac89028bd177836cae (patch) | |
| tree | 7e566a7e308e7531bbb7d6a3a39239e789f69a3c /building_guide/recipes.md | |
| parent | c705ae942573984784ef501bf8198f61f5206ddd (diff) | |
| download | thehouseoficarus-b8c90886ef1f3afb8d908aac89028bd177836cae.tar.gz | |
feat(admin): multi-select with shift+drag for common bulk operations
Diffstat (limited to 'building_guide/recipes.md')
| -rw-r--r-- | building_guide/recipes.md | 215 |
1 files changed, 104 insertions, 111 deletions
diff --git a/building_guide/recipes.md b/building_guide/recipes.md index 96bf0f9..67048c1 100644 --- a/building_guide/recipes.md +++ b/building_guide/recipes.md @@ -1,74 +1,97 @@ -# The House of Icarus - World Building Guide +## Crafting & Recipes -## Crafting +Crafting information lives on the **output item's YAML file** via the `craft:` block. There is no +separate recipe directory. To find out how to make `bronze_dagger`, open +`data/items/equipment/bronze_dagger.yaml` and look for the `craft:` block. -Crafting information lives on the **output item's YAML file** via the `craft:` block. There is no separate recipe directory. To find out how to make `bronze_dagger`, open `data/items/equipment/bronze_dagger.yaml` and look for the `craft:` block. (The item's **filename is its ID** — `bronze_dagger.yaml` → `bronze_dagger`; there is no `id:` field. `ingredients`/output entries reference items by filename.) +**The filename is the ID** (`bronze_dagger.yaml` → `bronze_dagger`). Ingredients reference items by +filename. The output item IS the craft — no separate `output` field. ### Craft YAML Reference -| Field | Type | Description | -| -------------- | -------------- | ----------------------------------------------- | -| `type` | string | Craft type (smithing, cooking, crafting, fletching, pharmacy, construction, combine, or "" for skill-less). Always matches a player skill name. | -| `subtype` | string | Production method override (`smelt` for furnace recipes, `clean` for herb cleaning). Defaults empty (no override). | -| `level` | int | Required skill level | -| `xp` | int | XP awarded on success | -| `wait` | float64 | Ticks per craft cycle | -| `station` | []string | Station object IDs required (optional) | -| `tool` | string | Required tool_type (optional) | -| `ingredients` | []IngredientEntry | Ingredients consumed (see below) | -| `output_qty` | int | Quantity produced (default 1, for stackables) | -| `fail` | string | ItemID produced on failure (optional) | -| `success_message` | string | Success message per cycle (optional, see message defaults) | -| `fail_message` | string | Failure message (optional, empty = silent fail) | -| `start_message`| string | Message when action begins (optional, see message defaults) | -| `end_message` | string | Message when action completes (optional, see message defaults) | -| `steps` | []CraftStep | Multi-step messages at tick intervals (optional)| -| `success` | SuccessFormula | Optional skill check formula (see Behaviors) | - -The output is the item itself — no `output` field needed. The item ID IS the craft ID. +| Field | Type | Description | +|-------|------|-------------| +| `type` | string | Skill name: `smithing`, `cooking`, `crafting`, `fletching`, `pharmacy`, `construction`, or `""` for skill-less. | +| `subtype` | string | Production method override: `smelt` for furnace, `clean` for herb cleaning. | +| `level` | int | Required skill level | +| `xp` | int | XP awarded on success | +| `ticks_per_cycle` | float64 | Ticks per craft cycle | +| `station` | []string | Station object IDs required (e.g. `[anvil]` or `[furnace]`) | +| `tool` | string | Required tool_type (e.g. `knife`, `saw`). Tool is NOT consumed. | +| `ingredients` | []IngredientEntry | Ingredients consumed (see below) | +| `output_qty` | int | Quantity produced per cycle (default 1) | +| `fail` | string | Item ID produced on failure | +| `success_message` | string | Success message per cycle (%n, %i1, %i2, %b1, %b2) | +| `fail_message` | string | Failure message; empty = silent fail | +| `start_message` | string | Message when action begins | +| `end_message` | string | Message when action completes | +| `steps` | []CraftStep | Multi-step messages at tick offsets | +| `success` | SuccessFormula | Optional skill check formula (base, per_level, cap) | ### Message Variables -All message fields (`success_message`, `fail_message`, `start_message`, `end_message`, and `steps[].message`) support variables that expand to colorized item names: +| Variable | Expands to | +|----------|-----------| +| `%n` | Output item name (colored) | +| `%i1` | 1st ingredient's matched item (colored) | +| `%i2` | 2nd ingredient's matched item (colored) | +| `%b1` | 1st ingredient's byproduct name (colored, success only) | +| `%b2` | 2nd ingredient's byproduct name (colored, success only) | -| Variable | Expands to | -| -------- | ----------------------------------------------- | -| `%n` | Output item name (colored, e.g. "stim potion") | -| `%i1` | 1st ingredient entry's matched item (colored) | -| `%i2` | 2nd ingredient entry's matched item (colored) | -| `%b1` | 1st byproduct item name (colored, success only) | -| `%b2` | 2nd byproduct item name (colored, success only) | - -Numbering follows YAML ingredient/byproduct order. If an ingredient entry has multiple alternative items (`items: [a, b]`), the variable expands to whichever the player actually possesses, colored with that item's `color:` field. - -Variables work alongside inline color tags (`{C4}text{/}`) which are expanded after variable substitution. +Numbering follows YAML ingredient/byproduct order. If an ingredient entry has multiple +alternatives (`items: [a, b]`), the variable expands to whichever the player has. Inline +color tags (`{C4}text{/}`) work alongside these variables. ### Message Defaults -If a message field is omitted from the YAML, the game uses a skill-level default based on the craft `type`: +If a message field is omitted, the game uses a skill-level default: -| Type | Default `success_message` | Default `start_message` | -|------|-------------------|------------------------| +| Type | Default success_message | Default start_message | +|------|------------------------|----------------------| | `cooking` | `"Cooked to perfection. %n looks great!"` | `"You start cooking %i1."` | -| `smelt` | `"You remove a white hot %n!"` | `"You place the %i1 into the furnace."` | +| `smelt` (subtype) | `"You remove a white hot %n!"` | `"You place the %i1 into the furnace."` | | `smithing` | `"You smith a %n."` | `"You begin smithing %i1."` | | `crafting` | `"You craft a %n."` | `"You begin crafting %i1."` | | `fletching` | `"You fletch a %n."` | `"You begin fletching %i1."` | | `pharmacy` | `"You mix a %n."` | `"You start mixing %i1."` | | `construction` | `"You construct a %n."` | `"You begin constructing %i1."` | -| `clean` | `"You clean the %i1."` | `"You begin cleaning herbs."` | +| `clean` (subtype) | `"You clean the %i1."` | `"You begin cleaning herbs."` | | (unset) | `"You produce %n."` | `"You start <verb> %i1."` | -Default messages are keyed by `subtype` when set, otherwise by `type`. For skills that never fail (smithing, crafting, fletching, pharmacy, construction), `fail_message` defaults to empty — no message is shown on failure. +For skills that never fail (smithing, crafting, fletching, pharmacy, construction), +`fail_message` defaults to empty — no message on failure. + +### IngredientEntry — Multi-Item Ingredient Slots + +Each ingredient entry defines a slot with multiple valid alternatives. The first matching +item in the player's inventory is consumed. + +```yaml +ingredients: + - items: [item_id, alternative_id, ...] + quantity: 1 + byproducts: [byproduct_for_item, byproduct_for_alt, ...] +``` + +`byproducts` matches the `items` list by index. Use `""` for items with no byproduct: + +```yaml +ingredients: + - items: [bucket_of_water, vial_of_water] + quantity: 1 + byproducts: [empty_bucket, ""] # bucket returns empty, vial is consumed entirely + - items: [herb] + quantity: 1 # no byproducts — herb is consumed entirely +``` ### CraftStep — Multi-Step Messages -Optional interim messages fired at specific tick offsets during the craft cycle. The `tick` is the number of ticks elapsed since the start of the cycle. +Interim messages fired at specific tick offsets during the cycle: ```yaml craft: type: "" - wait: 6 + ticks_per_cycle: 6 ingredients: - items: [map_piece_1] quantity: 1 @@ -84,105 +107,90 @@ craft: success_message: "You assemble the map!" ``` -### IngredientEntry — Multi-Item Ingredient Slots - -Each ingredient entry defines an ingredient slot with multiple valid items. The first matching item found in the player's inventory is consumed. - -```yaml -ingredients: - - items: [item_id, alternative_id, ...] - quantity: 1 - byproducts: [byproduct_for_item, byproduct_for_alt, ...] -``` - -`byproducts` is optional. When present, it matches the `items` list by index — consuming `items[0]` returns `byproducts[0]` to inventory. Use `""` for items with no byproduct: - -```yaml -ingredients: - - items: [bucket_of_water, vial_of_water] - quantity: 1 - byproducts: [empty_bucket, ""] # bucket returns empty, vial is consumed entirely - - items: [herb] - quantity: 1 # no byproducts — herb is consumed entirely -``` - ### Skill-Based Production ```yaml # data/items/consumables/stim_potion.yaml +name: stim potion craft: type: pharmacy level: 3 xp: 25 - wait: 4 + ticks_per_cycle: 4 ingredients: - items: [guam_potion_unf] quantity: 1 - items: [eye_of_newt] quantity: 1 - success_message: "You mix a %n." # %n expands to "stim potion" colored + success_message: "You mix a %n." ``` ### Station-Based Production +Furnace (smelting): + ```yaml # data/items/materials/bronze_bar.yaml +name: bronze bar craft: type: smithing subtype: smelt level: 1 xp: 6 - wait: 4 + ticks_per_cycle: 4 station: [furnace] ingredients: - items: [copper_ore] quantity: 1 - items: [tin_ore] quantity: 1 - success_message: "You smelt a %n." # default is "You remove a white hot %n!" - # overridden here for simpler flavor + fail_message: "You fail to smelt a usable bar." ``` +Anvil (smithing): + ```yaml # data/items/equipment/bronze_dagger.yaml +name: bronze dagger craft: type: smithing level: 1 xp: 12 - wait: 4 + ticks_per_cycle: 4 station: [anvil] ingredients: - items: [bronze_bar] quantity: 1 - # success_message omitted — uses default "You smith a %n." ``` -For stackable outputs, use `output_qty`: +Stackable outputs use `output_qty`: ```yaml # data/items/ammo/bronze_nails.yaml +name: bronze nails +stackable: true craft: type: smithing level: 4 xp: 12 - wait: 4 + ticks_per_cycle: 4 station: [anvil] ingredients: - items: [bronze_bar] quantity: 1 output_qty: 15 - # success_message omitted — uses default "You smith a %n." ``` ### Tool-Based Production ```yaml # data/items/ammo/arrow_shafts.yaml +name: arrow shafts craft: type: fletching level: 1 xp: 5 - wait: 3 + ticks_per_cycle: 3 tool: knife ingredients: - items: [logs, oak_logs, willow_logs] @@ -190,31 +198,31 @@ craft: output_qty: 15 ``` -The `tool` field requires the player to have an item with that `tool_type` equipped or in inventory. The tool is NOT consumed. +### Skill-Less Combinations -### Skill-Less Combinations (Item-on-Item) - -Omit `type` (or leave it empty) for combinations with no skill check, no XP, and 100% success: +Omit `type` (or leave empty) for combinations with no skill check and 100% success: ```yaml # data/items/consumables/bucket_of_water.yaml +name: bucket of water craft: - wait: 0 + ticks_per_cycle: 0 ingredients: - items: [vial_of_water, jug_of_water] quantity: 1 byproducts: [empty_vial, empty_jug] - items: [empty_bucket] quantity: 1 - success_message: "You pour the %i1 into the %i2." # %i1 = water source, %i2 = bucket + success_message: "You pour the %i1 into the %i2." ``` -### Multi-Piece Assembly (3+ items → 1) +### Multi-Piece Assembly ```yaml # data/items/quest/ancient_map.yaml +name: ancient map craft: - wait: 0 + ticks_per_cycle: 0 ingredients: - items: [torn_page_1] quantity: 1 @@ -230,46 +238,31 @@ craft: success_message: "You assemble the %n." ``` -### Clean Recipes +### Clean Recipes (Herb Cleaning) -Clean herb recipes use `type: pharmacy` with `subtype: clean` and are handled as background actions (one herb per cycle, directly mutating inventory): +Use `type: pharmacy` with `subtype: clean`: ```yaml -# data/items/materials/guam.yaml (clean guam) +# data/items/materials/guam.yaml (clean herb) +name: clean guam craft: type: pharmacy subtype: clean level: 3 xp: 3 - wait: 2 + ticks_per_cycle: 2 ingredients: - items: [grimy_guam] quantity: 1 - # success_message omitted — uses default "You clean the %i1." - # %i1 expands to the grimy herb name with its color ``` -### Food/Healing Items - -Items with `heal_value` and `eat_message` can be consumed via the `eat` command. - -```yaml -name: bread -color: "DE" -description: "A fresh loaf of bread, still warm from the oven." -value: 5 -heal_value: 5 -eat_message: "You eat the bread. Warm and satisfying." -``` +### Food / Healing -### Architecture +Items with `heal_value` and `eat_message` can be consumed via the `eat` command. See +`items.md` for the full food item format. -The `CraftIndex` (`internal/game/production_index.go`) is built once at startup from all item YAMLs that have a `craft:` block. It provides `O(1)` lookups by type, subtype, input item, and station. All crafting commands query the CraftIndex — no runtime file scanning. +### Construction -**Indexes:** -- `byType["pharmacy"]` → all pharmacy-craftable items (used by `mix`) -- `bySubtype["clean"]` → all items with subtype `clean` (grimy herb cleaning) -- `bySubtype["smelt"]` → all items with subtype `smelt` (furnace smelting) -- `byInput["guam"]` → all items that use guam (used by `use` to find combinations) -- `byStation["anvil"]` → all items craftable at an anvil (used by `use bar on anvil`) -- `FindByTwoInputs(a, b)` → items consuming both inputs in different ingredient entries +`type: construction` recipes use `station: [workbench]`. Log-to-plank recipes additionally +require `tool: saw`. See `construction.md` for plank tiers, furniture, NPCs, and player +housing. |
