aboutsummaryrefslogtreecommitdiff
path: root/worldbuilding_guide
diff options
context:
space:
mode:
Diffstat (limited to 'worldbuilding_guide')
-rw-r--r--worldbuilding_guide/hidden_objects.md3
-rw-r--r--worldbuilding_guide/items.md38
-rw-r--r--worldbuilding_guide/objects.md90
-rw-r--r--worldbuilding_guide/recipes.md81
4 files changed, 203 insertions, 9 deletions
diff --git a/worldbuilding_guide/hidden_objects.md b/worldbuilding_guide/hidden_objects.md
index 3cb8a1e..a191051 100644
--- a/worldbuilding_guide/hidden_objects.md
+++ b/worldbuilding_guide/hidden_objects.md
@@ -8,8 +8,7 @@ id: secret_lever
name: stone lever
behavior: secret_toggle
hidden: true
-props:
- description: "A cleverly concealed lever behind a loose stone."
+description: "A cleverly concealed lever behind a loose stone."
```
Room description hints at it:
diff --git a/worldbuilding_guide/items.md b/worldbuilding_guide/items.md
index e9e4352..0a4592b 100644
--- a/worldbuilding_guide/items.md
+++ b/worldbuilding_guide/items.md
@@ -65,17 +65,51 @@ eat_message: "You eat the bread. Warm and satisfying."
## MadeFrom — Item Combinations
-Define what items combine to make this item. Used by the `use` command.
+Define what items combine to make this item. Used by the `use` command. Combinations run through the production system — players are prompted "How many?" and the action loops with a timer.
```yaml
id: bread_dough
name: bread dough
color: "222"
+ticks: 2
made_from:
- items: [pot_of_flour]
qty: 1
+ byproducts: [empty_pot]
- items: [bucket_of_water, pitcher_of_water]
qty: 1
+ byproducts: [empty_bucket, empty_pitcher]
```
-Each entry is an ingredient slot. Multiple `items` means any of them works. The first matching item found in inventory is consumed. See also `recipes.md` for station-based recipes.
+Each entry is an ingredient slot. Multiple `items` means any of them works. The first matching item found in inventory is consumed.
+
+`ticks` controls how many game ticks each production cycle takes (default 2).
+
+### Byproducts
+
+`byproducts` is a list matching the `items` list by index. When `bucket_of_water` (items[0]) is consumed, `empty_bucket` (byproducts[0]) is returned to inventory. When `pitcher_of_water` (items[1]) is consumed, `empty_pitcher` (byproducts[1]) is returned instead.
+
+Use `""` for items that produce no byproduct:
+
+```yaml
+made_from:
+ - items: [pot_of_flour, loose_flour]
+ qty: 1
+ byproducts: [empty_pot, ""] # pot returns empty_pot, loose flour returns nothing
+ - items: [bucket_of_water]
+ qty: 1
+ byproducts: [empty_bucket]
+```
+
+Omit `byproducts` entirely if no items in that slot produce a byproduct:
+
+```yaml
+made_from:
+ - items: [pot_of_flour]
+ qty: 1
+ byproducts: [empty_pot] # returns empty_pot
+ - items: [salt]
+ qty: 1 # no byproducts field — salt is consumed entirely
+```
+
+See also `recipes.md` for station-based recipes.
diff --git a/worldbuilding_guide/objects.md b/worldbuilding_guide/objects.md
index 6929606..3644a18 100644
--- a/worldbuilding_guide/objects.md
+++ b/worldbuilding_guide/objects.md
@@ -24,18 +24,98 @@ id: iron_gate
name: iron gate
behavior: iron_gate_toggle
hidden: true
-props:
- description: "A heavy iron gate set into the north wall."
+description: "A heavy iron gate set into the north wall."
```
Decorative object (no behavior):
```yaml
id: lumby_fountain
name: town fountain
-behavior: ""
-props:
- description: "Clear water sparkles in the sunlight."
+description: "Clear water sparkles in the sunlight."
```
---
+## Use Interactions
+
+Objects can define `use_interactions` to handle when a player uses a specific item on the object. Each interaction can check conditions, show a message, and execute actions — using the same condition and action primitives as the talk system.
+
+Entries are checked top-to-bottom; the first match with a passing condition wins.
+
+Simple message (no action):
+```yaml
+id: anvil
+name: anvil
+use_interactions:
+ - item: silver_bar
+ message: "You should use this with a mold at a furnace."
+ - item: gold_bar
+ message: "You should use this with a mold at a furnace."
+```
+
+Puzzle interaction (take item, set flag):
+```yaml
+id: crystal_slot
+name: crystal slot
+use_interactions:
+ - item: crystal_key
+ condition:
+ flag: crystal_inserted
+ message: "The crystal key is already in the slot."
+ - item: crystal_key
+ message: "You insert the crystal key into the slot. It clicks into place."
+ action:
+ take_item: crystal_key
+ set_flags:
+ crystal_inserted: true
+```
+
+Quest item exchange:
+```yaml
+use_interactions:
+ - item: ancient_scroll
+ condition:
+ player_flag: quest_started
+ message: "You place the scroll on the pedestal. The door rumbles open!"
+ action:
+ take_item: ancient_scroll
+ set_player_flags:
+ quest_complete: true
+ set_flags:
+ temple_door_open: true
+```
+
+### UseInteraction Fields
+
+| Field | Type | Description |
+| ----------- | ---------- | ------------------------------------------------ |
+| `item` | string | Item ID that triggers this interaction |
+| `condition` | Condition | Optional condition (same as exits/talk/toggle) |
+| `message` | string | Message shown to the player |
+| `action` | NodeAction | Optional actions (same as talk node actions) |
+
+### Available Actions (same as talk)
+
+| Field | Type | Description |
+| ------------------ | -------------- | ---------------------------------- |
+| `set_flags` | map[string]any | Set world flags (shared) |
+| `set_player_flags` | map[string]any | Set player flags (per-character) |
+| `give_item` | string | Give an item to inventory |
+| `take_item` | string | Remove an item from inventory |
+| `teleport` | int | Move player to a room ID |
+| `heal` | int | Restore hitpoints |
+
+### Available Conditions (same as exits/talk)
+
+| Field | Description |
+| ------------- | -------------------------------- |
+| `flag` | World flag check |
+| `player_flag` | Per-character flag check |
+| `has_item` | Inventory item check |
+| `value` | Expected value for flag checks |
+| `not` | Invert the condition |
+| `all_of` | All sub-conditions must pass |
+| `any_of` | Any sub-condition must pass |
+
+---
+
diff --git a/worldbuilding_guide/recipes.md b/worldbuilding_guide/recipes.md
index 500954f..799dab0 100644
--- a/worldbuilding_guide/recipes.md
+++ b/worldbuilding_guide/recipes.md
@@ -24,6 +24,7 @@ Recipe files live in `data/recipes/<id>.yaml`.
| `station` | []string | Station object IDs required |
| `consume` | []ConsumeEntry | Ingredients consumed (see below) |
| `output` | string | ItemID produced on success |
+| `output_qty` | int | Quantity produced (default 1, for stackables) |
| `fail` | string | ItemID produced on failure (optional) |
| `message` | string | Success message |
| `fail_message` | string | Failure message |
@@ -39,6 +40,18 @@ Each consume entry defines an ingredient slot with multiple valid items. The fir
consume:
- items: [item_id, alternative_id, ...]
qty: 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
+consume:
+ - items: [bucket_of_water, vial_of_water]
+ qty: 1
+ byproducts: [empty_bucket, ""] # bucket returns empty, vial is consumed entirely
+ - items: [herb]
+ qty: 1 # no byproducts — herb is consumed entirely
```
### Station-based recipe (cooking on a fire)
@@ -79,6 +92,74 @@ message: "You bake the dough into a fresh loaf of bread."
fail_message: "You burn the bread to a crisp."
```
+### Smelting recipe (ore to bar at a furnace)
+
+Smelting recipes use `type: smelting` and `station: [furnace]`. The `smelt` command or `use <ore> on furnace` triggers them. Multi-ore recipes use `qty` on consume entries.
+
+```yaml
+id: smelt_steel
+type: smelting
+skill: smithing
+level: 40
+xp: 17
+wait: 4
+station: [furnace]
+consume:
+ - items: [iron_ore]
+ qty: 1
+ - items: [coal]
+ qty: 2
+output: steel_bar
+message: "You remove a white hot steel bar!"
+fail_message: "You fail to smelt a usable bar."
+```
+
+Iron smelting uses a `success` formula for its 50% failure rate:
+
+```yaml
+success:
+ base: 0.5
+ per_level: 0
+ cap: 0.5
+```
+
+### Smithing recipe (bar to item at an anvil)
+
+Smithing recipes use `type: smithing` and `station: [anvil]`. The `smith` command or `use <bar> on anvil` triggers them. Requires a hammer (`tool_type: hammer`) in inventory.
+
+```yaml
+id: smith_steel_platebody
+type: smithing
+skill: smithing
+level: 48
+xp: 187
+wait: 4
+station: [anvil]
+consume:
+ - items: [steel_bar]
+ qty: 5
+output: steel_platebody
+message: "You hammer out a steel platebody."
+```
+
+For stackable outputs, use `output_qty`:
+
+```yaml
+id: smith_iron_nails
+type: smithing
+skill: smithing
+level: 24
+xp: 25
+wait: 4
+station: [anvil]
+consume:
+ - items: [iron_bar]
+ qty: 1
+output: iron_nails
+output_qty: 15
+message: "You hammer out some iron nails."
+```
+
### MadeFrom — Item-on-item combinations
Item-on-item combinations are defined directly on the output item via the `made_from` field. No recipe file needed.