From 9fbad377017a11412af3222a4ff050f46de172ff Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sat, 7 Mar 2026 11:29:41 +0100 Subject: [PATCH 1/3] feat(copy): rename zone specs to location-specific, expand behavior pools (#630) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename rural-zone-spec.ron → krenn-rural-zone.ron and industrial-zone-spec.ron → krenn-industrial-zone.ron to reflect that these are culture×zone specific content, not reusable templates. Add ~108 new typical_behaviors across all roles: - Rural: farmer +20 (incl tavern/off-duty), mechanic +15 (incl tavern), trader +10 (observable stage directions), militia +5 - Industrial: dock_worker +20 (incl break room), technician +19 (incl break room), foreman +14 (person-beneath-the-role), security +5 Co-Authored-By: Claude Opus 4.6 --- content/global/industrial-zone-spec.ron | 124 --------------- content/global/krenn-industrial-zone.ron | 186 +++++++++++++++++++++++ content/global/krenn-rural-zone.ron | 170 +++++++++++++++++++++ content/global/rural-zone-spec.ron | 119 --------------- 4 files changed, 356 insertions(+), 243 deletions(-) delete mode 100644 content/global/industrial-zone-spec.ron create mode 100644 content/global/krenn-industrial-zone.ron create mode 100644 content/global/krenn-rural-zone.ron delete mode 100644 content/global/rural-zone-spec.ron diff --git a/content/global/industrial-zone-spec.ron b/content/global/industrial-zone-spec.ron deleted file mode 100644 index 16a682d6a..000000000 --- a/content/global/industrial-zone-spec.ron +++ /dev/null @@ -1,124 +0,0 @@ -// Zone Identity Spec — Industrial -// -// Schema: server/src/npc/blueprint.rs :: ZoneSpec -// Ticket: #609 (copy team) -// Validate: tooling/validate-ron content/global/industrial-zone-spec.ron zone -// -// Character: freight handling, manufacturing, maintenance. High throughput. -// Shift rhythms. Functional over comfortable. Nobody lingers — unless they're on break. -// -// Generator contrast target: industrial vs rural (Sprint 25 proof). -// If these produce NPCs that look the same, something is wrong. -// -// Heritage roots (D-104/D-105) overlay these base specs at generation time, -// modifying role weights, social site composition, and behavioral flavoring. - -( - zone_type: "industrial", - label: "Industrial Zone", - description: "Freight handling, manufacturing, and maintenance. High throughput, shift-based work rhythms, functional over comfortable. Faces are known by role and bay number more than name. The work doesn't stop between shifts — people do.", - - // 1-10. Industrial Krenn: steady credit flow, but it all goes somewhere. - economic_level: 7, - // 1-10. Dense. Multiple shifts overlap. Crowds at handover. - population_density: 6, - - roles: [ - ( - id: "dock_worker", - label: "Dock Worker", - // Most common. The zone runs on their backs. - weight: 5, - skill_focus: ["technical"], - combat_eligible: false, - typical_behaviors: [ - "guides a freight container into position with hand signals", - "checks a manifest against a handheld scanner, lips moving", - "waits at the loading bay apron with arms crossed, watching the clock", - "calls bay numbers to a colleague across the noise of the floor", - "hooks a cargo sling and steps clear before signaling the lift", - "stacks empty pallets against a wall with mechanical efficiency", - "wipes sweat from her face with a forearm and keeps moving", - "slumps into a break room chair and stares at nothing for a full minute before reaching for a drink", - ], - ), - ( - id: "technician", - label: "Systems Technician", - // Keeps the infrastructure running. Never enough of them. - weight: 4, - skill_focus: ["technical"], - combat_eligible: false, - typical_behaviors: [ - "runs a diagnostic routine on a floor console, eyes on the readout", - "traces a conduit run along the ceiling with a handheld light", - "swaps a panel module with practiced speed and no wasted motion", - "logs a fault code into a datapad before moving on", - "presses an ear to a vibrating duct and listens", - "argues quietly with a display that isn't giving the right numbers", - "queries a fault log through her insert without touching the terminal, eyes briefly unfocused", - "stretches both arms overhead in the break room doorway, blocking it without noticing", - ], - ), - ( - id: "foreman", - label: "Shift Foreman", - // Fewer of them. High visibility. Everyone knows where they are. - weight: 2, - skill_focus: ["observation", "persuasion"], - combat_eligible: false, - typical_behaviors: [ - "walks the floor with a datapad under one arm and says nothing", - "pulls a worker aside for a quiet word near the far wall", - "marks a line off a production board and moves to the next one", - "stands at the mezzanine rail watching throughput without expression", - "reviews shift handover notes and circles something with a stylus", - "speaks to a dock crew in a low voice — they listen without nodding", - "sits alone in the break room rubbing the back of her neck, datapad face-down on the table", - "laughs at something a technician says, then catches herself and goes quiet", - ], - ), - ( - id: "security", - label: "Facility Security", - // Present, watchful. Not looking for trouble — cataloguing it. - weight: 2, - skill_focus: ["combat", "observation"], - combat_eligible: true, - typical_behaviors: [ - "sweeps the access corridor on a timed circuit, same path each time", - "waves a regular through the checkpoint on sight — scans the one behind them out of procedure", - "leans at the restricted bay entrance, arms folded — been watching this corridor since the shift started", - "notes something in a shift log without reacting to it outwardly", - "watches a handover between crews from across the loading floor", - ], - ), - ], - - social_sites: [ - ( - site_type: "break_room", - label: "Worker Break Room", - // Between shifts. Decompression. People stop performing for a moment. - roles: ["dock_worker", "technician", "foreman"], - min_npcs: 2, - max_npcs: 5, - ), - ( - site_type: "maintenance_bay", - label: "Maintenance Bay", - // Active work site. Technicians and dock workers cross paths here. - roles: ["technician", "dock_worker"], - min_npcs: 2, - max_npcs: 4, - ), - ( - site_type: "loading_platform", - label: "Loading Platform", - // The operational center. Busy, loud, coordinated. - roles: ["dock_worker", "foreman", "security"], - min_npcs: 3, - max_npcs: 8, - ), - ], -) diff --git a/content/global/krenn-industrial-zone.ron b/content/global/krenn-industrial-zone.ron new file mode 100644 index 000000000..11918f376 --- /dev/null +++ b/content/global/krenn-industrial-zone.ron @@ -0,0 +1,186 @@ +// Krenn Industrial Zone — location-specific zone content +// +// Schema: server/src/npc/blueprint.rs :: ZoneSpec +// Ticket: #609, #630 (copy team) +// Validate: tooling/validate-ron content/global/krenn-industrial-zone.ron zone +// +// This is content for a specific location: a Krenn industrial district. +// Behaviors, roles, and social sites are culture×zone specific — not reusable +// templates. See Q-057 for the composable behavior generation design that +// will replace hand-authored pools with assembled primitives. +// +// Character: freight handling, manufacturing, maintenance. High throughput. +// Shift rhythms. Functional over comfortable. Nobody lingers — unless they're on break. + +( + zone_type: "industrial", + label: "Industrial Zone", + description: "Freight handling, manufacturing, and maintenance. High throughput, shift-based work rhythms, functional over comfortable. Faces are known by role and bay number more than name. The work doesn't stop between shifts — people do.", + + // 1-10. Industrial Krenn: steady credit flow, but it all goes somewhere. + economic_level: 7, + // 1-10. Dense. Multiple shifts overlap. Crowds at handover. + population_density: 6, + + roles: [ + ( + id: "dock_worker", + label: "Dock Worker", + // Most common. The zone runs on their backs. + weight: 5, + skill_focus: ["technical"], + combat_eligible: false, + typical_behaviors: [ + "guides a freight container into position with hand signals", + "checks a manifest against a handheld scanner, lips moving", + "waits at the loading bay apron with arms crossed, watching the clock", + "calls bay numbers to a colleague across the noise of the floor", + "hooks a cargo sling and steps clear before signaling the lift", + "stacks empty pallets against a wall with mechanical efficiency", + "wipes sweat from her face with a forearm and keeps moving", + "slumps into a break room chair and stares at nothing for a full minute before reaching for a drink", + // on-shift + "drags a heavy case along the deck plating one-handed, leaning hard into the weight", + "re-checks a seal on a container door after a colleague already checked it", + "flags a damaged pallet to the foreman without stopping the line", + "shoulders a cargo rig harness and clips in without looking down", + "sweeps debris off the loading apron with a long push broom", + "braces a container with a boot while reaching for the locking pin", + "reads the load ticket twice, then flips the handheld over to check the back", + "waves off a crane operator when the angle is wrong, holds up a fist", + "steps over a bundled cable run without breaking stride", + "peels off a work glove with his teeth to check a handheld display", + "trades a quick look with a colleague when the foreman walks by", + // off-shift / break room + "unwraps a meal packet in the break room and eats standing at the counter", + "passes a drink to the person next to her without being asked", + "leans back in a break room chair with eyes closed, boots crossed at the ankle", + "laughs at something across the break room table, loud enough to carry", + "shows something on a handheld to a colleague and both of them look at it for a moment", + "sits with elbows on knees, turning an empty cup in both hands", + "splashes water on his face at the sink and stands there a moment before turning off the tap", + "talks over the break room noise at volume, gesturing with a fork", + "falls asleep in a break room chair, chin on chest, arms folded", + ], + ), + ( + id: "technician", + label: "Systems Technician", + // Keeps the infrastructure running. Never enough of them. + weight: 4, + skill_focus: ["technical"], + combat_eligible: false, + typical_behaviors: [ + "runs a diagnostic routine on a floor console, eyes on the readout", + "traces a conduit run along the ceiling with a handheld light", + "swaps a panel module with practiced speed and no wasted motion", + "logs a fault code into a datapad before moving on", + "presses an ear to a vibrating duct and listens", + "argues quietly with a display that isn't giving the right numbers", + "queries a fault log through her insert without touching the terminal, eyes briefly unfocused", + "stretches both arms overhead in the break room doorway, blocking it without noticing", + // on-shift + "taps a wrench against a junction box lid to test for rattle", + "pulls a burnt relay from a panel and holds it up to the light", + "clips a sensor lead to two terminals and watches the readout settle", + "photographs a fault site with a handheld before touching anything", + "threads a cable through a conduit run without looking, hands working by feel", + "checks a pressure gauge by putting a thumb on the dial housing and reading the needle", + "labels a repaired junction with tape and a marker, block letters", + "reads a service manual on a battered datapad, scrolling with one finger", + "kneels under a raised floor panel with a light between her teeth", + "closes a maintenance hatch and shoulder-checks it twice", + "stands on the second rung of a ladder and reaches without climbing higher", + // off-shift / break room + "sits sideways in a break room chair, back against the wall, feet on the seat beside her", + "pulls up a schematic on a personal handheld and looks at it between bites", + "refills someone else's cup from the urn without commenting on it", + "puts her boots on the break room table and doesn't move them when the foreman walks in", + "describes a problem to a dock worker who doesn't follow it but nods anyway", + "argues a point at the break room table, tapping the surface for emphasis", + "reads something on a personal device with his head tipped back and the screen held at arm's length", + "laughs until he has to set down his drink", + ], + ), + ( + id: "foreman", + label: "Shift Foreman", + // Fewer of them. High visibility. Everyone knows where they are. + weight: 2, + skill_focus: ["observation", "persuasion"], + combat_eligible: false, + typical_behaviors: [ + "walks the floor with a datapad under one arm and says nothing", + "pulls a worker aside for a quiet word near the far wall", + "marks a line off a production board and moves to the next one", + "stands at the mezzanine rail watching throughput without expression", + "reviews shift handover notes and circles something with a stylus", + "speaks to a dock crew in a low voice — they listen without nodding", + "sits alone in the break room rubbing the back of her neck, datapad face-down on the table", + "laughs at something a technician says, then catches herself and goes quiet", + // the person beneath the role + "covers a worker's absence from the shift log by redistributing the bay assignments", + "eats lunch standing at a wall terminal so she can watch the floor at the same time", + "takes the call herself instead of forwarding it, one hand pressed to her other ear against the noise", + "corrects a dock worker's form on the cargo rig harness without making it a lesson", + "walks a new hire through the handover checklist once, point by point, no shortcuts", + "keeps a junior worker between herself and the inspection team as the inspectors pass through", + "finds a reason to be nearby when a new worker makes her first solo lift", + "absorbs a production shortfall report without passing the frustration down the line", + "hands a dock worker an extra meal packet and walks away without explaining it", + "sits next to a technician in the break room and doesn't talk, just sits", + "makes a note in the shift log that takes longer to write than it takes to read", + "tells a bad joke to nobody in particular while marking off the production board", + "signs off on a repair she didn't inspect, because she knows who did it", + "stands at the edge of the loading floor for a long moment before walking back", + ], + ), + ( + id: "security", + label: "Facility Security", + // Present, watchful. Not looking for trouble — cataloguing it. + weight: 2, + skill_focus: ["combat", "observation"], + combat_eligible: true, + typical_behaviors: [ + "sweeps the access corridor on a timed circuit, same path each time", + "waves a regular through the checkpoint on sight — scans the one behind them out of procedure", + "leans at the restricted bay entrance, arms folded — been watching this corridor since the shift started", + "notes something in a shift log without reacting to it outwardly", + "watches a handover between crews from across the loading floor", + "stops at a junction, looks both ways, and picks the longer route", + "runs an ID check on someone whose face she recognizes, procedure is procedure", + "stands with her back to a structural column where both exits are visible", + "glances at a badge without stopping the person wearing it", + "checks the restricted bay door seal before settling in to watch the corridor", + ], + ), + ], + + social_sites: [ + ( + site_type: "break_room", + label: "Worker Break Room", + // Between shifts. Decompression. People stop performing for a moment. + roles: ["dock_worker", "technician", "foreman"], + min_npcs: 2, + max_npcs: 5, + ), + ( + site_type: "maintenance_bay", + label: "Maintenance Bay", + // Active work site. Technicians and dock workers cross paths here. + roles: ["technician", "dock_worker"], + min_npcs: 2, + max_npcs: 4, + ), + ( + site_type: "loading_platform", + label: "Loading Platform", + // The operational center. Busy, loud, coordinated. + roles: ["dock_worker", "foreman", "security"], + min_npcs: 3, + max_npcs: 8, + ), + ], +) diff --git a/content/global/krenn-rural-zone.ron b/content/global/krenn-rural-zone.ron new file mode 100644 index 000000000..d3f2ebf7c --- /dev/null +++ b/content/global/krenn-rural-zone.ron @@ -0,0 +1,170 @@ +// Krenn Rural Zone — location-specific zone content +// +// Schema: server/src/npc/blueprint.rs :: ZoneSpec +// Ticket: #609, #630 (copy team) +// Validate: tooling/validate-ron content/global/krenn-rural-zone.ron zone +// +// This is content for a specific location: a Krenn rural settlement. +// Behaviors, roles, and social sites are culture×zone specific — not reusable +// templates. See Q-057 for the composable behavior generation design that +// will replace hand-authored pools with assembled primitives. +// +// Character: scattered homesteads and small workshops. Unhurried. Community-bound. +// Low throughput, high familiarity. Everyone knows who belongs here. + +( + zone_type: "rural", + label: "Rural Settlement", + description: "Scattered homesteads, small workshops, and communal gathering points. Low population density, strong community bonds, subsistence-plus economy. Work is seasonal and visible — everyone knows what everyone else is doing.", + + // 1-10. Rural Krenn: self-sufficient, low cash flow, barter supplements credits. + economic_level: 3, + // 1-10. Sparse. Faces are familiar. Strangers stand out. + population_density: 2, + + roles: [ + ( + id: "farmer", + label: "Farmer", + // Most common. The settlement runs on food production. + weight: 5, + skill_focus: ["technical"], + combat_eligible: false, + typical_behaviors: [ + "tends rows of low-growing crops with a long-handled hoe", + "lifts a crate of produce onto a flatbed with practiced ease", + "checks the section's light cycle timer before deciding whether to water", + "patches a cracked irrigation pipe with strips of bonding tape", + "calls across a field to a neighbor without looking up from work", + "hauls produce to the market stall before the morning exchange opens", + "checks seedling trays in a low prefab greenhouse", + "runs a thumb along the edge of a cracked irrigation seal, then sets it aside", + "stacks empty crates at the end of a row and knocks dirt off her boots", + "drags a length of hose to a dry section and clamps the fitting by hand", + "kneels at the base of a struggling plant and parts the soil with two fingers", + "leans on a fence post and watches the sky before going back to the row", + "refills a handheld sprayer from a standing drum without spilling", + "ties a row marker to a stake with a short length of wire", + "wipes sweat from her forehead with the back of a gloved hand", + "loads a wheelbarrow and tips it into a compost bin at the field edge", + "pulls a dead plant by the roots and carries it to the burn pile", + "tests soil moisture by pressing a thumb into the ground beside a seedling", + "walks the perimeter of a field and checks the wire for breaks", + "sets two crates down on the market floor and counts the lids twice", + // tavern / off-duty + "nurses a drink at the end of the bar with both hands wrapped around the glass", + "trades short words with the mechanic at the next seat without turning fully around", + "sits with boots off under the table, socked feet flat on the floor", + "refills a neighbor's cup from her own jug without being asked", + "plays a slow tile game with two others at the corner table", + "slides a credit chit across the bar and waits for change without counting it", + "leans back in the chair and stares at the ceiling for a long moment", + ], + ), + ( + id: "mechanic", + label: "Settlement Mechanic", + // One or two per settlement. Everyone knows who to call. + weight: 3, + skill_focus: ["technical"], + combat_eligible: false, + typical_behaviors: [ + "pulls a drive unit from a tiller and examines the worn housing", + "wipes grease on the thigh of her coveralls between jobs", + "explains a repair in clipped shorthand without looking up", + "lines up salvaged parts on a workbench and assesses them", + "welds a seam on a cracked water tank with slow, careful strokes", + "borrows a tool from a neighbor and returns it without being asked", + "taps a seized bolt with a mallet twice before reaching for a longer bar", + "threads a wire through a conduit clip and bites the insulation back with her teeth", + "sets a part down, picks up the spec card beside it, and reads it once", + "uses a straight edge to check the flatness of a repaired flange", + "drains a coolant line into a catch tray and marks the container", + "torques a fastener by feel and then confirms it with a wrench click", + "stacks finished repairs in a corner and photographs them with a handheld", + "jots a note on a strip of tape and sticks it to a part's casing", + "squeezes into a narrow access panel and works by touch", + "straightens up and rolls her neck once before kneeling back down", + // tavern / off-duty + "rinses her hands twice at the basin before sitting down at the bar", + "drops her toolkit bag under the stool and orders without looking at the board", + "listens to a farmer's complaint about a tiller and nods once or twice", + "draws a rough diagram on a napkin to explain something, then folds it away", + "buys a round for the table and returns to her seat before anyone can thank her", + ], + ), + ( + id: "trader", + label: "Itinerant Trader", + // Passes through. Outsider-familiar — not local, not stranger. + weight: 2, + skill_focus: ["persuasion", "observation"], + combat_eligible: false, + typical_behaviors: [ + "squares goods on a fold-out portable display with deliberate care", + "leans back on a stool and watches the foot traffic", + "flicks credit chits across the counter with one thumb, barely glancing down", + "holds eye contact through a long pause, waiting for the price to land", + "watches a regular browse the same shelf as last time and says nothing", + "packs unsold goods with no visible frustration", + "unrolls a cloth display on the counter and weights the corners with small stones", + "lifts a sample item and sets it in the light where a browser can see it clearly", + "rewraps an unsold item and tucks it back in the case with a specific order", + "counts coins into a small tray and slides it across the counter", + "pulls a ledger from the bag, checks one line, and closes it", + "marks a price down on the board with a grease stylus and steps back", + "holds a cracked tool up to show the seller where it failed before handing it back", + "folds the portable display flat and straps it to the pack in two moves", + "lays two items side by side on the counter for a customer to compare", + "wipes down the counter surface with a cloth before setting out the next goods", + ], + ), + ( + id: "militia", + label: "Settlement Militia", + // Rare. Part-time. Knows everyone, trusted because of it. + weight: 1, + skill_focus: ["combat", "observation"], + combat_eligible: true, + typical_behaviors: [ + "walks the fence line at a measured, unhurried pace", + "leans on the gate post with rifle slung, watching the road", + "waves a familiar face through without checking credentials", + "sits in the shade of the gatehouse with a local newsline", + "stops to talk with a passing farmer, eyes still scanning the perimeter", + "checks the charge on a handheld scanner and clips it back to the belt", + "props a boot on the lower fence rail and scans the far end of the road", + "nods to a passing trader and tracks the cart until it clears the gate", + "marks a log entry on a handheld at the end of a perimeter pass", + "steps out of the gatehouse at the sound of an approaching engine", + ], + ), + ], + + social_sites: [ + ( + site_type: "tavern", + label: "Local Tavern", + // The Last Shift equivalent for rural Krenn: functional, familiar, slow. + roles: ["farmer", "mechanic", "trader", "militia"], + min_npcs: 3, + max_npcs: 6, + ), + ( + site_type: "workshop", + label: "Community Workshop", + // Shared space. People fix things together. + roles: ["mechanic", "farmer"], + min_npcs: 2, + max_npcs: 4, + ), + ( + site_type: "market_stall", + label: "Settlement Market", + // Weekly or daily trading post. Commerce and gossip combined. + roles: ["trader", "farmer"], + min_npcs: 1, + max_npcs: 3, + ), + ], +) diff --git a/content/global/rural-zone-spec.ron b/content/global/rural-zone-spec.ron deleted file mode 100644 index d9c9c0471..000000000 --- a/content/global/rural-zone-spec.ron +++ /dev/null @@ -1,119 +0,0 @@ -// Zone Identity Spec — Rural -// -// Schema: server/src/npc/blueprint.rs :: ZoneSpec -// Ticket: #609 (copy team) -// Validate: tooling/validate-ron content/global/rural-zone-spec.ron zone -// -// Character: scattered homesteads and small workshops. Unhurried. Community-bound. -// Low throughput, high familiarity. Everyone knows who belongs here. -// -// Generator contrast target: rural vs industrial (Sprint 25 proof). -// If these produce NPCs that look the same, something is wrong. -// -// Heritage roots (D-104/D-105) overlay these base specs at generation time, -// modifying role weights, social site composition, and behavioral flavoring. - -( - zone_type: "rural", - label: "Rural Settlement", - description: "Scattered homesteads, small workshops, and communal gathering points. Low population density, strong community bonds, subsistence-plus economy. Work is seasonal and visible — everyone knows what everyone else is doing.", - - // 1-10. Rural Krenn: self-sufficient, low cash flow, barter supplements credits. - economic_level: 3, - // 1-10. Sparse. Faces are familiar. Strangers stand out. - population_density: 2, - - roles: [ - ( - id: "farmer", - label: "Farmer", - // Most common. The settlement runs on food production. - weight: 5, - skill_focus: ["technical"], - combat_eligible: false, - typical_behaviors: [ - "tends rows of low-growing crops with a long-handled hoe", - "lifts a crate of produce onto a flatbed with practiced ease", - "checks the section's light cycle timer before deciding whether to water", - "patches a cracked irrigation pipe with strips of bonding tape", - "calls across a field to a neighbor without looking up from work", - "hauls produce to the market stall before the morning exchange opens", - "checks seedling trays in a low prefab greenhouse", - ], - ), - ( - id: "mechanic", - label: "Settlement Mechanic", - // One or two per settlement. Everyone knows who to call. - weight: 3, - skill_focus: ["technical"], - combat_eligible: false, - typical_behaviors: [ - "pulls a drive unit from a tiller and examines the worn housing", - "wipes grease on the thigh of her coveralls between jobs", - "explains a repair in clipped shorthand without looking up", - "lines up salvaged parts on a workbench and assesses them", - "welds a seam on a cracked water tank with slow, careful strokes", - "borrows a tool from a neighbor and returns it without being asked", - ], - ), - ( - id: "trader", - label: "Itinerant Trader", - // Passes through. Outsider-familiar — not local, not stranger. - weight: 2, - skill_focus: ["persuasion", "observation"], - combat_eligible: false, - typical_behaviors: [ - "squares goods on a fold-out portable display with deliberate care", - "leans back on a stool and watches the foot traffic", - "flicks credit chits across the counter with one thumb, barely glancing down", - "holds eye contact through a long pause, waiting for the price to land", - "watches a regular browse the same shelf as last time and says nothing", - "packs unsold goods with no visible frustration", - ], - ), - ( - id: "militia", - label: "Settlement Militia", - // Rare. Part-time. Knows everyone, trusted because of it. - weight: 1, - skill_focus: ["combat", "observation"], - combat_eligible: true, - typical_behaviors: [ - "walks the fence line at a measured, unhurried pace", - "leans on the gate post with rifle slung, watching the road", - "waves a familiar face through without checking credentials", - "sits in the shade of the gatehouse with a local newsline", - "stops to talk with a passing farmer, eyes still scanning the perimeter", - ], - ), - ], - - social_sites: [ - ( - site_type: "tavern", - label: "Local Tavern", - // The Last Shift equivalent for rural Krenn: functional, familiar, slow. - roles: ["farmer", "mechanic", "trader", "militia"], - min_npcs: 3, - max_npcs: 6, - ), - ( - site_type: "workshop", - label: "Community Workshop", - // Shared space. People fix things together. - roles: ["mechanic", "farmer"], - min_npcs: 2, - max_npcs: 4, - ), - ( - site_type: "market_stall", - label: "Settlement Market", - // Weekly or daily trading post. Commerce and gossip combined. - roles: ["trader", "farmer"], - min_npcs: 1, - max_npcs: 3, - ), - ], -) From 5169629ac762b8836833dfd0656aff80890ed4f2 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sat, 7 Mar 2026 11:29:50 +0100 Subject: [PATCH 2/3] docs(decisions): add Q-057 composable behavior generation Open question for decomposing hand-authored behavior pools into composable primitives (role actions + culture modifiers + context tags). Part of Sprint 25 PoC spike. Server ticket #633, copy ticket #634. Co-Authored-By: Claude Opus 4.6 --- decisions/questions-content.md | 15 ++++++++++++++- decisions/questions.md | 6 +++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/decisions/questions-content.md b/decisions/questions-content.md index 93a913b5c..8f5c799e3 100644 --- a/decisions/questions-content.md +++ b/decisions/questions-content.md @@ -190,4 +190,17 @@ Narrative, NPCs, dialogue, templates, setting, worldbuilding, and storyteller me --- -*20 questions (5 resolved, 2 partially resolved, 13 open). Last updated: 2026-03-07 (Q-056 added — Sprint 25 review)* +### Q-057: Composable behavior generation — decompose culture × role × context into assembled behaviors + +- **Status:** Open +- **Raised:** Sprint 25, ticket #630 review discussion +- **Priority:** High (blocks scaling beyond hand-authored content) +- **Context:** Current behavior pools are hand-authored per culture×zone×role combination (`typical_behaviors` arrays in zone spec RON files). At ~50 behaviors per role × 4 roles × N zone types × M cultures, this is O(roles × zones × cultures) custom content. Each cell is effectively a unique location — "rural zone spec" is really "Krenn rural settlement content" with the name filed off. This doesn't scale to multiple cultures or zone types. +- **Question:** Should the generator compose observable behaviors from smaller primitives instead of drawing from pre-written complete sentences? Proposed decomposition: (1) **role action templates** — generic observable stage directions per role, culture-neutral, (2) **culture modifier sets** — culture-specific flavoring (Krenn mannerisms, speech patterns, social norms) that overlay role actions, (3) **context tags** — on-shift, off-duty, break-room, social-site-type that filter/weight which behaviors are available. The generator assembles these at runtime. +- **Implications:** Changes the content authoring model from "write 50 sentences per role per zone per culture" to "write role actions once, write culture modifiers once, compose at runtime." Server needs a composition engine (#633); copy needs to author the decomposed format (#634). Part of the Sprint 25 PoC spike. +- **Cross-reference:** #630 (behavior pool expansion), #633 (server: composition engine), #634 (copy: decomposed content format), D-121 (voice is culture-driven), D-122 (all NPCs generated) +- **Assigned to:** Tyre, Mellanie, Miri + +--- + +*21 questions (5 resolved, 2 partially resolved, 14 open). Last updated: 2026-03-07 (Q-057 added — composable behaviors)* diff --git a/decisions/questions.md b/decisions/questions.md index 5aba5fcb3..aaf8bb3fa 100644 --- a/decisions/questions.md +++ b/decisions/questions.md @@ -8,7 +8,7 @@ Tracked questions awaiting discussion or resolution. Split by domain, mirroring |------|--------|-----------| | [questions-architecture.md](questions-architecture.md) | Technical foundation | Q-001, Q-006, Q-009, Q-018, Q-019, Q-020, Q-021, Q-022, Q-023, Q-029, Q-030, Q-046 | | [questions-perception.md](questions-perception.md) | Player observation | Q-003, Q-014, Q-016, Q-024, Q-025, Q-026, Q-051, Q-053, Q-054 | -| [questions-content.md](questions-content.md) | Narrative, NPCs, setting | Q-010, Q-012, Q-013, Q-015, Q-017, Q-028, Q-031, Q-033, Q-040, Q-041, Q-042, Q-043, Q-044, Q-045, Q-047, Q-048, Q-049, Q-050, Q-052, Q-056 | +| [questions-content.md](questions-content.md) | Narrative, NPCs, setting | Q-010, Q-012, Q-013, Q-015, Q-017, Q-028, Q-031, Q-033, Q-040, Q-041, Q-042, Q-043, Q-044, Q-045, Q-047, Q-048, Q-049, Q-050, Q-052, Q-056, Q-057 | | [questions-scope.md](questions-scope.md) | Game concept, prototype | Q-002, Q-004, Q-005, Q-007, Q-008, Q-011, Q-027, Q-032, Q-034, Q-035, Q-036, Q-037, Q-038, Q-039 | ## Status Summary @@ -17,9 +17,9 @@ Tracked questions awaiting discussion or resolution. Split by domain, mirroring |--------|-------|----------|---------|------| | Architecture | 12 | 6 | 1 | 5 | | Perception | 9 | 5 | 1 | 3 | -| Content | 19 | 5 | 2 | 12 | +| Content | 21 | 5 | 2 | 14 | | Scope | 14 | 1 | 3 | 10 | -| **Total** | **54** | **17** | **7** | **30** | +| **Total** | **56** | **17** | **7** | **32** | *Updated 2026-03-05: Q-011 resolved (D-117/D-115/D-122), Q-034 partially resolved (D-117), Q-037 partially resolved (D-119), Q-033 partially resolved/reframed (D-122) — Where's the Fun? Workshop* From ba77c2f71fc92fca15e215bb98f2d912adb8d393 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sat, 7 Mar 2026 11:30:09 +0100 Subject: [PATCH 3/3] chore(meta): update changelog Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c32e2e66..8131a8906 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ Format based on [Keep a Changelog](https://keepachangelog.com/). ## [Unreleased] +### Added +- Zone identity specs renamed to location-specific: krenn-rural-zone.ron and krenn-industrial-zone.ron — acknowledges these are culture×zone content, not reusable templates (#630, Q-057) +- ~108 new NPC behavior pool entries across all roles in both zone files — trader stage directions, foreman humanity behaviors, dock_worker/technician off-shift/break room behaviors (#630) +- Q-057 open question: composable behavior generation — decompose hand-authored pools into role actions + culture modifiers + context tags (#633, #634) + ## [v0.1.24] — 2026-03-06 ### Changed