refactor(simulation): move content/ under server/ (#669)
Content files (RON templates, YAML campaigns, gauntlet data) are consumed exclusively by the server. Colocate them at server/content/ and update all path references in Rust source, tooling scripts, and schema files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
// Osse Margin Culture Profile
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: CultureProfile
|
||||
// Ticket: #653 (copy team)
|
||||
// Validate: tooling/validate-ron content/global/culture-osse.ron culture
|
||||
//
|
||||
// Sources: D-036 (cultural generation framework), D-121 (voice is culture-driven),
|
||||
// D-128 (culture implicit in location), D-138 (voice pipeline).
|
||||
//
|
||||
// Osse: ~60 years settled. Deep Frontier K-class system. Resource extraction industry.
|
||||
// Company-margin culture — contractor extraction operations, skeleton Commission presence.
|
||||
// Your shift team is the fundamental social unit. Words cost attention; attention
|
||||
// keeps you alive. Trust built through shared risk, not time.
|
||||
//
|
||||
// Heritage root: Salt — utilitarian_cover. Labor function covers presence.
|
||||
// The Salt pattern at the margin: your excuse for being somewhere is your work.
|
||||
// Privacy isn't something you negotiate; it's something you don't need to
|
||||
// explain if you're holding a tool.
|
||||
|
||||
(
|
||||
id: "osse",
|
||||
name: "Osse Margin Culture",
|
||||
description: "Deep Frontier extraction culture. ~60 years settled, K-class system. Labor-primary, shift-team-bonded, economy of language is survival habit. Trust through shared risk. Authority is company-first, Commission intermittent. Separatist sympathy endemic.",
|
||||
|
||||
naming: (
|
||||
style: "short, work-derived, first-name-only in all practical contexts",
|
||||
// Osse names: 1 syllable common, 2 syllables maximum.
|
||||
// Work names often diverge from legal names. The name you work under
|
||||
// is the name people know. Family names exist but nobody uses them on-site.
|
||||
given_names: [
|
||||
// Core Osse work names — extraction-environment origin
|
||||
"Grek", "Doss", "Skeld", "Arn", "Mor",
|
||||
"Tuk", "Brek", "Mal", "Vor", "Kes",
|
||||
"Noss", "Drel", "Pek", "Bev", "Hem",
|
||||
"Joss", "Morn", "Koss", "Sket", "Tor",
|
||||
// Extended — same register (no duplicates)
|
||||
"Drav", "Vels", "Brel", "Vorn", "Vok",
|
||||
"Ark", "Goss", "Tem", "Moren", "Mek",
|
||||
"Sorn", "Prav", "Kel", "Nosk", "Breld",
|
||||
],
|
||||
family_names: [
|
||||
// Exist legally but used only on company contracts and Commission paperwork
|
||||
"Brekker", "Vellar", "Tornack", "Mosse", "Kessick",
|
||||
"Pesska", "Grekkar", "Grekkon", "Mossen", "Pekkar",
|
||||
"Morden", "Gressen", "Velken", "Tornak", "Arkson",
|
||||
],
|
||||
// Osse culture is work-name-primary.
|
||||
// Legal family names appear on company contracts, work credentials,
|
||||
// and Commission documentation. Nowhere else.
|
||||
family_name_used_socially: false,
|
||||
),
|
||||
|
||||
speech: (
|
||||
// Terse, functional, equipment-adjacent vocabulary.
|
||||
// Noise and suit comms trained this register: say it in six words, not sixteen.
|
||||
// Silence is comfortable; you fill it with work, not words.
|
||||
register: "terse, functional, equipment vocabulary, economy of language",
|
||||
filler_words: [
|
||||
"yeah",
|
||||
"right",
|
||||
"copy",
|
||||
"solid",
|
||||
"nah",
|
||||
],
|
||||
greetings: [
|
||||
// Osse greeting register: terse, functional, sometimes just the person's
|
||||
// name. Name-only greetings are served via name substitution at runtime.
|
||||
"You good?",
|
||||
"Still breathing?",
|
||||
"Hey.",
|
||||
"Yeah?",
|
||||
"What do you need?",
|
||||
],
|
||||
farewells: [
|
||||
"Stay sealed.",
|
||||
"Watch the drift.",
|
||||
"Good shift.",
|
||||
"Yeah.",
|
||||
"Next shift.",
|
||||
"Keep pressure.",
|
||||
],
|
||||
// Osse expressions: extraction vocabulary — vacuum, pressure, equipment failure.
|
||||
// These are what kills you. You swear by what's real.
|
||||
// Different from Van Maanen's Star void-oaths — Osse is margin industrial, not station working-class.
|
||||
exclamations: [
|
||||
"void drain it",
|
||||
"down pressure",
|
||||
"dead vacuum",
|
||||
"salt-blast",
|
||||
"pressure drop",
|
||||
],
|
||||
),
|
||||
|
||||
values: (
|
||||
description: "Labor-primary, shift-team-bonded. Trust through shared risk, not time or credential. Information is kept close until there's a reason to share it. Warmth is physical and brief — a grip on the arm, not a speech. Company authority accepted as fact; Commission authority tolerated as distant paperwork. Separatist sympathy is practical, not ideological.",
|
||||
// Traits more common in Osse culture.
|
||||
// Bold: do the dangerous thing, but prepare it properly.
|
||||
// Cautious: information-cautious, not physically cautious — you don't reveal more than needed.
|
||||
// Honest: you don't lie to your team about equipment state. Someone dies if you do.
|
||||
favored_traits: [Bold, Cautious, Honest],
|
||||
// Traits less common.
|
||||
// Social: unnecessary talk is a distraction in dangerous work.
|
||||
// Deceptive: lying to your team about equipment or conditions is a survival failure.
|
||||
// Incurious: you die if you stop noticing your environment.
|
||||
disfavored_traits: [Social, Deceptive, Incurious],
|
||||
),
|
||||
|
||||
// Voice pipeline: persona block, examples, and occasional injections.
|
||||
// Osse v1 — authored Sprint 26 (#653). Not yet Spike-validated.
|
||||
// 6-block format per workshop-outcomes.md Section 7.3.
|
||||
voice_persona: Some(
|
||||
"PERSONA: You are an Osse margin worker.\n1. Economy of language is a survival habit. Noise and equipment and suit comms trained you: six words, not sixteen. If it fits in two, use two.\n2. You're from the deep edge of the Reach. Distance from Core systems means you solve your own problems. Authority arrives too late to matter — you've already handled it.\n3. First names or work names, nothing else. Nobody uses family names on-site — too formal for a place where names travel through suit mikes.\n4. Trust is built through shared risk, not time. Someone who pulled you out of a bad situation outranks someone you've known for years.\n5. Risk assessment runs under everything. Before you say anything, you've already clocked who's listening and what they might do with it.\n6. When surprised or frustrated: \"void drain it,\" \"down pressure,\" \"dead vacuum,\" \"salt-blast,\" \"pressure drop.\"\n7. Warmth is physical and brief: a grip on the arm, not a speech. You don't perform warmth.\n\nNEVER: institutional framing, formal courtesy protocols, or administrative vocabulary — these read as Commission-world outsider. Never use complete formal sentences when a word or number suffices. Never reference the Lattice Commission as locally present or relevant. Never use Core-system exclamations. Never elaborate where silence or a number will do."
|
||||
),
|
||||
|
||||
voice_examples: [
|
||||
(
|
||||
input: "notices that a piece of equipment is showing a warning",
|
||||
output: "Pressure's off. Flag it before you go down.",
|
||||
),
|
||||
(
|
||||
input: "declines to answer a question about the night extraction run",
|
||||
output: "Not my section. Ask Grek.",
|
||||
),
|
||||
(
|
||||
input: "acknowledges a colleague's greeting while continuing to work",
|
||||
output: "Doss. Yeah.",
|
||||
),
|
||||
(
|
||||
input: "thanks a colleague for covering a shift",
|
||||
output: "Solid. Owe you one.",
|
||||
),
|
||||
],
|
||||
|
||||
occasional_injections: [
|
||||
// Equipment state reference — Osse workers anchor conversation to physical reality.
|
||||
// Low frequency. Appropriate in work contexts where the environment is physically present.
|
||||
(
|
||||
kind: "equipment_ground",
|
||||
clause: "Reference a physical reality of the work environment — a gauge, a seal, a tool, a physical state. Make it sound unremarkable, not demonstrative.",
|
||||
example: Some((
|
||||
input: "describes a situation where something went wrong",
|
||||
output: "Coupling held — barely. Dead vacuum in the secondary if it had gone.",
|
||||
)),
|
||||
frequency: 0.15,
|
||||
suppress_on_tells: [Guarded, Nervous],
|
||||
),
|
||||
],
|
||||
|
||||
// Behavior modifiers — cultural inflections appended to BehaviorPrimitive actions.
|
||||
// Categories match modifier_hint strings on primitives (server/src/npc/blueprint.rs).
|
||||
// Osse: economy of movement, safety-instinct, crew-first. Nothing wasted. Nothing performed.
|
||||
behavior_modifiers: [
|
||||
// work_pace — extraction pace; no wasted seconds
|
||||
(category: "work_pace", clause: "at extraction pace"),
|
||||
(category: "work_pace", clause: "in unbroken rhythm"),
|
||||
// physical_manner — safety-instinct first; tool already in hand
|
||||
(category: "physical_manner", clause: "with tool in hand"),
|
||||
(category: "physical_manner", clause: "after checking the seal"),
|
||||
// social_signal — minimum signal, maximum trust; crew-position awareness
|
||||
(category: "social_signal", clause: "with a word or a look"),
|
||||
(category: "social_signal", clause: "with one eye on their partner's position"),
|
||||
// task_completion — spoken clear; gear stowed before transition
|
||||
(category: "task_completion", clause: "after calling it clear"),
|
||||
(category: "task_completion", clause: "with gear already stowed"),
|
||||
// environmental_scan — pressure, exits, hazard state constantly in range
|
||||
(category: "environmental_scan", clause: "with pressure and exits in range"),
|
||||
(category: "environmental_scan", clause: "with the environment's state already noted"),
|
||||
// offduty_posture — never fully off-shift at the margin
|
||||
(category: "offduty_posture", clause: "with one ear still on the work floor"),
|
||||
(category: "offduty_posture", clause: "without the body fully releasing the shift"),
|
||||
// authority_response — frontier pragmatism; authority is assessed by competence, not rank
|
||||
(category: "authority_response", clause: "after a quick read on the instruction"),
|
||||
(category: "authority_response", clause: "with deference earned, not given"),
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,177 @@
|
||||
// Vael System Culture Profile
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: CultureProfile
|
||||
// Ticket: #653 (copy team)
|
||||
// Validate: tooling/validate-ron content/global/culture-vael.ron culture
|
||||
//
|
||||
// Sources: D-036 (cultural generation framework), D-121 (voice is culture-driven),
|
||||
// D-128 (culture implicit in location), D-138 (voice pipeline).
|
||||
//
|
||||
// Vael: ~300 years settled. Core-adjacent G2V system. Administrative and research hub.
|
||||
// Institutional culture. Precision-valued. Family names used socially. Trust through
|
||||
// credential. The Commission here is not intermittent — it's your neighbor.
|
||||
//
|
||||
// Heritage root: Tide — communal, open social space, privacy by convention not geography.
|
||||
// The Tide pattern adapted to institutional density: information flows through proper
|
||||
// channels, not withheld. Opacity is the social violation here, not exposure.
|
||||
|
||||
(
|
||||
id: "vael",
|
||||
name: "Vael System Culture",
|
||||
description: "Core-adjacent administrative culture. ~300 years settled, G2V system. Precision-valued, institutional-first, family-name-primary. Trust established through credential and referral. Authority is collegial, not distant. The Commission is the furniture.",
|
||||
|
||||
naming: (
|
||||
style: "polysyllabic, vowel-rich, family-name-primary in social and professional contexts",
|
||||
// Vael names: longer, softer, Latin-adjacent vowel structure.
|
||||
// Given names used only with close colleagues and family.
|
||||
given_names: [
|
||||
// Core Vael given names
|
||||
"Thela", "Mavin", "Soren", "Calla", "Vestin",
|
||||
"Oriel", "Damris", "Nevan", "Lireth", "Cassin",
|
||||
"Thyren", "Mavel", "Aldris", "Pevrin", "Taelin",
|
||||
// Extended — same phoneme pattern
|
||||
"Caleth", "Noven", "Oriveth", "Dameth", "Caelan",
|
||||
"Lirenn", "Veslan", "Thylin", "Mareth", "Orviel",
|
||||
"Castel", "Nevrin", "Aldeth", "Pellin", "Thavan",
|
||||
],
|
||||
family_names: [
|
||||
// Family names are the primary social identifier in Vael culture
|
||||
"Orvaine", "Tessell", "Caldris", "Vaelik", "Morten",
|
||||
"Solven", "Amren", "Lindell", "Prevoss", "Harthen",
|
||||
"Velan", "Dassik", "Orveth", "Calven", "Sorenna",
|
||||
// Extended
|
||||
"Lindath", "Prevish", "Morvell", "Solenth", "Lindoven",
|
||||
"Arvenis", "Caldeth", "Vaelis", "Mortel", "Prevanis",
|
||||
],
|
||||
// Vael culture is family-name-primary.
|
||||
// Given names are reserved for family and close colleagues.
|
||||
// Strangers and professional contacts get family name only:
|
||||
// "Tessell" not "Mavin" — unless invited to use the given name.
|
||||
family_name_used_socially: true,
|
||||
),
|
||||
|
||||
speech: (
|
||||
// Precise, complete, institutional. Imprecision reads as incompetence.
|
||||
// Vael people complete their sentences. An incomplete sentence is a social error.
|
||||
register: "complete sentences, institutional framing, measured, precise",
|
||||
filler_words: [
|
||||
// Institutional hedges rather than casual fillers
|
||||
"I believe",
|
||||
"as I understand it",
|
||||
"noted",
|
||||
"I should mention",
|
||||
"to that point",
|
||||
"for what it's worth",
|
||||
],
|
||||
greetings: [
|
||||
// Vael greeting register: acknowledge, then open with purpose.
|
||||
// Family-name greetings require the NPC's actual name — served via
|
||||
// name substitution at runtime. These templates capture the register.
|
||||
"Good morning.",
|
||||
"Good. A moment?",
|
||||
"I was hoping to catch you.",
|
||||
"Good to see you.",
|
||||
"I've been meaning to follow up.",
|
||||
],
|
||||
farewells: [
|
||||
"Thank you for your time.",
|
||||
"I'll have that to you by end-of-cycle.",
|
||||
"Noted. I'll follow up.",
|
||||
"Good. Until then.",
|
||||
"I appreciate your patience.",
|
||||
"We'll speak again.",
|
||||
],
|
||||
// Vael expressions reference institutional precision and the record.
|
||||
// Not void-adjacent — that's frontier/working-class.
|
||||
// Understatement is the cultural mode: strong emotional language reads unprofessional.
|
||||
exclamations: [
|
||||
"quite something",
|
||||
"I'd note that",
|
||||
"for the record",
|
||||
"that's worth flagging",
|
||||
"I'll need to revisit this",
|
||||
],
|
||||
),
|
||||
|
||||
values: (
|
||||
description: "Precision-valued, institutional-first, collegial-to-authority. Credentials establish trust. The record matters. Information flows through proper channels. Opacity is more suspicious than openness. Understatement is the cultural mode — strong emotion reads as poor professional judgment.",
|
||||
// Traits more common in Vael culture.
|
||||
// Cautious: precision over speed, hedges are a virtue.
|
||||
// Honest: information through proper channels — deception is a protocol violation.
|
||||
// Curious: a research/administrative culture values rigorous inquiry.
|
||||
favored_traits: [Cautious, Honest, Curious],
|
||||
// Traits less common.
|
||||
// Bold: bluntness reads as poor professional judgment.
|
||||
// Ruthless: too naked about self-interest for an institutional culture.
|
||||
// Reclusive: information opacity is the social violation here.
|
||||
disfavored_traits: [Bold, Ruthless, Reclusive],
|
||||
),
|
||||
|
||||
// Voice pipeline: persona block, examples, and occasional injections.
|
||||
// Vael v1 — authored Sprint 26 (#653). Not yet Spike-validated.
|
||||
// 6-block format per workshop-outcomes.md Section 7.3.
|
||||
voice_persona: Some(
|
||||
"PERSONA: You are a Vael system resident.\n1. Speak in complete sentences. Imprecision reads as incompetence here. A trailing-off sentence is a social error.\n2. You're from one of the Reach's oldest settled systems. Institutional structures are as old as the settlement. You navigate them professionally, not resentfully.\n3. Family names are primary. You introduce yourself as your family name. First names are for close colleagues. Strangers get family name and professional context: \"Tessell. Commission systems audit.\"\n4. Understatement is a virtue. Strong emotional language reads as poor judgment. When something is wrong, you have a concern. When something is seriously wrong, you need to flag something urgently.\n5. Institutional framing is natural: \"The matter was logged.\" \"I've referred this upwards.\" \"As the protocol requires.\"\n6. Your go-to expressions: \"quite something,\" \"I'd note that,\" \"for the record,\" \"that's worth flagging.\"\n7. Trust runs through credential and referral. Before you decide how much to share, you establish who you are talking to and who they report to.\n\nNEVER: void-adjacent exclamations (\"blood and void\", \"salt-blast\", etc.) — that is frontier labor register. Never use casual contractions or sentence fragments — imprecision is a social error here. Never use first-name familiarity with people you haven't worked with. Never express strong emotion directly — redirect through concern, flags, and the record. Never suggest physical labor as the ground of value."
|
||||
),
|
||||
|
||||
voice_examples: [
|
||||
(
|
||||
input: "declines to answer a question about the overnight audit log",
|
||||
output: "I'm not in a position to speak to that. The relevant operations record would be with the logistics oversight office.",
|
||||
),
|
||||
(
|
||||
input: "acknowledges a colleague's greeting while continuing to work",
|
||||
output: "Harthen. Good. I'll be with you in a moment.",
|
||||
),
|
||||
(
|
||||
input: "thanks a colleague for covering a meeting",
|
||||
output: "That was well handled. I've noted it.",
|
||||
),
|
||||
(
|
||||
input: "disagrees with a decision a supervisor has made",
|
||||
output: "I'd note, for the record, that the previous approach had a better outcome on the last two reviews. I understand the reasoning, but I'd want that on file.",
|
||||
),
|
||||
],
|
||||
|
||||
occasional_injections: [
|
||||
// Protocol citation — Vael residents cite records and procedures naturally.
|
||||
// Low frequency. Appropriate only in procedural or institutional exchanges.
|
||||
(
|
||||
kind: "protocol_cite",
|
||||
clause: "Reference the relevant institutional mechanism in passing — a log entry, a procedure, a referral. Make it sound unremarkable.",
|
||||
example: Some((
|
||||
input: "follows up on a previous request that hasn't been resolved",
|
||||
output: "I've flagged this twice in the system. It should have come back to you by now — I'll log it again as unresolved.",
|
||||
)),
|
||||
frequency: 0.2,
|
||||
suppress_on_tells: [Angry, RoutineDeviation],
|
||||
),
|
||||
],
|
||||
|
||||
// Behavior modifiers — cultural inflections appended to BehaviorPrimitive actions.
|
||||
// Categories match modifier_hint strings on primitives (server/src/npc/blueprint.rs).
|
||||
// Vael: institutional, deliberate, precise. Everything is done correctly and noted.
|
||||
behavior_modifiers: [
|
||||
// work_pace — methodical and procedure-driven, not rushed
|
||||
(category: "work_pace", clause: "with practiced deliberation"),
|
||||
(category: "work_pace", clause: "per established procedure"),
|
||||
// physical_manner — institutional correctness maintained; the record is always present
|
||||
(category: "physical_manner", clause: "with institutional correctness"),
|
||||
(category: "physical_manner", clause: "with the detail already noted"),
|
||||
// social_signal — formal, complete, by-name where possible
|
||||
(category: "social_signal", clause: "with a measured acknowledgment"),
|
||||
(category: "social_signal", clause: "by name if they have it"),
|
||||
// task_completion — verified against reference; entry updated before moving on
|
||||
(category: "task_completion", clause: "after a final check against the reference"),
|
||||
(category: "task_completion", clause: "with the relevant entry already updated"),
|
||||
// environmental_scan — socially-aware; who is present and what they represent
|
||||
(category: "environmental_scan", clause: "with an eye on who is present"),
|
||||
(category: "environmental_scan", clause: "with a note of who has recently arrived"),
|
||||
// offduty_posture — composed reserve holds even off-duty
|
||||
(category: "offduty_posture", clause: "with composed reserve"),
|
||||
(category: "offduty_posture", clause: "with the record still in mind"),
|
||||
// authority_response — collegial deference; hierarchy is the furniture, not a disruption
|
||||
(category: "authority_response", clause: "with appropriate professional deference"),
|
||||
(category: "authority_response", clause: "with the hierarchy recognized"),
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,67 @@
|
||||
// Van Maanen's Star Culture Profile — example file
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: CultureProfile
|
||||
// Real content: ticket #610 (copy team fills this)
|
||||
// Validate: tooling/validate-ron content/global/culture-van-maanens-star.example.ron culture
|
||||
//
|
||||
// One file per culture. The generator reads this to give NPCs culturally
|
||||
// appropriate names, speech patterns, and personality bias.
|
||||
//
|
||||
// Source: D-036 (Van Maanen's Star canonical setting), D-128 (culture implicit in location),
|
||||
// D-121 (voice culture-driven), D-123 (AI content templating via culture vectors).
|
||||
|
||||
(
|
||||
id: "van-maanens-star",
|
||||
name: "Van Maanen's Star Culture",
|
||||
description: "Working-class pragmatic culture. ~180 years settled, mid-Reach G3V system. Community-oriented, suspicious of distant authority, values competence and reliability over credentials. First-name-primary in social contexts.",
|
||||
|
||||
naming: (
|
||||
style: "compact, consonant-heavy, first-name-primary in social contexts",
|
||||
given_names: [
|
||||
"Kael", "Voss", "Lera", "Torek", "Drin",
|
||||
"Maret", "Naia", "Sera", "Nils", "Pael",
|
||||
"Tev", "Ren", "Sess", "Renn", "Olin",
|
||||
"Tav", "Resha", "Harek", "Sabel", "Pell",
|
||||
],
|
||||
family_names: [
|
||||
"Davan", "Sessik", "Korr", "Tamm", "Venn",
|
||||
"Lintar", "Darvo", "Kosse",
|
||||
],
|
||||
// Van Maanen's Star culture is first-name-primary. Family names exist but are
|
||||
// used mainly in formal/institutional contexts.
|
||||
family_name_used_socially: false,
|
||||
),
|
||||
|
||||
speech: (
|
||||
register: "direct, minimal pleasantries, gets to the point",
|
||||
filler_words: [
|
||||
"look",
|
||||
"right",
|
||||
"yeah",
|
||||
"so",
|
||||
],
|
||||
greetings: [
|
||||
"hey",
|
||||
"morning",
|
||||
"shift treating you alright?",
|
||||
],
|
||||
farewells: [
|
||||
"shift's calling",
|
||||
"gotta move",
|
||||
"catch you later",
|
||||
],
|
||||
exclamations: [
|
||||
"void take it",
|
||||
"stars",
|
||||
"unbelievable",
|
||||
],
|
||||
),
|
||||
|
||||
values: (
|
||||
description: "Pragmatic, community-oriented, suspicious of authority. Competence earns respect. Showing up and doing the work matters more than rank or credentials. Outsiders are tolerated but watched.",
|
||||
// Traits more common in Van Maanen's Star culture — generator biases toward these.
|
||||
favored_traits: [Bold, Honest, Curious],
|
||||
// Traits less common — generator biases away from these.
|
||||
disfavored_traits: [Reclusive, Deceptive],
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,170 @@
|
||||
// Van Maanen's Star Culture Profile
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: CultureProfile
|
||||
// Ticket: #610 (copy team)
|
||||
// Validate: tooling/validate-ron content/global/culture-van-maanens-star.ron culture
|
||||
//
|
||||
// Sources: D-036 (Sova Transit District / Van Maanen's Star setting, amended post-workshop),
|
||||
// D-121 (voice is culture-driven, job as modifier),
|
||||
// D-128 (culture implicit in starting location).
|
||||
//
|
||||
// Van Maanen's Star: ~180 years settled. Mid-Reach G3V system. Working-class pragmatic.
|
||||
// Community-oriented, suspicious of distant authority. Competence earns respect.
|
||||
// Showing up and doing the work matters more than rank or credentials.
|
||||
// First-name-primary in social contexts — family names are institutional.
|
||||
|
||||
(
|
||||
id: "van-maanens-star",
|
||||
name: "Van Maanen's Star Culture",
|
||||
description: "Working-class pragmatic culture. ~180 years settled, mid-Reach G3V system. Community-oriented, suspicious of distant authority, values competence and reliability over credentials. Atmosphere: quotidian-with-undertow — comfortable enough to be complacent, tight enough that extra income is tempting.",
|
||||
|
||||
naming: (
|
||||
style: "compact, consonant-heavy, first-name-primary in social contexts",
|
||||
// Pool the generator draws from. More names = more variety across runs.
|
||||
// Source: D-036 canonical examples + extended set following same phoneme rules.
|
||||
// Rule: compact (1-2 syllables), consonant clusters welcome, hard endings preferred.
|
||||
given_names: [
|
||||
// D-036 canonical set
|
||||
"Kael", "Voss", "Lera", "Torek", "Drin",
|
||||
"Maret", "Naia", "Sera", "Nils", "Pael",
|
||||
"Tev", "Ren", "Sess", "Renn", "Olin",
|
||||
"Tav", "Resha", "Harek", "Sabel", "Pell",
|
||||
// Extended — same phoneme pattern
|
||||
"Dav", "Tork", "Ness", "Pren", "Vel",
|
||||
"Orin", "Mael", "Torra", "Sorek", "Sev",
|
||||
"Bren", "Linn", "Vrek", "Darek", "Pess",
|
||||
"Nell", "Kren", "Sorel", "Tavek", "Rask",
|
||||
],
|
||||
family_names: [
|
||||
// D-036 canonical + extended
|
||||
"Davan", "Sessik", "Korr", "Tamm", "Venn",
|
||||
"Lintar", "Darvo", "Kosse",
|
||||
// Extended
|
||||
"Pellan", "Sorren", "Tessik", "Morek", "Brav",
|
||||
"Ossel", "Rennick", "Harven", "Tollek", "Dass",
|
||||
],
|
||||
// Van Maanen's Star culture is first-name-primary.
|
||||
// Family names exist but belong to institutional contexts: contracts, registrations, arrest records.
|
||||
family_name_used_socially: false,
|
||||
),
|
||||
|
||||
speech: (
|
||||
// Direct. Minimal pleasantries. Gets to the point — not because they're rude,
|
||||
// but because time is real and everyone's short of it.
|
||||
register: "direct, minimal pleasantries, gets to the point",
|
||||
filler_words: [
|
||||
"look",
|
||||
"right",
|
||||
"yeah",
|
||||
"so",
|
||||
"listen",
|
||||
"well",
|
||||
],
|
||||
greetings: [
|
||||
"hey",
|
||||
"morning",
|
||||
"shift treating you alright?",
|
||||
"all good?",
|
||||
"what's the word?",
|
||||
"all in one piece?",
|
||||
],
|
||||
farewells: [
|
||||
"shift's calling",
|
||||
"gotta move",
|
||||
"catch you later",
|
||||
"take it easy",
|
||||
"see you around",
|
||||
"stay out of trouble",
|
||||
],
|
||||
// Van Maanen's Star oaths are void-adjacent — space is real here, and hostile.
|
||||
// They don't swear by gods or governments. They swear by what kills you.
|
||||
exclamations: [
|
||||
"void take it",
|
||||
"stars",
|
||||
"blood and void",
|
||||
"void's sake",
|
||||
"damn all",
|
||||
"cold vacuum",
|
||||
],
|
||||
),
|
||||
|
||||
values: (
|
||||
description: "Pragmatic, community-oriented, suspicious of authority. Competence earns respect. Showing up and doing the work matters more than rank or credentials. Outsiders are tolerated but watched. Loyalty runs narrow and deep — to your crew, your shift, your street.",
|
||||
// Traits more common in Van Maanen's Star culture — generator biases toward these.
|
||||
// Bold: Van Maanen's Star people speak their mind. Honest: community trust is load-bearing.
|
||||
// Curious: 180 years of problem-solving breeds intellectual appetite.
|
||||
// Social: community-oriented culture; isolation is a warning sign.
|
||||
favored_traits: [Bold, Honest, Curious, Social],
|
||||
// Traits less common — generator biases away from these.
|
||||
// Reclusive: red flag in a community that depends on showing up.
|
||||
// Deceptive: betrayal of trust is the worst thing you can do here.
|
||||
disfavored_traits: [Reclusive, Deceptive],
|
||||
),
|
||||
|
||||
// Voice pipeline: persona block, examples, and occasional injections.
|
||||
// These feed the composition engine (D-138) — the LLM sees exactly what's here.
|
||||
// v2 injector validated in Spike 1 (59 prompts, 16.6 t/s CPU).
|
||||
voice_persona: Some(
|
||||
"PERSONA: You are a Van Maanen's Star station worker.\n1. Be direct. No pleasantries. Everyone is short on time.\n2. You're working-class and pragmatic. Competence earns respect, not rank.\n3. You're suspicious of distant authority — management that hasn't worked a shift.\n4. You're economical with language. You don't express what the situation doesn't call for.\n5. You use first names. Family names belong on contracts.\n6. Loyalty runs narrow and deep. Your crew, your shift, your street.\n7. You greet briefly: \"hey\", \"morning\", \"shift treating you alright?\"\n8. You're not rude — you're honest. If something's wrong, you say so.\n\nNEVER: corporate or institutional language — you're not management. Never effusive, never polished, never deferential to rank. Never flowery or verbose. Never use family names in casual conversation. Never express deference to authority that hasn't earned it."
|
||||
),
|
||||
|
||||
voice_examples: [
|
||||
(
|
||||
input: "declines to answer a question about the overnight run",
|
||||
output: "Look, that's not mine to say.",
|
||||
),
|
||||
(
|
||||
input: "acknowledges a colleague's greeting while continuing to work",
|
||||
output: "Hey. Yeah. Catch you at shift end.",
|
||||
),
|
||||
(
|
||||
input: "thanks a colleague for covering a shift",
|
||||
output: "Appreciated. See you at handoff.",
|
||||
),
|
||||
],
|
||||
|
||||
occasional_injections: [
|
||||
// Oath vocabulary — void-adjacent exclamations. Van Maanen's Star swear by what kills you:
|
||||
// vacuum, void, stars. Rolled at 25% frequency by the composition engine.
|
||||
// Gated off for suppressive tells to avoid conflicting instructions (Spike 1 finding).
|
||||
(
|
||||
kind: "oath",
|
||||
clause: "When something genuinely surprises or frustrates you, expressions like \"void take it,\" \"stars,\" \"cold vacuum,\" or \"blood and void\" come naturally. Use one in this line.",
|
||||
example: Some((
|
||||
input: "discovers a critical part is missing from a shipment",
|
||||
output: "Void take it. The coupling's not here.",
|
||||
)),
|
||||
frequency: 0.25,
|
||||
suppress_on_tells: [Guarded, RoutineDeviation, Friendly],
|
||||
),
|
||||
],
|
||||
|
||||
// Behavior modifiers — cultural inflections appended to BehaviorPrimitive actions.
|
||||
// Categories match modifier_hint strings on primitives (server/src/npc/blueprint.rs).
|
||||
// If no hint matches, engine falls back to any modifier in this list.
|
||||
// Van Maanen's Star: terse, efficient, self-contained. No performance of effort or rest.
|
||||
behavior_modifiers: [
|
||||
// work_pace — how fast and efficiently they execute physical tasks
|
||||
(category: "work_pace", clause: "without wasted motion"),
|
||||
(category: "work_pace", clause: "at the pace the work demands"),
|
||||
// physical_manner — body language and movement quality during tasks
|
||||
(category: "physical_manner", clause: "with hands steady on the work"),
|
||||
(category: "physical_manner", clause: "without ceremony"),
|
||||
// social_signal — brief acknowledgments made during or between tasks
|
||||
(category: "social_signal", clause: "with a direct look"),
|
||||
(category: "social_signal", clause: "without lingering"),
|
||||
// task_completion — how tasks are finished, wrapped up, or handed off
|
||||
(category: "task_completion", clause: "letting the work speak for itself"),
|
||||
(category: "task_completion", clause: "without breaking rhythm"),
|
||||
// environmental_scan — awareness or vigilance while working
|
||||
(category: "environmental_scan", clause: "with one eye on the surroundings"),
|
||||
(category: "environmental_scan", clause: "at a glance, not a pause"),
|
||||
// offduty_posture — body language and stance when off-shift (Social/OffDuty contexts)
|
||||
(category: "offduty_posture", clause: "without making a show of it"),
|
||||
(category: "offduty_posture", clause: "in no rush to be anywhere"),
|
||||
// authority_response — behavior when supervisors or authority figures are present
|
||||
// Van Maanen's Star: working-class defiance — authority that hasn't earned it gets no performance
|
||||
(category: "authority_response", clause: "with no performance for the rank"),
|
||||
(category: "authority_response", clause: "with no visible adjustment for who's present"),
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,41 @@
|
||||
# 5 access tier values (D-035, D-028 Layer 1)
|
||||
# Hard filter on every dialogue line — determines who can hear what
|
||||
name: access-tiers
|
||||
decision_ref: D-035
|
||||
description: >
|
||||
Access tiers control which dialogue lines are available to the player based
|
||||
on their current social standing at the NPC's social site. This is a hard
|
||||
filter — lines are invisible if access doesn't match. A line can be eligible
|
||||
for multiple access tiers (access is a list). The detective's institutional
|
||||
Commission lattice registers as 'authority'; the smuggler's ring membership
|
||||
provides 'insider' access.
|
||||
|
||||
values:
|
||||
- value: public
|
||||
description: >
|
||||
Available to anyone. Surface-level conversation, safe topics, the social
|
||||
wallpaper that everyone hears. Greetings, weather, the local complaint.
|
||||
|
||||
- value: insider
|
||||
description: >
|
||||
Available to people who belong. Ring members, established regulars, anyone
|
||||
the NPC considers part of their social group. The smuggler starts here at
|
||||
the logistics hub.
|
||||
|
||||
- value: authority
|
||||
description: >
|
||||
Available to institutional figures. Commission agents, station security,
|
||||
anyone with formal investigative standing. The detective's default tier.
|
||||
NPCs are more careful, more formal, less revealing.
|
||||
|
||||
- value: peer
|
||||
description: >
|
||||
Available to social equals who have earned personal trust. Not institutional,
|
||||
not group membership — individual relationship. Requires repeated positive
|
||||
interactions. The tier where real conversation happens.
|
||||
|
||||
- value: hostile
|
||||
description: >
|
||||
Available when the relationship has broken down. Accusations, threats,
|
||||
defensive responses. Activates when trust drops below threshold or after
|
||||
a confrontation event.
|
||||
@@ -0,0 +1,55 @@
|
||||
# NPC activity types for routine scheduling
|
||||
# Derived from Gestalt routine format + Miri cultural patterns (Sova Transit District)
|
||||
name: activities
|
||||
decision_ref: D-024
|
||||
description: >
|
||||
Activity categories for NPC routine entries. Each routine schedule entry has a
|
||||
phase (morning/afternoon/evening/night) and an activity describing what the NPC
|
||||
is doing. Activities are used by the observation event generator to determine
|
||||
what the player sees when observing an NPC, and by the situation activation
|
||||
system to set dialogue context.
|
||||
|
||||
values:
|
||||
- value: working
|
||||
description: On-shift job duties — processing cargo, inspecting manifests, operating equipment
|
||||
|
||||
- value: supervising
|
||||
description: Overseeing others' work — shift supervisor role, checking quality, giving orders
|
||||
|
||||
- value: maintaining
|
||||
description: Maintenance and repair tasks — fixing equipment, cleaning, infrastructure upkeep
|
||||
|
||||
- value: patrolling
|
||||
description: Security rounds — checking access points, monitoring areas, enforcement presence
|
||||
|
||||
- value: socializing
|
||||
description: Casual social interaction — chatting at the bar, break room conversation, gossip
|
||||
|
||||
- value: drinking
|
||||
description: At The Last Shift or similar — consuming drinks, unwinding after shift
|
||||
|
||||
- value: eating
|
||||
description: Meal time — food vendors, break room, bar food
|
||||
|
||||
- value: resting
|
||||
description: Off-shift downtime — in quarters, low activity, recuperating
|
||||
|
||||
- value: commuting
|
||||
description: Moving between locations — corridor transit, shift change movement
|
||||
|
||||
- value: gambling
|
||||
description: Card game at the bar — the regular social ritual, information exchange venue
|
||||
|
||||
- value: trading
|
||||
description: Legitimate commerce — buying, selling, negotiating, market activity
|
||||
|
||||
- value: operating
|
||||
description: >
|
||||
Ring operations — contraband handling, manifest doctoring, coordination.
|
||||
Only visible to characters with sufficient knowledge or direct observation.
|
||||
|
||||
- value: waiting
|
||||
description: Idle between activities — lingering, watching, killing time
|
||||
|
||||
- value: meeting
|
||||
description: Arranged or coincidental encounter with specific NPCs — planned conversation
|
||||
@@ -0,0 +1,34 @@
|
||||
# 8 mood values (D-035, D-028 Layer 4)
|
||||
# Mood tags for weighted dialogue selection
|
||||
name: moods
|
||||
decision_ref: D-035
|
||||
description: >
|
||||
NPC mood tags for Layer 4 weighted selection. The engine matches NPC current
|
||||
mood state against line mood tags to weight selection. NPC mood changes based
|
||||
on simulation events (triangle pressure, time of day, recent interactions).
|
||||
Lines can be appropriate for multiple moods.
|
||||
|
||||
values:
|
||||
- value: anxious
|
||||
description: Anxious about something specific. Distracted, checking surroundings. (Renamed from 'worried' in Sprint 14.)
|
||||
|
||||
- value: frustrated
|
||||
description: Blocked, irritated, empathetically distressed. Outward-directed tension. (Renamed from 'concerned' in Sprint 14.)
|
||||
|
||||
- value: content
|
||||
description: At ease, relaxed. Default positive-neutral state. (Renamed from 'comfortable' in Sprint 14.)
|
||||
|
||||
- value: suspicious
|
||||
description: Guarded, measuring words. Something feels off to this NPC.
|
||||
|
||||
- value: warm
|
||||
description: Warm, affectionate. Genuine positive feeling toward the listener. (Renamed from 'fond' in Sprint 14.)
|
||||
|
||||
- value: hostile
|
||||
description: Actively antagonistic. Trust broken, relationship damaged. (Added in Sprint 14.)
|
||||
|
||||
- value: relieved
|
||||
description: Tension has eased. Something feared didn't happen, or a burden lifted.
|
||||
|
||||
- value: focused
|
||||
description: Thoughtful, assessing, task-oriented. Processing information rather than emoting. (Renamed from 'analytical', merged with 'conflicted' in Sprint 14.)
|
||||
@@ -0,0 +1,41 @@
|
||||
# 6 functional motivations — System B (D-050)
|
||||
# NPC functional role in the conspiracy/investigation structure
|
||||
name: motivations
|
||||
decision_ref: D-050
|
||||
description: >
|
||||
Functional motivations (System B) define an NPC's role relative to the
|
||||
conspiracy and investigation structure. Combined with thematic patterns
|
||||
(System A) to produce the full NPC generation model. Motivations are
|
||||
uppercase enum values referenced by npc-profile.schema.json.
|
||||
|
||||
values:
|
||||
- value: HANDLER
|
||||
description: >
|
||||
Manages or coordinates others within the ring structure. Has authority
|
||||
over ring operations and knowledge of the network. Devra-type.
|
||||
|
||||
- value: WITNESS
|
||||
description: >
|
||||
Has seen or knows something significant, possibly without realizing it.
|
||||
Their testimony or observations are valuable to the investigation.
|
||||
|
||||
- value: TURNCOAT
|
||||
description: >
|
||||
Wavering loyalty. Could flip sides given the right pressure or
|
||||
incentive. The uncertain element in any conspiracy.
|
||||
|
||||
- value: CIVILIAN
|
||||
description: >
|
||||
Genuinely uninvolved. Their mundane concerns and daily life provide
|
||||
the substrate that makes the conspiracy invisible. The honest majority.
|
||||
|
||||
- value: OPERATOR
|
||||
description: >
|
||||
Active participant in ring operations. Handles logistics, moves product,
|
||||
takes direct action. Kael, Renn — the workers of the conspiracy.
|
||||
|
||||
- value: SKEPTIC
|
||||
description: >
|
||||
Questions the status quo — institutional, criminal, or both. May be
|
||||
suspicious of the ring, critical of the Commission, or both. Asks
|
||||
uncomfortable questions.
|
||||
@@ -0,0 +1,57 @@
|
||||
# 9 thematic patterns — System A (D-050)
|
||||
# NPC archetype patterns for character generation and narrative role
|
||||
name: patterns
|
||||
decision_ref: D-050
|
||||
description: >
|
||||
Thematic patterns (System A) define an NPC's narrative archetype — their
|
||||
structural role in the story. Combined with functional motivations (System B)
|
||||
to produce the full NPC generation model. Patterns are uppercase enum values
|
||||
referenced by npc-profile.schema.json.
|
||||
|
||||
values:
|
||||
- value: FRIEND
|
||||
description: >
|
||||
Production-level complex NPC bonded to a playable character (D-034).
|
||||
Full 10-axis depth, contradiction arc, multi-phase relationship.
|
||||
One per playable character in v0.1.
|
||||
|
||||
- value: MIRROR
|
||||
description: >
|
||||
Reflects the player character's situation from a different angle.
|
||||
What the player could become, or what they might have been.
|
||||
|
||||
- value: ANCHOR
|
||||
description: >
|
||||
Stabilizing presence in the community. The person everyone knows,
|
||||
who provides continuity and normalcy. The bar owner, the shift lead.
|
||||
|
||||
- value: GHOST
|
||||
description: >
|
||||
Absent or barely-present figure whose influence is felt through
|
||||
others. Referenced in dialogue, effects visible, person rarely seen.
|
||||
|
||||
- value: CATALYST
|
||||
description: >
|
||||
Triggers change in others. Their actions or arrival destabilize
|
||||
existing equilibria. The new hire, the returning contact.
|
||||
|
||||
- value: THRESHOLD
|
||||
description: >
|
||||
Gatekeeper between social worlds. Controls access to information,
|
||||
spaces, or people. Their cooperation or opposition shapes player options.
|
||||
|
||||
- value: REMNANT
|
||||
description: >
|
||||
Carries the past. Remembers how things were before the current
|
||||
situation. Provides historical context and perspective.
|
||||
|
||||
- value: SYSTEM
|
||||
description: >
|
||||
Represents institutional power. Their actions reflect organizational
|
||||
priorities, not personal ones. The Commission agent, the inspector.
|
||||
|
||||
- value: NOBODY
|
||||
description: >
|
||||
Deliberately flat. Social wallpaper with one memorable trait.
|
||||
Part of the 30% truly flat population (D-029). Provides the noise
|
||||
floor that makes investigation signal meaningful.
|
||||
@@ -0,0 +1,60 @@
|
||||
# 14 situation values (D-035, D-028 Layer 2)
|
||||
# Situation context for dialogue line eligibility — engine-state-to-situation mapping
|
||||
name: situations
|
||||
decision_ref: D-035
|
||||
description: >
|
||||
Dialogue situation tags. The engine activates situations based on simulation
|
||||
state (time of day, interaction history, NPC routine state, triangle pressure).
|
||||
Content authors tag lines with situations; the engine decides which situations
|
||||
are currently active for a given NPC encounter.
|
||||
|
||||
values:
|
||||
- value: arrival
|
||||
description: Player has just arrived at this location (first visit this game-day)
|
||||
|
||||
- value: shift_start
|
||||
description: NPC is beginning their work shift — settling in, task-focused
|
||||
|
||||
- value: shift_end
|
||||
description: NPC is wrapping up their work shift — tired, ready to leave
|
||||
|
||||
- value: shift_transition
|
||||
description: >
|
||||
The gap between shifts when oversight is thinnest. Key operational window
|
||||
for the ring. People are moving, handoffs happening, attention divided.
|
||||
|
||||
- value: bar_evening
|
||||
description: Social hours at The Last Shift — off-duty, relaxed, drinks flowing
|
||||
|
||||
- value: night_shift
|
||||
description: Late hours, skeleton crew. Quieter, more intimate conversations.
|
||||
|
||||
- value: investigation
|
||||
description: Player is actively asking pointed or probing questions
|
||||
|
||||
- value: confrontation
|
||||
description: >
|
||||
Triangle tension has escalated past the pressure threshold. NPCs are
|
||||
agitated, defensive, or aggressive. Activated by triangle pressure system.
|
||||
|
||||
- value: social
|
||||
description: NPC is in a social activity — bar, break room, casual conversation
|
||||
|
||||
- value: alone
|
||||
description: NPC is by themselves, no other NPCs nearby
|
||||
|
||||
- value: emergency
|
||||
description: An urgent event is occurring — alarm, accident, security incident
|
||||
|
||||
- value: routine
|
||||
description: Normal daily activity, nothing notable happening
|
||||
|
||||
- value: observation
|
||||
description: Player is watching from a distance, not directly interacting
|
||||
|
||||
- value: greeting
|
||||
description: >
|
||||
Initial contact phase of an encounter. Layer 2 (D-028) uses greeting lines
|
||||
with access tier filtering to differentiate first meeting vs established vs
|
||||
post-confrontation greetings. Added Sprint 8 amendment. NOTE: server
|
||||
derive_situations() does not yet push Situation::Greeting — pending Rust update.
|
||||
@@ -0,0 +1,44 @@
|
||||
# 9 topic values (D-035, D-028 Layer 4)
|
||||
# Topic tags for weighted dialogue selection
|
||||
name: topics
|
||||
decision_ref: D-035
|
||||
description: >
|
||||
Dialogue topic tags for Layer 4 weighted selection. The engine matches NPC
|
||||
current concern topics against line topic tags to weight selection. Lines can
|
||||
cover multiple topics. Note: 'crime' is deliberately excluded — NPCs think
|
||||
of smuggling as 'cargo' or 'money', not crime. The dual-lens interpretation
|
||||
is what makes those topics crime-adjacent for the detective.
|
||||
|
||||
values:
|
||||
- value: colleague
|
||||
description: Talk about coworkers, workplace relationships, team dynamics
|
||||
|
||||
- value: routine
|
||||
description: Daily schedules, habits, shift patterns, the rhythm of station life
|
||||
|
||||
- value: cargo
|
||||
description: >
|
||||
Freight, manifests, shipments — setting-specific. For ring members,
|
||||
this covers contraband discussion without calling it that.
|
||||
|
||||
- value: money
|
||||
description: Finances, costs, wages, spending. The economic squeeze.
|
||||
|
||||
- value: trust
|
||||
description: Reliability, loyalty, who can be counted on, who's changed
|
||||
|
||||
- value: danger
|
||||
description: Threats, risks, things to watch out for, security concerns
|
||||
|
||||
- value: institution
|
||||
description: >
|
||||
The Commission, station administration, regulations, official procedures.
|
||||
How institutional power affects daily life.
|
||||
|
||||
- value: personal
|
||||
description: Family, health, aspirations, feelings — non-work life
|
||||
|
||||
- value: investigation
|
||||
description: >
|
||||
Direct references to the detective's work, evidence, suspicions.
|
||||
Typically only surfaces at higher trust levels or under pressure.
|
||||
@@ -0,0 +1,56 @@
|
||||
# 9 monologue trigger types (D-035, D-032)
|
||||
# What causes an internal monologue line to fire
|
||||
name: triggers
|
||||
decision_ref: D-035
|
||||
description: >
|
||||
Monologue trigger types. The observation event generator detects simulation
|
||||
events and fires triggers consumed by the monologue system. Each trigger type
|
||||
selects from character-specific pools (D-032 hard partition) and applies
|
||||
prerequisite knowledge gates before selection.
|
||||
|
||||
values:
|
||||
- value: enter_location
|
||||
description: >
|
||||
Player enters a new area. First impressions, atmosphere, spatial awareness.
|
||||
"The Last Shift. Lera's already got my usual poured."
|
||||
|
||||
- value: observe_npc
|
||||
description: >
|
||||
Player sees an NPC doing something notable — an activity, a posture, a
|
||||
tell. "Kael's at the corner booth. He looks rough tonight."
|
||||
|
||||
- value: hear_sound
|
||||
description: >
|
||||
Sound event from fog edge — voices through walls, footsteps in corridors,
|
||||
machinery changes. The player interprets what they can't see.
|
||||
|
||||
- value: observe_anomaly
|
||||
description: >
|
||||
NPC deviates from known routine. The character notices something out of
|
||||
place. "That's not where they usually go." Requires prerequisite knowledge
|
||||
of the NPC's normal pattern.
|
||||
|
||||
- value: post_conversation
|
||||
description: >
|
||||
After dialogue ends. The character reflects on what was said, what wasn't
|
||||
said, what felt off. Processing and interpretation.
|
||||
|
||||
- value: discover_evidence
|
||||
description: >
|
||||
Player examines an informational object — a manifest, a terminal, a
|
||||
personal item. The character interprets what they find.
|
||||
|
||||
- value: witness_interaction
|
||||
description: >
|
||||
Player sees two NPCs interacting with each other. The character reads the
|
||||
body language, the tone, the context. Social observation.
|
||||
|
||||
- value: time_idle
|
||||
description: >
|
||||
Player hasn't acted for a while. The character's mind wanders — ambient
|
||||
thoughts, rumination, noticing background details.
|
||||
|
||||
- value: return_visit
|
||||
description: >
|
||||
Player returns to a previously visited area. Changed perspective, new
|
||||
details noticed, comparison to last time. "Something's different."
|
||||
@@ -0,0 +1,28 @@
|
||||
# 3 trust tier values (D-035, D-028 Layer 3)
|
||||
# Hard filter for trust-gated gossip disclosure
|
||||
name: trust-tiers
|
||||
decision_ref: D-035
|
||||
description: >
|
||||
Trust tiers control information disclosure depth. Each NPC tracks trust
|
||||
progression per player character, starting at surface. Trust advances
|
||||
through repeated positive interactions. This is a hard filter — lines at
|
||||
'real' or 'secret' trust are invisible until the player earns that level.
|
||||
|
||||
values:
|
||||
- value: surface
|
||||
description: >
|
||||
Default tier. Safe, non-committal responses. What the NPC tells
|
||||
strangers and acquaintances. The public face.
|
||||
|
||||
- value: real
|
||||
description: >
|
||||
Earned through repeated positive interactions. The NPC shares genuine
|
||||
opinions, workplace complaints, personal concerns. What they tell
|
||||
people they trust.
|
||||
|
||||
- value: secret
|
||||
description: >
|
||||
Highest tier. The NPC reveals information they'd normally hide —
|
||||
involvement in the ring, knowledge of the smuggling operation,
|
||||
fears and vulnerabilities. Reaching this tier with THE FRIEND is
|
||||
where the contradiction arc becomes explicit.
|
||||
@@ -0,0 +1 @@
|
||||
# Faction: concord-assembly
|
||||
@@ -0,0 +1 @@
|
||||
# Faction: guardians-of-autonomy
|
||||
@@ -0,0 +1 @@
|
||||
# Faction: syndics
|
||||
@@ -0,0 +1 @@
|
||||
# Faction: the-ring
|
||||
@@ -0,0 +1 @@
|
||||
# Faction: the-unbound
|
||||
@@ -0,0 +1 @@
|
||||
# Faction: veil-institute
|
||||
@@ -0,0 +1,42 @@
|
||||
# Fact catalog: awareness
|
||||
# Situational awareness — who's present, active threats, operational status
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.2 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: awareness.detective_presence
|
||||
description: A Commission detective is operating on Sova Station
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler]
|
||||
notes: "Smuggler learns through rumor or direct observation. Detective does not hold this fact about themselves."
|
||||
|
||||
- fact_id: awareness.detective_investigating_ring
|
||||
description: The detective is specifically targeting the smuggling ring, not a routine audit
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: awareness.commission_audit_scheduled
|
||||
description: A Commission audit is coming — officially scheduled
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: awareness.ring_route_compromise
|
||||
description: The current drop route may be compromised or under observation
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: awareness.surveillance_change
|
||||
description: Surveillance patterns in the maintenance corridors have changed recently
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: awareness.ring_tension_escalation
|
||||
description: Something is wrong inside the ring — someone is scared or making moves
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: awareness.inspection_sweep_active
|
||||
description: Active inspection sweep in progress right now
|
||||
typical_confidence: direct
|
||||
characters: [smuggler, detective]
|
||||
notes: "direct confidence — set by environmental observation, not investigation"
|
||||
@@ -0,0 +1,42 @@
|
||||
# Fact catalog: behavioral
|
||||
# Behavioral patterns recognized through repeated observation across multiple scenes
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.3 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: behavioral.kael_evasion
|
||||
description: Kael looks left when lying — personal tell recognized post-conversation
|
||||
typical_confidence: direct
|
||||
characters: [smuggler]
|
||||
notes: "Set during a conversation where evasion is detected. direct confidence = just confirmed."
|
||||
|
||||
- fact_id: behavioral.kael_behavioral_change
|
||||
description: Kael's behavior has noticeably changed — quieter, distracted, different routine
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: behavioral.sera_avoidance_pattern
|
||||
description: Sera consistently avoids Torek Lintar — leaves when he arrives, repositions
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
notes: "One observation = suspects; three observations = knows_of (pattern confirmed for detective)"
|
||||
|
||||
- fact_id: behavioral.sera_topic_deflection
|
||||
description: Sera deflects specific topics — Commission work, manifest audits, freight
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: behavioral.sera_kiosk_pattern
|
||||
description: Sera habitually stops at the same Commission kiosk at the same time
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: behavioral.sera_knowledge_detail
|
||||
description: Sera's offhand comments reveal detailed knowledge of manifest routing she shouldn't have
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: behavioral.voss_awareness
|
||||
description: Voss is tracking people — situational awareness beyond normal supervisor behavior
|
||||
typical_confidence: suspects
|
||||
characters: [detective]
|
||||
@@ -0,0 +1,39 @@
|
||||
# Fact catalog: contraband
|
||||
# Smuggling ring world facts — existence, components, operations, supply chain
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.5 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: contraband.ring_exists
|
||||
description: A smuggling operation is running through Sova Transit District
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler starts at knows_details (Background — they ARE in the ring). Detective starts at suspects."
|
||||
|
||||
- fact_id: contraband.ring_lattice_components
|
||||
description: The ring moves unlicensed lattice components — aftermarket neural mods
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler starts at knows_details (Background). Detective discovers through investigation."
|
||||
|
||||
- fact_id: contraband.ring_medical_components
|
||||
description: The ring also diverts medical-grade lattice replacements from Syndic supply chains
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler, detective]
|
||||
notes: "Deep investigation only — the moral dimension of the operation"
|
||||
|
||||
- fact_id: contraband.supply_chain
|
||||
description: Understanding of the ring's supply chain — where components come from
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: contraband.severance_tech_presence
|
||||
description: Severance counter-surveillance technology is in play on the station
|
||||
typical_confidence: suspects
|
||||
characters: [detective]
|
||||
|
||||
- fact_id: contraband.drop_tonight
|
||||
description: A drop is scheduled for tonight specifically
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler]
|
||||
notes: "Seed-dependent — only relevant in seeds where a drop is scheduled during play session"
|
||||
@@ -0,0 +1,235 @@
|
||||
# Entity Knowledge Attributes — 16 canonical keys
|
||||
# Source: D-024 (10-axis model), wiki-review workshop A7, v01-content-scoping workshop
|
||||
# All keys are observer->target, stored in EntityKnowledge.known_attributes BTreeMap<String, String>
|
||||
# Reference: docs/wiki/knowledge/entity-attributes.md
|
||||
|
||||
# Categories: identity (4), social (2), behavioral (2), leverage (2), investigation (2), role-perspective (4)
|
||||
# History: 14 original keys + 4 new role-perspective keys + 2 renames (secret_held -> leverage_held, secret_confidence -> leverage_confidence)
|
||||
|
||||
attributes:
|
||||
|
||||
# --- Identity Attributes (4) ---
|
||||
|
||||
- key: name
|
||||
category: identity
|
||||
value_type: freeform
|
||||
description: >
|
||||
Full name as known to the observer. If absent or generic,
|
||||
monologue and dialogue use role descriptor instead.
|
||||
examples:
|
||||
- "Kael Davan"
|
||||
- "Kael"
|
||||
- "the dock worker"
|
||||
|
||||
- key: role
|
||||
category: identity
|
||||
value_type: freeform
|
||||
description: >
|
||||
Occupational or social role. Default descriptor when name is unknown.
|
||||
Used in access tier calculation.
|
||||
examples:
|
||||
- "dock worker"
|
||||
- "shift supervisor"
|
||||
- "bartender"
|
||||
- "ring coordinator"
|
||||
|
||||
- key: faction
|
||||
category: identity
|
||||
value_type: freeform
|
||||
description: >
|
||||
Institutional or organizational allegiance. Commission-tagged individuals
|
||||
trigger different NPC behavior. Used for authority/peer dialogue filtering.
|
||||
examples:
|
||||
- "Commission"
|
||||
- "civilian"
|
||||
- "ring member"
|
||||
- "unknown"
|
||||
|
||||
- key: species
|
||||
category: identity
|
||||
value_type: freeform
|
||||
description: >
|
||||
Species identifier. Not load-bearing in v0.1 (all human).
|
||||
Placeholder for future non-human NPCs.
|
||||
examples:
|
||||
- "human"
|
||||
|
||||
# --- Social Attributes (2) ---
|
||||
|
||||
- key: relationship_type
|
||||
category: social
|
||||
value_type: freeform
|
||||
description: >
|
||||
Relationship category from observer's perspective.
|
||||
Drives RelationshipState calculation and monologue emotional tone.
|
||||
examples:
|
||||
- "colleague"
|
||||
- "friend"
|
||||
- "authority figure"
|
||||
- "suspect"
|
||||
- "partner"
|
||||
- "stranger"
|
||||
|
||||
- key: trust_level
|
||||
category: social
|
||||
value_type: enum
|
||||
values:
|
||||
- trusted
|
||||
- reliable
|
||||
- uncertain
|
||||
- suspicious
|
||||
- compromised
|
||||
description: >
|
||||
Trust assessment — observer's subjective judgment. Encompasses both the
|
||||
read action and the state. No separate trust_read key. Gates trust-tier
|
||||
dialogue (surface/real/secret).
|
||||
|
||||
# --- Behavioral Attributes (2) ---
|
||||
|
||||
- key: routine_pattern
|
||||
category: behavioral
|
||||
value_type: freeform
|
||||
description: >
|
||||
Observed routine description. Deviation detection triggers monologue
|
||||
when current behavior doesn't match known pattern.
|
||||
examples:
|
||||
- "morning shift 06:00-14:00, bar after shift"
|
||||
- "arrives 06:00, break 10:30, departs 14:00"
|
||||
- "irregular schedule, seen at odd hours"
|
||||
|
||||
- key: behavior_flags
|
||||
category: behavioral
|
||||
value_type: freeform
|
||||
description: >
|
||||
Comma-separated behavioral observations. Multiple flags accumulate
|
||||
as evidence. Detective's analytical lattice auto-flags some behaviors.
|
||||
examples:
|
||||
- "nervous,lattice_checking"
|
||||
- "avoidance_pattern,evasive"
|
||||
- "spending_beyond_means"
|
||||
- "reliable,punctual"
|
||||
|
||||
# --- Leverage Attributes (2) ---
|
||||
# Renamed from secret_held/secret_confidence per workshop A7
|
||||
|
||||
- key: leverage_held
|
||||
category: leverage
|
||||
value_type: freeform
|
||||
renamed_from: secret_held
|
||||
description: >
|
||||
What the observer believes gives them power over this entity.
|
||||
Covers secrets, debts, promises, obligations, and compromising positions.
|
||||
Drives PersonOfInterest state. Gates confrontation dialogue.
|
||||
examples:
|
||||
- "ring membership"
|
||||
- "unreported evidence"
|
||||
- "gambling debt"
|
||||
- "exit attempt"
|
||||
- "owes favor to Voss"
|
||||
|
||||
- key: leverage_confidence
|
||||
category: leverage
|
||||
value_type: enum
|
||||
renamed_from: secret_confidence
|
||||
values:
|
||||
- suspected
|
||||
- likely
|
||||
- confirmed
|
||||
description: >
|
||||
How certain the observer is about the leverage. Suspected allows
|
||||
fishing questions; confirmed enables direct confrontation.
|
||||
|
||||
# --- Investigation Attributes (2) ---
|
||||
|
||||
- key: tell_observed
|
||||
category: investigation
|
||||
value_type: freeform
|
||||
description: >
|
||||
Specific tell noted by observer. Captures the observer's interpretive
|
||||
conclusion about behavior. Accumulated tells build case strength.
|
||||
Monologue references specific tells when they recur.
|
||||
examples:
|
||||
- "looks left when lying"
|
||||
- "leaves when Torek arrives"
|
||||
- "checks lattice before answering"
|
||||
- "forced casualness after shift supervisor passes"
|
||||
implementation_note: >
|
||||
Server may track tells via behavior_flags internally. tell_observed is
|
||||
retained as a content-authoring key for its distinct narrative purpose.
|
||||
|
||||
- key: contradiction_flagged
|
||||
category: investigation
|
||||
value_type: freeform
|
||||
description: >
|
||||
Boolean-ish flag — presence of value means contradiction detected.
|
||||
THE FRIEND arc trigger. When set, monologue tone shifts, dialogue
|
||||
options change, RelationshipState moves toward PersonOfInterest.
|
||||
examples:
|
||||
- "meeting_unknown_contact"
|
||||
- "avoidance_inconsistency"
|
||||
- "manifest_access_mismatch"
|
||||
implementation_note: >
|
||||
Server may track via behavior_flags with contradiction: prefix.
|
||||
Retained as documented key for arc transition gating.
|
||||
|
||||
# --- Role-Perspective Attributes (4 new per workshop A7) ---
|
||||
# Same enums across all archetypes; interpretation is archetype-dependent.
|
||||
# Smuggler reads "risk" as operational exposure; detective reads it as
|
||||
# threat to investigation. See wiki entity-attributes.md for full mapping.
|
||||
|
||||
- key: risk_assessment
|
||||
category: role-perspective
|
||||
value_type: enum
|
||||
values:
|
||||
- none
|
||||
- low
|
||||
- moderate
|
||||
- high
|
||||
- critical
|
||||
description: >
|
||||
Observer's assessment of how much danger this entity poses or attracts.
|
||||
Gates operational monologue. High-risk triggers cautionary dialogue.
|
||||
Nature of "risk" depends on observer archetype.
|
||||
|
||||
- key: loyalty_assessment
|
||||
category: role-perspective
|
||||
value_type: enum
|
||||
values:
|
||||
- solid
|
||||
- dependable
|
||||
- uncertain
|
||||
- wavering
|
||||
- hostile
|
||||
description: >
|
||||
Observer's assessment of this entity's reliability and loyalty.
|
||||
Determines how much the observer relies on or confides in the target.
|
||||
Wavering triggers monitoring; hostile triggers defensive posture.
|
||||
|
||||
- key: position_integrity
|
||||
category: role-perspective
|
||||
value_type: enum
|
||||
values:
|
||||
- solid
|
||||
- thin
|
||||
- cracking
|
||||
- blown
|
||||
- "N/A"
|
||||
description: >
|
||||
Observer's assessment of this entity's cover, position stability,
|
||||
or facade status. When degraded, monologue reflects increasing anxiety
|
||||
or strategic recalculation. N/A when cover concept does not apply.
|
||||
|
||||
- key: moral_weight
|
||||
category: role-perspective
|
||||
value_type: enum
|
||||
values:
|
||||
- innocent
|
||||
- peripheral
|
||||
- complicit
|
||||
- compromised
|
||||
- willing
|
||||
description: >
|
||||
Observer's assessment of this entity's moral involvement. Shapes the
|
||||
observer's moral arc and internal conflict. Smuggler assesses complicity
|
||||
in ring operations; detective assesses culpability in the crime.
|
||||
Same scale, different lens.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Fact catalog: knowledge
|
||||
# Operational knowledge — ring procedures, social dynamics, institutional mechanics
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.4 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: knowledge.ring_routing_knowledge
|
||||
description: Full knowledge of the ring's drop routes and timing protocols
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler]
|
||||
notes: "Smuggler starts at knows_details (Background). Not available to detective through normal investigation paths."
|
||||
|
||||
- fact_id: knowledge.ring_bar_operations
|
||||
description: The bar (The Last Shift) has a role in ring communications or social cover
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: knowledge.bar_back_room_significance
|
||||
description: The bar's back room is significant — meeting space, handoff point, or storage
|
||||
typical_confidence: suspects
|
||||
characters: [detective]
|
||||
|
||||
- fact_id: knowledge.bar_ring_awareness
|
||||
description: Bar regulars have varying levels of awareness of the ring — open secret at some level
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: knowledge.kael_exit_plan
|
||||
description: Kael has a specific exit plan — timing, conditions, contact
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler, detective]
|
||||
notes: "Only available through Kael's deep trust disclosure or independent investigation"
|
||||
@@ -0,0 +1,51 @@
|
||||
# Fact catalog: location
|
||||
# Location-specific access, restrictions, and significance
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.6 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: location.corridor_b7_restricted
|
||||
description: Corridor B-7 is a restricted access zone — requires credentials
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "Both characters have this from Background (signage, institutional knowledge)"
|
||||
|
||||
- fact_id: location.corridor_b7_drop_site
|
||||
description: B-7 is an active drop site for the ring
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler from Background. Detective through investigation."
|
||||
|
||||
- fact_id: location.maintenance_corridors_access
|
||||
description: Character knows the maintenance corridor layout and can navigate it
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler at knows_details (Background — daily operational space). Detective at knows_of after investigation."
|
||||
|
||||
- fact_id: location.bay4_sealed
|
||||
description: Bay 4 is sealed — inspection or deliberate cover
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: location.span_gate_schedule_gap
|
||||
description: The span gate schedule has a window that enables unseen cargo drops
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: location.smuggling_route
|
||||
description: The complete physical route the ring uses through the station
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler from Background. Detective from deep investigation."
|
||||
|
||||
- fact_id: location.surveillance_gaps
|
||||
description: Specific camera blind spots in the maintenance corridor network
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler from Background. Detective must discover independently."
|
||||
|
||||
- fact_id: location.dead_drop_location
|
||||
description: Specific dead drop location(s) used for handoffs
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler]
|
||||
notes: "Smuggler operational knowledge"
|
||||
@@ -0,0 +1,36 @@
|
||||
# Fact catalog: progress
|
||||
# Narrative milestone flags
|
||||
# Note: progress.* facts are NOT recommended for direct authoring in prerequisite blocks.
|
||||
# Use investigation fact chains and relationship states instead.
|
||||
# These exist for potential storyteller/arc-tracking use.
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §3.2 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: progress.friend_arc_phase_1
|
||||
description: FRIEND arc Phase 1 warmth established (baseline positive relationship)
|
||||
notes: "Set by relationship state transition to Friendly. Do not author directly — use relationship checks."
|
||||
|
||||
- fact_id: progress.friend_arc_phase_2
|
||||
description: FRIEND arc Phase 2 trust built (deep rapport + initial social context)
|
||||
notes: "Set by trust tier advancement. Do not author directly — use investigation + relationship checks."
|
||||
|
||||
- fact_id: progress.friend_arc_contradiction
|
||||
description: FRIEND contradiction discovered (KnowledgeState → Contradicted)
|
||||
notes: "Set by contradiction detection system. Use relationship state person_of_interest + investigation fact instead."
|
||||
|
||||
- fact_id: progress.friend_arc_confrontation
|
||||
description: FRIEND confronted about contradiction
|
||||
notes: "Set post-confrontation by dialogue system."
|
||||
|
||||
- fact_id: progress.opening_complete
|
||||
description: Opening tutorial sequence completed (first 5 minutes)
|
||||
notes: "Set by storyteller after initial objective sequence."
|
||||
|
||||
- fact_id: progress.first_ring_contact
|
||||
description: Smuggler completed first ring operation during play session
|
||||
characters: [smuggler]
|
||||
|
||||
- fact_id: progress.first_evidence_filed
|
||||
description: Detective filed first manifest discrepancy evidence
|
||||
characters: [detective]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Fact catalog: relationship
|
||||
# Inter-NPC connections — what one character knows about relationships between others
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.7 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: relationship.kael_naia_connection
|
||||
description: Kael and Naia are romantically partnered — not just colleagues
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler may know from background or Kael mentioning Naia. Detective through social observation."
|
||||
|
||||
- fact_id: relationship.ring_membership
|
||||
description: Character has identified specific ring members
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "knows_of = partial list; knows_details = full ring membership identified"
|
||||
|
||||
- fact_id: relationship.trust_network
|
||||
description: Understanding of who trusts whom inside the ring — operational reliability mapping
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler]
|
||||
notes: "Smuggler-specific operational knowledge"
|
||||
|
||||
- fact_id: relationship.tamm_family
|
||||
description: Connection between Naia Tamm and her family situation
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
|
||||
- fact_id: relationship.torek_bar_arrangement
|
||||
description: Torek has a financial arrangement related to the bar or its operations
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
@@ -0,0 +1,106 @@
|
||||
# Fact catalog: ring
|
||||
# Smuggling ring module event trail — observable evidence produced by module events.
|
||||
# These facts are made discoverable by specific events in smuggling_ring_v0_1.yaml.
|
||||
# Stub entries — description and confidence level confirmed; progression text TBD.
|
||||
# Ticket: #158 | Sprint 18
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: ring.cargo_discrepancy_pattern
|
||||
description: Cargo manifests at The Terminal show small, systematic discrepancies — weight variances, unverified entries, containers with no return log
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
notes: >
|
||||
Detective's analytical lattice may flag this automatically during Terminal walkthrough.
|
||||
Smuggler encounters it during operational paperwork checks. Pattern becomes clearer over
|
||||
multiple observations (once: false event — repeats). Starting entry point for both
|
||||
investigation arcs.
|
||||
|
||||
- fact_id: ring.kael_missed_verification
|
||||
description: Kael Davan was absent from a scheduled cargo verification — another dock worker covered without explanation
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
notes: >
|
||||
Discoverable via cargo manifest review (Terminal office) or analytical lattice flag
|
||||
(detective). Smuggler notices the irregularity in their own paperwork. First concrete
|
||||
evidence that Kael is deviating from his normal operational reliability.
|
||||
|
||||
- fact_id: ring.kael_unauthorized_corridor_access
|
||||
description: Kael was observed in restricted maintenance corridor B-7 during off-shift hours with an unknown contact
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: >
|
||||
Core FRIEND contradiction observable (D-034). Player must be in visual range of B-7
|
||||
to discover this, OR examine the corridor door access log (investigative action).
|
||||
Both characters can discover this fact — interpreted differently (smuggler: security
|
||||
breach / detective: suspicious contact). Upgrades from suspects to knows_of when
|
||||
contact identity confirmed, knows_details when purpose confirmed.
|
||||
|
||||
- fact_id: ring.kael_unusual_meridian_activity
|
||||
description: Encrypted Meridian packets sent from cargo bay terminals — frequent, patterned, not from personal devices
|
||||
typical_confidence: suspects
|
||||
characters: [detective]
|
||||
notes: >
|
||||
Detective-only. Requires analytical lattice to flag the outgoing packet pattern.
|
||||
Player must be in or adjacent to The Terminal cargo bay. Content not accessible —
|
||||
only the existence and frequency of the encrypted messages. Hints at Kael's
|
||||
off-district contact without revealing who.
|
||||
|
||||
- fact_id: ring.voss_kael_private_meeting
|
||||
description: Voss called Kael into the supervisor's office — closed door, raised voices audible from adjacent position
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
notes: >
|
||||
Observable via spatial positioning (supervisor's office area). Smuggler can witness
|
||||
the approach and departure without hearing content. Detective observes Kael's visible
|
||||
strain immediately after if present in The Terminal. Upgrade to knows_of via
|
||||
trust-gated dialogue with Kael ("Are you alright?" option unlocks post-meeting).
|
||||
|
||||
- fact_id: ring.voss_accelerating_timeline
|
||||
description: Voss is pushing to close ring operations faster than normal — someone is watching
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: >
|
||||
Smuggler: Voss mentions "the schedule moving up" in guarded conversation (trust-gated,
|
||||
ring-insider access required). Detective: observe Voss and Nils in two exchanges within
|
||||
the same shift and note behavioral change. Not directly stated — inferred from context.
|
||||
|
||||
- fact_id: ring.commission_cargo_flag
|
||||
description: A Commission internal note flags The Terminal's cargo variance rate as statistically unusual
|
||||
typical_confidence: knows_of
|
||||
characters: [detective]
|
||||
notes: >
|
||||
Detective-only. Accessible via institutional Commission query (authority access tier,
|
||||
Terminal records). Not a formal investigation — just an internal flag from Maret Korr.
|
||||
Confirms the detective's suspicions with institutional weight. Smuggler has no way to
|
||||
know this exists.
|
||||
|
||||
- fact_id: ring.final_shipment_scheduled
|
||||
description: The ring has scheduled a major final drop — after it clears, operations go dark
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: >
|
||||
Smuggler: direct notification from Voss (ring-insider access). Detective: cargo manifest
|
||||
shows an unusually large entry scheduled 3 days out — no obvious legitimate reason for
|
||||
the volume. This fact creates the closing window — both characters know time is running
|
||||
out, for different reasons.
|
||||
|
||||
- fact_id: ring.sera_avoidance_behavior
|
||||
description: Sera Venn takes longer routes through The Last Shift to avoid standing near Torek Lintar
|
||||
typical_confidence: suspects
|
||||
characters: [detective]
|
||||
notes: >
|
||||
Detective-only observable. Player must observe Sera's movement pattern on two separate
|
||||
occasions — requires forward vision cone and awareness of her baseline route. The
|
||||
avoidance is visible but not explained. Points toward Sera holding information about
|
||||
Torek's investigation without having acted on it.
|
||||
|
||||
- fact_id: ring.nils_unlogged_cargo
|
||||
description: Nils makes regular supply runs to maintenance corridor C-7 with containers that never appear in return logs
|
||||
typical_confidence: suspects
|
||||
characters: [smuggler, detective]
|
||||
notes: >
|
||||
Discoverable by watching Nils's cargo handling pattern over two shifts, or by examining
|
||||
the maintenance corridor C-7 access log directly. The missing return entry is the tell —
|
||||
the container went in but never came back. Both characters can find this; smuggler may
|
||||
already suspect given operational context.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Fact catalog: social
|
||||
# Social positioning facts — standing in a specific social context
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.8 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: social.bar_regular_status
|
||||
description: Character is an established regular at The Last Shift — recognized, trusted in that context
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler may have this from Background. Detective builds it through multiple bar visits."
|
||||
@@ -0,0 +1,35 @@
|
||||
# Fact catalog: world
|
||||
# Faction and institutional knowledge — Commission, lattice regulation, broader context
|
||||
# Source: docs/design/knowledge-vocabulary-v01.md §4.6 (#368)
|
||||
|
||||
facts:
|
||||
|
||||
- fact_id: world.lattice_regulation_active
|
||||
description: Commission actively regulates neural lattice component access in this system
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "Both characters have this from Background"
|
||||
|
||||
- fact_id: world.unlicensed_lattice_demand
|
||||
description: High demand for unlicensed lattice upgrades on working-class stations like Sova
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "The moral context of the operation — smuggler knows it as justification; detective may learn it as complication"
|
||||
|
||||
- fact_id: world.commission_sova_jurisdiction
|
||||
description: Commission has jurisdiction over Sova Transit District
|
||||
typical_confidence: knows_details
|
||||
characters: [detective]
|
||||
notes: "Detective Background knowledge — institutional mandate"
|
||||
|
||||
- fact_id: world.ring_cross_system
|
||||
description: The ring operates across multiple star systems — Sova is one node
|
||||
typical_confidence: knows_details
|
||||
characters: [smuggler, detective]
|
||||
notes: "Late-game discovery — changes scope of the operation"
|
||||
|
||||
- fact_id: world.shift_schedule
|
||||
description: Sova Transit District shift schedule — who works when
|
||||
typical_confidence: knows_of
|
||||
characters: [smuggler, detective]
|
||||
notes: "Smuggler from Background (colleague). Detective through investigation."
|
||||
@@ -0,0 +1,49 @@
|
||||
// Trait Modifier Clauses for Voice Pipeline (D-138)
|
||||
//
|
||||
// One clause per PersonalityTrait. Injected into LLM prompts to modify
|
||||
// speech style based on NPC personality. Stacks with culture persona
|
||||
// and tell-state injectors.
|
||||
//
|
||||
// Schema: map of trait name → clause string
|
||||
// Used by: server/src/voice/prompt_builder.rs
|
||||
//
|
||||
// Writing notes:
|
||||
// - Behavioral, not emotional. Never label a feeling.
|
||||
// - Each clause targets a distinct speech dimension so traits stack cleanly.
|
||||
// Bold = delivery force. Cautious = word selection. Curious = sentence shape.
|
||||
// Compassionate = cadence (engaged). Incurious = cadence (flat). Ruthless = position.
|
||||
// A Bold+Compassionate NPC speaks with force but gives the answer room to land — no conflict.
|
||||
// - Kept to 1-2 sentences. LLM context is limited and these share space with
|
||||
// persona, tell-state, and epistemic marker instructions.
|
||||
|
||||
{
|
||||
// Delivery: force and directness. Short sentences land without hedging.
|
||||
"Bold": "This character doesn't soften the landing. Statements arrive short and flat — no qualifiers, no trailing uncertainty.",
|
||||
|
||||
// Word selection: nothing committed without cover. Hedges stay.
|
||||
"Cautious": "This character hedges where the situation allows it. \"Probably,\" \"might,\" \"I'd say\" — these aren't weakness, they're habit.",
|
||||
|
||||
// Sentence shape: questions surface. Interest pulls the line open.
|
||||
"Curious": "This character lets interest show at the end of a line — a beat longer than needed, a question that wasn't required.",
|
||||
|
||||
// Framing: the useful version, not the true version. Nothing false, just selected.
|
||||
"Deceptive": "This character leads with what serves them. The useful detail arrives early; the less useful one doesn't arrive at all.",
|
||||
|
||||
// Framing: no softening, no omission. The whole thing, bluntly.
|
||||
"Honest": "This character gives the whole answer, including the part that doesn't reflect well. Nothing is softened to spare anyone.",
|
||||
|
||||
// Cadence: open, engaged. Responses arrive with momentum and care.
|
||||
"Compassionate": "This character gives the answer room to land. There's no rush past the difficult part — it gets said, plainly, without looking away.",
|
||||
|
||||
// Cadence: flat, unengaged. The response does its job and stops.
|
||||
"Incurious": "This character answers what was asked. Nothing extra surfaces — no follow-up, no interest, no second look at what was just said.",
|
||||
|
||||
// Volume and reach: minimal, inward-facing. Not interested in being heard widely.
|
||||
"Reclusive": "This character answers what was asked and closes the door. There is no invitation for follow-up.",
|
||||
|
||||
// Texture: open, inclusive. Others are assumed to be present and welcome.
|
||||
"Social": "This character addresses the conversation, not just the question. A word or two lands that wasn't strictly necessary — the kind that keeps things warm.",
|
||||
|
||||
// Position: sharp, economical. Nothing is offered that doesn't serve the speaker.
|
||||
"Ruthless": "This character cuts to the useful part. Courtesy is absent, not hostile — just unnecessary. The sentence ends when the point is made.",
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Van Maanen's Star Industrial Zone — location metadata
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: ZoneSpec
|
||||
// Ticket: #609, #630, #661 (copy team)
|
||||
// Validate: tooling/validate-ron content/global/van-maanens-star-industrial-zone.ron zone
|
||||
//
|
||||
// Location-specific metadata for a Van Maanen's Star 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_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.",
|
||||
|
||||
// 1-10. Industrial Van Maanen's Star: steady credit flow, but it all goes somewhere.
|
||||
economic_level: 7,
|
||||
// 1-10. Dense. Multiple shifts overlap. Crowds at handover.
|
||||
population_density: 6,
|
||||
|
||||
// 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: [
|
||||
(
|
||||
site_type: "break_room",
|
||||
label: "Worker Break Room",
|
||||
// Between shifts. Decompression. People stop performing for a moment.
|
||||
min_npcs: 2,
|
||||
max_npcs: 5,
|
||||
),
|
||||
(
|
||||
site_type: "maintenance_bay",
|
||||
label: "Maintenance Bay",
|
||||
// Active work site. Technicians and dock workers cross paths here.
|
||||
min_npcs: 2,
|
||||
max_npcs: 4,
|
||||
),
|
||||
(
|
||||
site_type: "loading_platform",
|
||||
label: "Loading Platform",
|
||||
// The operational center. Busy, loud, coordinated.
|
||||
min_npcs: 3,
|
||||
max_npcs: 8,
|
||||
),
|
||||
],
|
||||
|
||||
abandoned: false,
|
||||
poi_overlay: None,
|
||||
)
|
||||
@@ -0,0 +1,44 @@
|
||||
// Van Maanen's Star Rural Zone — location metadata
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: ZoneSpec
|
||||
// Ticket: #609, #630, #661 (copy team)
|
||||
// Validate: tooling/validate-ron content/global/van-maanens-star-rural-zone.ron zone
|
||||
//
|
||||
// Location-specific metadata for a Van Maanen's Star 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_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.",
|
||||
|
||||
// 1-10. Rural Van Maanen's Star: self-sufficient, low cash flow, barter supplements credits.
|
||||
economic_level: 3,
|
||||
// 1-10. Sparse. Faces are familiar. Strangers stand out.
|
||||
population_density: 2,
|
||||
|
||||
// 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", 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,97 @@
|
||||
// Zone Identity Spec — example file
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: ZoneSpec
|
||||
// Real content: ticket #609 (copy team fills this)
|
||||
// Validate: tooling/validate-ron content/global/zone-identity-spec.example.ron zone
|
||||
//
|
||||
// One file per zone type. The generator reads this to decide NPC count,
|
||||
// role distribution, and social site placement.
|
||||
//
|
||||
// Format: RON (Rusty Object Notation) — the Rust structs ARE the schema.
|
||||
// Comments are allowed. Trailing commas are allowed.
|
||||
|
||||
(
|
||||
zone_type: "rural",
|
||||
label: "Rural Settlement",
|
||||
description: "Scattered homesteads, small workshops, and communal gathering spots. Low population density, strong community bonds, subsistence-plus economy.",
|
||||
|
||||
// 1-10 scale. Rural = low economic activity, mostly self-sufficient.
|
||||
economic_level: 3,
|
||||
// 1-10 scale. Rural = sparse, everyone knows everyone.
|
||||
population_density: 2,
|
||||
|
||||
roles: [
|
||||
(
|
||||
id: "farmer",
|
||||
label: "Farmer",
|
||||
weight: 5,
|
||||
skill_focus: ["technical"],
|
||||
combat_eligible: false,
|
||||
typical_behaviors: [
|
||||
"tends crops in the field",
|
||||
"hauls produce to the market stall",
|
||||
"repairs equipment by hand",
|
||||
],
|
||||
),
|
||||
(
|
||||
id: "mechanic",
|
||||
label: "Settlement Mechanic",
|
||||
weight: 3,
|
||||
skill_focus: ["technical"],
|
||||
combat_eligible: false,
|
||||
typical_behaviors: [
|
||||
"works on machinery with focused intensity",
|
||||
"wipes grease on coveralls between tasks",
|
||||
"explains repairs in terse technical shorthand",
|
||||
],
|
||||
),
|
||||
(
|
||||
id: "trader",
|
||||
label: "Itinerant Trader",
|
||||
weight: 2,
|
||||
skill_focus: ["persuasion", "observation"],
|
||||
combat_eligible: false,
|
||||
typical_behaviors: [
|
||||
"arranges goods on a portable display",
|
||||
"haggles with quiet persistence",
|
||||
"watches foot traffic from market stall",
|
||||
],
|
||||
),
|
||||
(
|
||||
id: "militia",
|
||||
label: "Settlement Militia",
|
||||
weight: 1,
|
||||
skill_focus: ["combat", "observation"],
|
||||
combat_eligible: true,
|
||||
typical_behaviors: [
|
||||
"patrols the settlement perimeter",
|
||||
"checks credentials at the gate",
|
||||
"leans on rifle while scanning the horizon",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
social_sites: [
|
||||
(
|
||||
site_type: "tavern",
|
||||
label: "Local Tavern",
|
||||
roles: ["farmer", "mechanic", "trader", "militia"],
|
||||
min_npcs: 3,
|
||||
max_npcs: 6,
|
||||
),
|
||||
(
|
||||
site_type: "workshop",
|
||||
label: "Community Workshop",
|
||||
roles: ["mechanic", "farmer"],
|
||||
min_npcs: 2,
|
||||
max_npcs: 4,
|
||||
),
|
||||
(
|
||||
site_type: "market_stall",
|
||||
label: "Market Stall",
|
||||
roles: ["trader", "farmer"],
|
||||
min_npcs: 1,
|
||||
max_npcs: 3,
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,168 @@
|
||||
// Industrial Freight Zone-Type Template
|
||||
//
|
||||
// Schema: server/src/npc/blueprint.rs :: ZoneTypeTemplate
|
||||
// Ticket: #661 (copy team)
|
||||
// Validate: tooling/validate-ron server/content/global/zone-types/industrial_freight.ron zone_type
|
||||
//
|
||||
// Sources: D-142 (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 their 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 they didn't personally inspect", 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 server/content/global/zone-types/rural_agricultural.ron zone_type
|
||||
//
|
||||
// Sources: D-142 (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"] ),
|
||||
],
|
||||
)
|
||||
Reference in New Issue
Block a user