aboutsummaryrefslogtreecommitdiff
path: root/building_guide/recipes.md
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-09 16:09:35 -0400
committerhistoria <[not public]>2026-07-09 16:09:35 -0400
commitb8c90886ef1f3afb8d908aac89028bd177836cae (patch)
tree7e566a7e308e7531bbb7d6a3a39239e789f69a3c /building_guide/recipes.md
parentc705ae942573984784ef501bf8198f61f5206ddd (diff)
downloadthehouseoficarus-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.md215
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.