diff options
Diffstat (limited to 'worldbuilding_guide/behaviors.md')
| -rw-r--r-- | worldbuilding_guide/behaviors.md | 518 |
1 files changed, 294 insertions, 224 deletions
diff --git a/worldbuilding_guide/behaviors.md b/worldbuilding_guide/behaviors.md index aa46073..1934f5b 100644 --- a/worldbuilding_guide/behaviors.md +++ b/worldbuilding_guide/behaviors.md @@ -1,112 +1,167 @@ ## Behaviors +Behaviors are **inline configs** placed directly inside object YAML (`gather:`, `talk:`, +`use:`) or mob YAML (`talk:`). There is no separate `data/behaviors/` +directory. Each section below shows the keys you can use under each behavior type. + ### Gather (mining, fishing, woodcutting) -Mining — per-drop depletion: +Mining — per-drop depletion on a rock object: ```yaml -id: mine_copper -type: gather -skill: mining -level: 1 -xp: 17 # XP awarded per successful gather -base_wait: 8 # ticks between attempts -tool: pickaxe # requires item with tool_type: pickaxe -success: - base: 0.40 # 40% base chance - per_level: 0.01 # +1% per level above requirement - cap: 0.95 # 95% max -gather_message: "You swing your pickaxe at the rock..." -fail_message: "You chip away but get nothing useful." -drops: - - item_id: copper_ore - weight: 90 # 90% chance when roll succeeds - depletes: true # rock becomes depleted after this drop - message: "You manage to mine some {178}copper ore{/}." - - table: gem_table # reference a shared drop table - weight: 10 - depletes: false # gem drops don't deplete the rock - message: "You spot a glint of something valuable!" -respawn_timer: 50 # ticks until rock respawns -respawn_message: "You see more ore in the rock." -respawn_broadcast: "A glint of copper catches your eye from some {name}." +id: copper_rock +name: copper rock +color: "178" +gather: + skill: mining + level: 1 + xp: 17 # XP awarded per successful gather + base_wait: 8 # ticks between attempts + tools: # requires item with matching tool_type + - pickaxe + success: + base: 0.40 # 40% base chance + per_level: 0.01 # +1% per level above requirement + cap: 0.95 # 95% max + gather_message: "You swing your pickaxe at the rock..." + fail_message: "You chip away but get nothing useful." + drops: + - item_id: copper_ore + weight: 90 # 90% chance when roll succeeds + depletes: true # rock becomes depleted after this drop + message: "You manage to mine some {178}copper ore{/}." + - table: gem_table # reference a shared drop table + weight: 10 + depletes: false # gem drops don't deplete the rock + message: "You spot a glint of something valuable!" + respawn_timer: 50 # ticks until rock respawns + respawn_broadcast: "A glint of copper catches your eye from some {name}." ``` -Drop messages support inline color tags: `{<0-255>}text{/}`. Use the item's color index to match its display color. Gradients also work: `{g:196,82}text{/}`. +Drop messages support inline color tags: `{<0-255>}text{/}`. Use the item's color +index to match its display color. Gradients also work: `{g:196,82}text{/}`. -Non-depleting gather (fishing): +Non-depleting gather (fishing on a fishing spot object): ```yaml -id: fish_trout -type: gather -skill: fishing -level: 1 -xp: 10 -base_wait: 4 -tool: fishing_rod -success: - base: 0.30 - per_level: 0.01 - cap: 0.90 -gather_message: "You cast your line into the water..." -fail_message: "Nothing seems to bite." -drops: - - item_id: raw_trout - weight: 100 - depletes: false # never depletes - message: "You catch a {69}raw trout{/}!" +id: bait_fishing_spot +name: fishing spot +gather: + skill: fishing + level: 1 + xp: 10 + base_wait: 4 + tools: + - fishing_rod + bait: fishing_bait + success: + base: 0.30 + per_level: 0.01 + cap: 0.90 + gather_message: "You cast your line into the water..." + fail_message: "Nothing seems to bite." + drops: + - item_id: raw_trout + weight: 100 + depletes: false # never depletes + message: "You catch a {69}raw trout{/}!" ``` Woodcutting with shared depletion and bird's nests: ```yaml -id: chop_oak -type: gather -skill: woodcutting -level: 15 -xp: 37 -base_wait: 6 -tool: axe -success: - base: 0.40 - per_level: 0.01 - cap: 0.90 -gather_message: "You swing your axe at the oak tree..." -fail_message: "You swing but get no logs." -drops: - - item_id: oak_logs - weight: 100 - depletes: false # depletion is timer-based (deplete_timer) - message: "You get some {113}oak logs{/}." -respawn_timer: 14 # ticks until tree respawns after being cut down -deplete_timer: 45 # max ticks before next gather depletes (counts down while chopping) -nest_chance: 256 # 1/256 chance for a bird's nest on each successful gather -respawn_message: "A new oak sapling grows in its place." -respawn_broadcast: "An {name} grows back." +id: oak_tree +name: oak tree +color: "113" +gather: + skill: woodcutting + level: 15 + xp: 37 + base_wait: 6 + tools: + - axe + success: + base: 0.40 + per_level: 0.01 + cap: 0.90 + gather_message: "You swing your axe at the oak tree..." + fail_message: "You swing but get no logs." + drops: + - item_id: oak_logs + weight: 100 + depletes: false # depletion is timer-based (deplete_timer) + message: "You get some {113}oak logs{/}." + respawn_timer: 14 # ticks until tree respawns after being cut down + deplete_timer: 45 # max ticks before next gather depletes (counts down while chopping) + nest_chance: 256 # 1/256 chance for a bird's nest on each successful gather + respawn_broadcast: "An {name} grows back." ``` Regular tree — always depletes on first gather, no shared timer, no nests: ```yaml -id: chop_tree -type: gather -skill: woodcutting -level: 1 -xp: 25 -base_wait: 4 -tool: axe -success: - base: 0.50 - per_level: 0.01 - cap: 0.95 -gather_message: "You swing your axe at the tree..." -fail_message: "You swing but get no logs." -drops: - - item_id: logs - weight: 100 - depletes: true # regular tree depletes on first successful gather - message: "You get some {107}logs{/}." -respawn_timer: 80 -respawn_message: "A new tree grows in its place." -respawn_broadcast: "A {name} grows back." +id: tree +name: tree +gather: + skill: woodcutting + level: 1 + xp: 25 + base_wait: 4 + tools: + - axe + success: + base: 0.50 + per_level: 0.01 + cap: 0.95 + gather_message: "You swing your axe at the tree..." + fail_message: "You swing but get no logs." + drops: + - item_id: logs + weight: 100 + depletes: true # regular tree depletes on first successful gather + message: "You get some {107}logs{/}." + respawn_timer: 80 + respawn_broadcast: "A {name} grows back." ``` +#### GatherConfig Fields + +| Field | Type | Description | +|---|---|---| +| `skill` | string | Skill name for level check | +| `level` | int | Required level to gather | +| `xp` | int | XP per successful gather | +| `base_wait` | float64 | Base ticks per action cycle | +| `tools` | []string | Required tool_type list (e.g. `[pickaxe]`) | +| `bait` | string | Required bait item (for fishing) | +| `success` | SuccessFormula | Base + per_level, capped | +| `gather_message` | string | Custom "You gather..." message | +| `depleted_message` | string | Custom "The rock is depleted" message | +| `exhausted_message` | string | Custom "The tree falls" message | +| `fail_message` | string | Custom failure message | +| `drops` | []DropEntry | Weighted drop entries | +| `respawn_timer` | float64 | Ticks until depleted object respawns | +| `respawn_broadcast` | string | Broadcast message when object respawns | +| `deplete_timer` | float64 | Ticks for shared depletion (trees) | +| `nest_chance` | int | 1/N chance for bird's nest alongside normal drop | + +#### SuccessFormula + +| Field | Type | Description | +|---|---|---| +| `base` | float64 | Base success chance (0.0-1.0) | +| `per_level` | float64 | Chance increase per level above requirement | +| `cap` | float64 | Maximum success chance | + +#### DropEntry + +| Field | Type | Description | +|---|---|---| +| `item_id` | string | Item ID to drop | +| `table` | string | Reference to a shared drop table in `data/drops/` | +| `weight` | int | Relative drop weight | +| `depletes` | bool | Resource depletes on this drop | +| `quantity` | int | Amount to drop (1-3 for random) | +| `message` | string | Player message on drop | +| `level` | int | Skill level required for this drop | +| `xp` | int | Bonus XP on this drop | + #### Shared depletion explained When `deplete_timer > 0`, the tree has a shared despawn timer: @@ -131,60 +186,63 @@ toggle is on, the output includes the XP gain: `(+37xp wct)`. ### Talk (dialog trees) -Full conversation with conditions, actions, and player flag tracking: +Talk configs go under the `talk:` key on objects or mobs. Full conversation with +conditions, actions, and player flag tracking: + ```yaml -id: guard_talk -type: talk -nodes: - start: - message: "\"Halt! This area is restricted.\"" - options: - - text: "\"What's behind that gate?\"" - goto: about_gate - - text: "\"I have copper ore.\"" # only shows if player has ore - goto: trade_ore - condition: - has_item: copper_ore - - text: "\"I have a pass.\"" # only shows if player earned a pass - goto: has_pass - condition: - player_flag: got_pass - value: true - - text: "\"Goodbye.\"" - end: true - - about_gate: - message: "\"Bring me some copper ore and I'll stamp you a pass.\"" - action: - set_player_flags: # player-local: only this player - talked_to_guard: true - options: - - text: "\"I'll be back.\"" - end: true - - text: "\"I have some right here.\"" - goto: trade_ore - condition: - has_item: copper_ore - - trade_ore: - message: "\"Good quality ore.\" He stamps a pass and hands it to you." - action: - take_item: copper_ore # removes 1 copper ore - give_item: pass_stub # gives pass stub - set_player_flags: - got_pass: true # player now "has a pass" - options: - - text: "\"Thanks.\"" - end: true - - has_pass: - message: "\"Alright, I'll open the gate for you.\"" - action: - set_flags: # WORLD flag: gate opens for everyone - gate_open: true - options: - - text: "\"Thanks.\"" - end: true +id: guard +name: Guard +talk: + nodes: + start: + message: "\"Halt! This area is restricted.\"" + options: + - text: "\"What's behind that gate?\"" + goto: about_gate + - text: "\"I have copper ore.\"" + goto: trade_ore + condition: + has_item: copper_ore + - text: "\"I have a pass.\"" + goto: has_pass + condition: + player_flag: got_pass + value: true + - text: "\"Goodbye.\"" + end: true + + about_gate: + message: "\"Bring me some copper ore and I'll stamp you a pass.\"" + action: + set_player_flags: + talked_to_guard: true + options: + - text: "\"I'll be back.\"" + end: true + - text: "\"I have some right here.\"" + goto: trade_ore + condition: + has_item: copper_ore + + trade_ore: + message: "\"Good quality ore.\" He stamps a pass and hands it to you." + action: + take_item: copper_ore + give_item: pass_stub + set_player_flags: + got_pass: true + options: + - text: "\"Thanks.\"" + end: true + + has_pass: + message: "\"Alright, I'll open the gate for you.\"" + action: + set_flags: + gate_open: true + options: + - text: "\"Thanks.\"" + end: true ``` #### Node action reference @@ -203,19 +261,21 @@ nodes: | `skip_task` | Cancels current assassin task, costs 30 reputation, resets streak | | `extend_task` | Adds 50% more kills to current task, costs 30 reputation | | `reputation_cost` | Deducts reputation from the player's `assassin_reputation` flag (fails node if insufficient) | +| `sawmill` | Opens sawmill plank conversion interface | -All fields in a single action are processed together — you can give an item, take an item, set flags, and heal all in one node. +All fields in a single action are processed together — you can give an item, take an item, +set flags, and heal all in one node. Example — quest completion: ```yaml action: - take_item: dragon_head - give_item: dragon_slayer_medal - set_player_flags: - dragon_quest: complete - dragon_slain: true - heal: 99 - teleport: 1 # return to town + take_item: dragon_head + give_item: dragon_slayer_medal + set_player_flags: + dragon_quest: complete + dragon_slain: true + heal: 99 + teleport: 1 ``` #### Shop (buy/sell interface) @@ -225,15 +285,15 @@ items, buy with credits, and sell items back. Define a shop on a talk node: ```yaml action: - shop: - message: "What would you like to buy or sell?" - items: - - item_id: fishing_rod - buy_price: 10 - sell_price: 2 - - item_id: fishing_bait - buy_price: 2 - sell_price: 0 + shop: + message: "What would you like to buy or sell?" + items: + - item_id: fishing_rod + buy_price: 10 + sell_price: 2 + - item_id: fishing_bait + buy_price: 2 + sell_price: 0 ``` | Field | Description | @@ -249,85 +309,95 @@ When the player leaves the shop, they return to the talk node's options. Full example — General Store: ```yaml -id: general_store -type: talk -nodes: - start: - message: "\"Welcome to the General Store!\"" - options: - - text: "\"I'd like to browse.\"" - goto: shop - - text: "\"Goodbye.\"" - end: true - shop: - message: "\"Take your time.\"" - action: - shop: - message: "What would you like to buy or sell?" - items: - - item_id: fishing_rod - buy_price: 10 - sell_price: 2 - - item_id: hammer - buy_price: 20 - sell_price: 5 - options: - - text: "\"I'm done.\"" - goto: start +id: general_store_clerk +name: General Store Clerk +talk: + nodes: + start: + message: "\"Welcome to the General Store!\"" + options: + - text: "\"I'd like to browse.\"" + goto: shop + - text: "\"Goodbye.\"" + end: true + shop: + message: "\"Take your time.\"" + action: + shop: + message: "What would you like to buy or sell?" + items: + - item_id: fishing_rod + buy_price: 10 + sell_price: 2 + - item_id: hammer + buy_price: 20 + sell_price: 5 + options: + - text: "\"I'm done.\"" + goto: start ``` Node options on the shop node are shown when the player leaves the shop. Use `goto: start` to loop back to the main greeting. -### Toggle (levers, switches, gates) +### Object Interactions (levers, switches, gates) + +Interaction configs go under the `use_interactions:` key on objects. +Entries with no `item` field are bare interactions triggered by "use" +or "push"/"pull": -Simple toggle that sets a world flag: ```yaml -id: iron_gate_toggle -type: toggle -message: "You push the heavy iron gate open." -set_flags: - gate_open: true -check: # only works when gate is closed - flag: gate_open - value: true - not: true +id: iron_gate +name: iron gate +hidden: true +description: "A heavy iron gate set into the north wall." +use_interactions: + - condition: + flag: gate_open + value: true + not: true + message: "You push the heavy iron gate open." + action: + set_flags: + gate_open: true ``` -Lever that toggles between two states: +Item-specific interaction: ```yaml -id: bridge_lever -type: toggle -message: "You pull the lever. Mechanisms groan somewhere in the distance." -set_flags: - bridge_extended: true -check: - flag: bridge_extended - value: true - not: true +id: bookshelf +name: bookshelf +use_interactions: + - item: dusty_tome + message: "The bookshelf slides aside, revealing a secret passage!" + action: + set_flags: + secret_passage_open: true ``` ### Use (crafting stations) +Use configs go under the `use:` key on objects (e.g. furnaces, ranges): + ```yaml -id: smelt_copper -type: use -message: "You place the ore in the furnace..." -wait: 4 # ticks between crafts -consume: # items consumed per craft - copper_ore: 1 -reward: # item produced - item_id: copper_bar - quantity: 1 -fail_message: "The ore crumbles to dust." -success: - base: 0.60 - per_level: 0.01 - cap: 0.95 -skill: smithing -level: 1 -xp: 15 # XP awarded per successful craft +id: furnace +name: furnace +color: "208" +use: + message: "You place the ore in the furnace..." + wait: 4 + consume: + copper_ore: 1 + reward: + item_id: copper_bar + quantity: 1 + fail_message: "The ore crumbles to dust." + success: + base: 0.60 + per_level: 0.01 + cap: 0.95 + skill: smithing + level: 1 + xp: 15 ``` --- - |
