feat(copy): restructure behavior primitives into zone-type templates (#661, D-142)

Move behavior_primitives from per-location zone specs into global
zone-type template files (content/global/zone-types/). Location specs
now declare zone_type and contain only metadata (role weights, social
sites, economic/density levels). Primitives are culture-neutral and
reusable across all 300+ systems. Scrub Krenn-specific language.

New files: rural_agricultural.ron, industrial_freight.ron
Modified: krenn-rural-zone.ron, krenn-industrial-zone.ron (metadata only)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 11:45:42 +01:00
co-authored by Claude Opus 4.6
parent 56b8bbfeb9
commit f44a105e96
4 changed files with 374 additions and 291 deletions
+19 -143
View File
@@ -1,19 +1,21 @@
// Krenn Industrial Zone — location-specific zone content
// Krenn Industrial Zone — location metadata
//
// Schema: server/src/npc/blueprint.rs :: ZoneSpec
// Ticket: #609, #630 (copy team)
// Ticket: #609, #630, #661 (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.
// Location-specific metadata for a Krenn industrial freight district.
// Behavior primitives have moved to the zone-type template:
// content/global/zone-types/industrial_freight.ron
//
// This file holds: zone_type reference, location metadata, role weights, social sites.
// The generator reads zone_type to find the primitive pool; overrides come from here.
//
// Character: freight handling, manufacturing, maintenance. High throughput.
// Shift rhythms. Functional over comfortable. Nobody lingers — unless they're on break.
(
zone_type: "industrial",
zone_type: "industrial_freight",
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.",
@@ -22,139 +24,13 @@
// 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",
],
),
// Role presence and weights for this location.
// skill_focus / combat_eligible / behavior_primitives live in the zone-type template.
role_weights: [
( id: "dock_worker", weight: 5 ),
( id: "technician", weight: 4 ),
( id: "foreman", weight: 2 ),
( id: "security", weight: 2 ),
],
social_sites: [
@@ -162,7 +38,6 @@
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,
),
@@ -170,7 +45,6 @@
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,
),
@@ -178,9 +52,11 @@
site_type: "loading_platform",
label: "Loading Platform",
// The operational center. Busy, loud, coordinated.
roles: ["dock_worker", "foreman", "security"],
min_npcs: 3,
max_npcs: 8,
),
],
abandoned: false,
poi_overlay: None,
)
+22 -148
View File
@@ -1,19 +1,21 @@
// Krenn Rural Zone — location-specific zone content
// Krenn Rural Zone — location metadata
//
// Schema: server/src/npc/blueprint.rs :: ZoneSpec
// Ticket: #609, #630 (copy team)
// Ticket: #609, #630, #661 (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.
// Location-specific metadata for a Krenn rural agricultural settlement.
// Behavior primitives have moved to the zone-type template:
// content/global/zone-types/rural_agricultural.ron
//
// This file holds: zone_type reference, location metadata, role weights, social sites.
// The generator reads zone_type to find the primitive pool; overrides come from here.
//
// Character: scattered homesteads and small workshops. Unhurried. Community-bound.
// Low throughput, high familiarity. Everyone knows who belongs here.
(
zone_type: "rural",
zone_type: "rural_agricultural",
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.",
@@ -22,149 +24,21 @@
// 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",
],
),
// Role presence and weights for this location.
// skill_focus / combat_eligible / behavior_primitives live in the zone-type template.
role_weights: [
( id: "farmer", weight: 5 ),
( id: "mechanic", weight: 3 ),
( id: "trader", weight: 2 ),
( id: "militia", weight: 1 ),
],
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,
),
( site_type: "tavern", label: "Local Tavern", min_npcs: 3, max_npcs: 6 ),
( site_type: "workshop", label: "Community Workshop", min_npcs: 2, max_npcs: 4 ),
( site_type: "market_stall", label: "Settlement Market", min_npcs: 1, max_npcs: 3 ),
],
abandoned: false,
poi_overlay: None,
)
@@ -0,0 +1,168 @@
// Industrial Freight Zone-Type Template
//
// Schema: server/src/npc/blueprint.rs :: ZoneTypeTemplate
// Ticket: #661 (copy team)
// Validate: tooling/validate-ron content/global/zone-types/industrial_freight.ron zone_type
//
// Sources: D-141 (zone-type template architecture).
//
// Zone character: freight handling, cargo throughput, shift-based manufacturing.
// High throughput, functional over comfortable. Faces known by role and bay number.
// The work doesn't stop between shifts — people do.
//
// Primitives are CULTURE-NEUTRAL. Culture modifiers (culture-*.ron files) append
// cultural flavor at assembly time. Do not encode cultural attitudes in action text.
//
// Roles: dock_worker, technician, foreman, security
// Social site types: break_room, maintenance_bay, loading_platform
(
id: "industrial_freight",
subtype: None,
label: "Industrial Freight Zone",
description: "Freight handling, cargo throughput, shift-based work rhythms. Functional over comfortable. Faces known by role and bay number. The work doesn't stop between shifts — people do.",
// Default economic/density profile. Location specs override.
economic_level: 7,
population_density: 6,
roles: [
(
id: "dock_worker",
label: "Dock Worker",
skill_focus: ["technical"],
combat_eligible: false,
// weight omitted — location specs declare role_weights
behavior_primitives: [
// OnShift
( action: "guides a freight container into position with hand signals", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "checks a manifest against a handheld scanner", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "waits at the loading bay apron, watching the clock", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "calls bay numbers to a colleague across the noise of the floor", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "hooks a cargo sling and steps clear before signaling the lift", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "stacks empty pallets against a wall", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "wipes sweat from her face with a forearm and keeps moving", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "drags a heavy case along the deck plating one-handed, leaning into the weight", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "re-checks a seal on a container door after a colleague already checked it", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "flags a damaged pallet to the foreman without stopping the line", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "shoulders a cargo rig harness and clips in without looking down", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "sweeps debris off the loading apron with a long push broom", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "braces a container with a boot while reaching for the locking pin", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "reads the load ticket twice, then flips the handheld over to check the back", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "waves off a crane operator when the angle is wrong, holds up a fist", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "steps over a bundled cable run without breaking stride", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "peels off a work glove with his teeth to check a handheld display", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "exchanges a brief look with a nearby colleague when the supervisor passes", context: OnShift, modifier_hint: Some("authority_response") ),
// OffDuty / break room
( action: "slumps into a break room chair and stares at nothing for a full minute before reaching for a drink", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "unwraps a meal packet in the break room and eats standing at the counter", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "passes a drink to the person next to her without being asked", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "leans back in a break room chair with eyes closed, boots crossed at the ankle", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "laughs at something across the break room table, loud enough to carry", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "shows something on a handheld to a colleague and both of them look at it", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "sits with elbows on knees, turning an empty cup in both hands", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "splashes water on his face at the sink and stands there a moment before turning off the tap", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "talks over the break room noise at volume, gesturing with a fork", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "falls asleep in a break room chair, chin on chest, arms folded", context: OffDuty, modifier_hint: Some("offduty_posture") ),
],
),
(
id: "technician",
label: "Systems Technician",
skill_focus: ["technical"],
combat_eligible: false,
behavior_primitives: [
// OnShift
( action: "runs a diagnostic routine on a floor console, eyes on the readout", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "traces a conduit run along the ceiling with a handheld light", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "swaps a panel module, tools back in the pouch before the cover is latched", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "logs a fault code into a datapad before moving on", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "presses an ear to a vibrating duct and listens", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "argues quietly with a display that isn't giving the right numbers", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "queries a fault log through a terminal, eyes briefly unfocused", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "taps a wrench against a junction box lid to test for rattle", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "pulls a burnt relay from a panel and holds it up to the light", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "clips a sensor lead to two terminals and watches the readout settle", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "photographs a fault site with a handheld before touching anything", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "threads a cable through a conduit run without looking, hands working by feel", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "checks a pressure gauge by putting a thumb on the dial housing and reading the needle", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "labels a repaired junction with tape and a marker, block letters", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "reads a service manual on a battered datapad, scrolling with one finger", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "kneels under a raised floor panel with a light between her teeth", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "closes a maintenance hatch and shoulder-checks it twice", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "stands on the second rung of a ladder and reaches without climbing higher", context: OnShift, modifier_hint: Some("physical_manner") ),
// OffDuty / break room
( action: "stretches both arms overhead in the break room doorway, blocking it without noticing", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "sits sideways in a break room chair, back against the wall, feet on the seat beside her", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "pulls up a schematic on a personal handheld and looks at it between bites", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "refills someone else's cup from the urn without commenting on it", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "puts her boots on the break room table when off-shift", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "describes a problem to a colleague who doesn't follow it but nods anyway", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "argues a point at the break room table, tapping the surface for emphasis", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "reads something on a personal device with his head tipped back and the screen held at arm's length", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "laughs until he has to set down his drink", context: OffDuty, modifier_hint: Some("social_signal") ),
],
),
(
id: "foreman",
label: "Shift Foreman",
skill_focus: ["observation", "persuasion"],
combat_eligible: false,
behavior_primitives: [
// OnShift
( action: "walks the floor with a datapad under one arm and says nothing", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "pulls a worker aside for a quiet word near the far wall", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "marks a line off a production board and moves to the next one", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "stands at the mezzanine rail watching throughput without expression", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "reviews shift handover notes and circles something with a stylus", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "speaks to a crew in a low voice — they listen without nodding", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "covers a worker's absence from the shift log by redistributing the bay assignments", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "eats lunch standing at a wall terminal so she can keep an eye on the work", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "takes the call herself instead of forwarding it", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "corrects a worker's form on a piece of equipment without making it a lesson", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "walks a new hire through the handover checklist once, point by point, no shortcuts", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "keeps a junior worker between herself and the inspection team as the inspectors pass through", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "finds a reason to be nearby when a new worker makes her first solo lift", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "absorbs a production shortfall report without passing the frustration down the line", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "hands a worker an extra meal packet and walks away without explaining it", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "signs off on a repair she didn't inspect, because she knows who did it", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "stands at the edge of the loading floor for a long moment before walking back", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "makes a note in the shift log that takes longer to write than it takes to read", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "tells a bad joke to nobody in particular while marking off the production board", context: OnShift, modifier_hint: Some("social_signal") ),
// OffDuty
( action: "sits alone in the break room rubbing the back of her neck, datapad face-down on the table", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "laughs at something a colleague says, then catches herself and goes quiet", context: OffDuty, modifier_hint: Some("social_signal") ),
( action: "sits next to someone in the break room and doesn't talk, just sits", context: OffDuty, modifier_hint: Some("social_signal") ),
],
),
(
id: "security",
label: "Facility Security",
skill_focus: ["combat", "observation"],
combat_eligible: true,
behavior_primitives: [
// OnShift
( action: "sweeps the access corridor on a timed circuit, same path each time", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "waves a regular through the checkpoint on sight — scans the one behind them out of procedure", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "leans at the restricted bay entrance, arms folded, watching the corridor", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "notes something in a shift log without reacting to it outwardly", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "watches a handover between crews from across the loading floor", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "stops at a junction, looks both ways, and picks the longer route", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "runs an ID check on someone whose face she recognizes, procedure is procedure", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "stands with her back to a structural column where both exits are visible", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "glances at a badge without stopping the person wearing it", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "checks the restricted bay door seal before settling in to watch the corridor", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "runs the same check routine when the supervisor is watching as when she isn't", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "acknowledges the facility manager's walk-through with a nod and doesn't change her position", context: OnShift, modifier_hint: Some("authority_response") ),
],
),
],
// Valid social site types for this zone type.
// Location specs declare which appear, with their own label, min_npcs, max_npcs.
social_site_types: [
( site_type: "break_room", eligible_roles: ["dock_worker", "technician", "foreman"] ),
( site_type: "maintenance_bay", eligible_roles: ["technician", "dock_worker"] ),
( site_type: "loading_platform", eligible_roles: ["dock_worker", "foreman", "security"] ),
],
)
@@ -0,0 +1,165 @@
// Rural Agricultural Zone-Type Template
//
// Schema: server/src/npc/blueprint.rs :: ZoneTypeTemplate
// Ticket: #661 (copy team)
// Validate: tooling/validate-ron content/global/zone-types/rural_agricultural.ron zone_type
//
// Sources: D-141 (zone-type template architecture).
//
// Zone character: scattered homesteads, small workshops, open agricultural land.
// Seasonal work rhythms, low population density, strong community familiarity.
// Work is visible and shared — everyone knows what everyone else is doing.
//
// Primitives are CULTURE-NEUTRAL. Culture modifiers (culture-*.ron files) append
// cultural flavor at assembly time. Do not encode cultural attitudes in action text.
//
// Roles: farmer, mechanic, trader, militia
// Social site types: tavern, workshop, market_stall
(
id: "rural_agricultural",
subtype: None,
label: "Rural Agricultural Zone",
description: "Crop farming, small workshops, communal settlement. Low density, community-bonded, self-sufficient economy. Work is visible to neighbors — everyone knows what everyone else is doing.",
// Default economic/density profile. Location specs override.
economic_level: 3,
population_density: 2,
roles: [
(
id: "farmer",
label: "Farmer",
skill_focus: ["technical"],
combat_eligible: false,
// weight omitted — location specs declare role_weights
behavior_primitives: [
// OnShift
( action: "works back along a crop row, stopping to pull weeds by the root", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "lifts a crate of produce onto a flatbed and reaches for the next before it settles", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "checks the section's light cycle timer before deciding whether to water", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "patches a cracked irrigation pipe with bonding tape", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "calls across a field to a neighbor without looking up from work", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "hauls produce to the market stall before the morning exchange opens", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "crouches over seedling trays and pinches back a leggy stem that grew sideways", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "runs a thumb along the edge of a cracked irrigation seal, then sets it aside", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "stacks empty crates at the end of a row", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "drags a length of hose to a dry section and clamps the fitting by hand", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "kneels at the base of a struggling plant and parts the soil with two fingers", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "leans on a fence post and watches the sky before going back to the row", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "refills a handheld sprayer from a standing drum", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "ties a row marker to a stake with a short length of wire", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "pulls a glove off to wipe her face, pulls it back on without looking", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "loads a wheelbarrow and tips it into a compost bin at the field edge", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "pulls a dead plant by the roots and carries it to the burn pile", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "tests soil moisture by pressing a thumb into the ground beside a seedling", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "walks the field edge, pulling the wire taut at each span to test the tension", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "sets two crates down on the market floor and counts the lids twice", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "answers an inspector's question without breaking the task rhythm", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "waits for the settlement head to finish speaking before going back to work", context: OnShift, modifier_hint: Some("authority_response") ),
// Social / off-duty
( action: "nurses a drink at the end of the bar with both hands wrapped around the glass", context: Social, modifier_hint: Some("offduty_posture") ),
( action: "trades short words with the person at the next seat without turning fully around", context: Social, modifier_hint: Some("social_signal") ),
( action: "sits with boots off under the table, socked feet flat on the floor", context: Social, modifier_hint: Some("offduty_posture") ),
( action: "refills a neighbor's cup from her own jug without being asked", context: Social, modifier_hint: Some("social_signal") ),
( action: "plays a slow tile game with two others at the corner table", context: Social, modifier_hint: Some("offduty_posture") ),
( action: "slides a credit chit across the bar and waits for change without counting it", context: Social, modifier_hint: Some("offduty_posture") ),
( action: "leans back in the chair and stares at the ceiling for a long moment", context: Social, modifier_hint: Some("offduty_posture") ),
],
),
(
id: "mechanic",
label: "Settlement Mechanic",
skill_focus: ["technical"],
combat_eligible: false,
behavior_primitives: [
// OnShift
( action: "pulls a drive unit from a tiller and examines the worn housing", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "wipes grease on the thigh of her coveralls between jobs", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "explains a repair in clipped shorthand without looking up", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "lines up salvaged parts on a workbench and assesses them", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "welds a seam on a cracked water tank with slow, careful strokes", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "borrows a tool from a neighbor and returns it without being asked", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "taps a seized bolt with a mallet twice before reaching for a longer bar", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "threads a wire through a conduit clip and bites the insulation back with her teeth", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "sets a part down, picks up the spec card beside it, and reads it once", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "uses a straight edge to check the flatness of a repaired flange", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "drains a coolant line into a catch tray and marks the container", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "torques a fastener by feel and then confirms it with a wrench click", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "stacks finished repairs in a corner and photographs them with a handheld", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "jots a note on a strip of tape and sticks it to a part's casing", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "squeezes into a narrow access panel and works by touch", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "straightens up and rolls her neck once before kneeling back down", context: OnShift, modifier_hint: Some("physical_manner") ),
// Social / off-duty
( action: "rinses her hands twice at the basin before sitting down at the bar", context: Social, modifier_hint: Some("offduty_posture") ),
( action: "drops her toolkit bag under the stool and orders without looking at the board", context: Social, modifier_hint: Some("offduty_posture") ),
( action: "listens to a complaint about a piece of equipment and nods once or twice", context: Social, modifier_hint: Some("social_signal") ),
( action: "draws a rough diagram on a napkin to explain something, then folds it away", context: Social, modifier_hint: Some("social_signal") ),
( action: "buys a round for the table and returns to her seat before anyone can thank her", context: Social, modifier_hint: Some("social_signal") ),
],
),
(
id: "trader",
label: "Itinerant Trader",
skill_focus: ["persuasion", "observation"],
combat_eligible: false,
behavior_primitives: [
// OnShift
( action: "squares goods on a fold-out portable display", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "leans back on a stool and tracks a browser who has checked the same display twice without committing", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "flicks credit chits across the counter with one thumb", context: OnShift, modifier_hint: Some("physical_manner") ),
( action: "holds eye contact through a long pause, waiting for the price to land", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "watches a regular browse the same shelf as last time and says nothing", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "packs unsold goods without reacting", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "unrolls a cloth display on the counter and weights the corners with small stones", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "lifts a sample item and sets it in the light where a browser can see it clearly", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "rewraps an unsold item and tucks it back in the case with a specific order", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "counts coins into a small tray and slides it across the counter", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "pulls a ledger from the bag, checks one line, and closes it", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "marks a price down on the board with a grease stylus and steps back", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "holds a cracked item up to show where it failed before handing it back", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "folds the portable display flat and straps it to the pack in two moves", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "lays two items side by side on the counter for a customer to compare", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "wipes down the counter surface with a cloth before setting out the next goods", context: OnShift, modifier_hint: Some("work_pace") ),
// Social
( action: "nurses a drink at the far end of the bar, watching who comes in", context: Social, modifier_hint: Some("environmental_scan") ),
( action: "talks price with whoever's sitting nearest without making it a pitch", context: Social, modifier_hint: Some("social_signal") ),
( action: "buys a round and tracks who accepts and who doesn't", context: Social, modifier_hint: Some("social_signal") ),
( action: "listens more than she talks at the bar, refilling her glass slowly", context: Social, modifier_hint: Some("offduty_posture") ),
],
),
(
id: "militia",
label: "Settlement Militia",
skill_focus: ["combat", "observation"],
combat_eligible: true,
behavior_primitives: [
// OnShift
( action: "walks the fence line at a measured, unhurried pace", context: OnShift, modifier_hint: Some("work_pace") ),
( action: "leans on the gate post with rifle slung, watching the road", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "waves a familiar face through without checking credentials", context: OnShift, modifier_hint: Some("social_signal") ),
// on-duty quiet time — context is OnShift but posture reads as off-duty
( action: "sits in the shade of the gatehouse reading a local newsline", context: OnShift, modifier_hint: Some("offduty_posture") ),
( action: "stops to talk with a passerby, eyes still scanning the perimeter", context: OnShift, modifier_hint: Some("social_signal") ),
( action: "checks the charge on a handheld scanner and clips it back to the belt", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "props a boot on the lower fence rail and scans the far end of the road", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "nods to a passing cart and tracks it until it clears the gate", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "marks a log entry on a handheld at the end of a perimeter pass", context: OnShift, modifier_hint: Some("task_completion") ),
( action: "steps out of the gatehouse at the sound of an approaching engine", context: OnShift, modifier_hint: Some("environmental_scan") ),
( action: "reports a situation to the settlement head without editorializing", context: OnShift, modifier_hint: Some("authority_response") ),
( action: "straightens slightly when the relief officer arrives for handover", context: OnShift, modifier_hint: Some("authority_response") ),
// OffDuty
( action: "sits at the end of the bar still in kit, drink in hand, not really off yet", context: OffDuty, modifier_hint: Some("offduty_posture") ),
( action: "catches up with a neighbor over a drink without mentioning work", context: Social, modifier_hint: Some("social_signal") ),
],
),
],
// Valid social site types for this zone type.
// Location specs declare which appear, with their own label, min_npcs, max_npcs.
social_site_types: [
( site_type: "tavern", eligible_roles: ["farmer", "mechanic", "trader", "militia"] ),
( site_type: "workshop", eligible_roles: ["mechanic", "farmer"] ),
( site_type: "market_stall", eligible_roles: ["trader", "farmer"] ),
],
)