165 lines
7.7 KiB
Markdown
165 lines
7.7 KiB
Markdown
# The Steward — Simulation Definitions
|
|
|
|
## Purpose
|
|
|
|
Stable IDs and immutable definitions form the vocabulary shared by simulation
|
|
state, systems, world adapters, scenes, tests, and save migrations.
|
|
|
|
`SimulationIds` remains the append-only source for code-facing compatibility
|
|
IDs. `SimulationContentPack` is the no-code authoring manifest and
|
|
`ContentCatalog` transactionally validates and publishes typed definitions in
|
|
stable-ID order. The current core pack contains actions, professions,
|
|
capability tags, items, resources, storage policies, and enemies. A failed pack
|
|
publishes nothing: duplicate IDs, unknown references, unsupported handlers, or
|
|
missing presentation cues are authoring errors rather than silent overrides.
|
|
|
|
Simulation code resolves definitions through the catalog. Presentation cue IDs
|
|
remain headless strings and are mapped separately to scenes, materials, icons,
|
|
or animation hooks. Runtime quantities and ownership stay in state records;
|
|
saves do not contain `.tres` paths or copied definition balance.
|
|
|
|
## Content-pack contract
|
|
|
|
Each pack has a stable `pack_id`, display name, explicit pack dependencies,
|
|
required handler IDs, and typed definition arrays. Pack and definition IDs are
|
|
unique across the whole catalog. Packs cannot override each other in the first
|
|
version, and enumeration is sorted independently of resource load order.
|
|
|
|
Adding data-only content is:
|
|
|
|
1. create a typed `.tres` definition;
|
|
2. add it to an explicit pack;
|
|
3. optionally register its stable presentation cue in the presentation layer;
|
|
4. place or spawn an instance with its own canonical runtime ID.
|
|
|
|
Adding a fundamentally new mechanic still requires one bounded reusable
|
|
handler. The pack declares that dependency so missing runtime support fails
|
|
validation rather than becoming a partially functioning object.
|
|
|
|
## Action contract
|
|
|
|
Each executable `ActionDefinition` contains:
|
|
|
|
- stable action ID and display name;
|
|
- duration and optional preferred profession;
|
|
- target family and resource-action metadata;
|
|
- optional completion cost;
|
|
- actor and target capability tags;
|
|
- selection, target, and completion handler IDs;
|
|
- reusable typed effects;
|
|
- event and presentation cue IDs.
|
|
|
|
Reusable `ActionEffect` definitions cover metric/need change, exact inventory
|
|
transfer, damage/healing, relationship-dimension change, scheduling an ordinary
|
|
action, and site-condition change. `ActionCommand` carries stable actor/action/
|
|
target/item IDs, amount, and expected revision; `ActionOffer` and `ActionResult`
|
|
are copy-only values. `ActionCommandService` is the authority boundary and must
|
|
revalidate range, capabilities, reservation, permission, cost, and target state
|
|
at execution time for either a player or NPC caller.
|
|
|
|
The current actions are gather food, gather wood, feed animal, deposit food,
|
|
deposit wood, withdraw food, patrol, study, eat, rest, sleep, wander, and
|
|
defend. Idle and dead are state sentinels, not executable definitions. The
|
|
two-leg animal-feeding transaction remains a custom completion handler because
|
|
it has a real compound pickup/delivery contract and no second shared consumer
|
|
yet.
|
|
|
|
## Items, resources, and storage
|
|
|
|
`ItemDefinition` validates fields by category. Weapons require damage, reach,
|
|
cooldown, and an equip slot; materials and consumables do not carry fake weapon
|
|
fields. The core pack contains food, wood, herb, sword, and claw. Herb proves a
|
|
new non-weapon item and route without a manager branch.
|
|
|
|
`ResourceDefinition` owns yielded item, gather action, capability tags, base
|
|
capacity/yield/regrowth, access policy, and presentation cue. Placement/state
|
|
records retain unique contextual IDs and overrides such as safety risk,
|
|
comfort, and discovery priority. Berry patches, trees, and herb patches share
|
|
this contract.
|
|
|
|
`StorageDefinition` declares accepted item IDs/tags, policy priority, capacity,
|
|
settlement scope, deposit/withdraw actions, and presentation cue.
|
|
`StorageRoutingPolicy` ranks compatible destinations deterministically by
|
|
priority then stable target ID. Food-to-pantry and wood-to-woodpile remain
|
|
covered; herb-to-apothecary proves data-only routing beyond those legacy cases.
|
|
|
|
## Professions and capabilities
|
|
|
|
Each `ProfessionDefinition` contains a stable ID, display name, body color, and
|
|
prop color. Farmer, woodcutter, guard, scholar, and wanderer are registered in
|
|
the core pack. NPC state saves only the ID and rejects unknown definitions.
|
|
|
|
`CapabilityTagDefinition` gives actions and targets a validated shared
|
|
vocabulary. Tags express composable affordances; they do not mutate state or
|
|
replace concrete authority checks.
|
|
|
|
## Enemies and combat
|
|
|
|
`EnemyDefinition` carries a behavior profile, combatant ID prefix, faction,
|
|
hostility, weapon, health, movement, and visual parameters.
|
|
`CombatantFactory` creates/restores every hostile and rebuilds collision-free
|
|
per-prefix allocators. The core boar reuses the wolf-hunt behavior without a
|
|
new manager or combat switch; raider and wolf compatibility spawn APIs delegate
|
|
to the same factory.
|
|
|
|
Combatant and faction state use stable IDs. NPC combatants point to their
|
|
person ID; hostile records persist `enemy_definition_id`. Weapons resolve
|
|
through the same item catalog used by inventory rather than a parallel combat
|
|
item table.
|
|
|
|
## Animals
|
|
|
|
`AnimalDefinition` + `AnimalCatalog` + `AnimalFactory` apply the same
|
|
definition-instance-state-presentation contract to domestic animals. Goat and
|
|
sheep reuse the `grazer_routine`, feeding capability, generic CozyGrazer scene,
|
|
state migration, and care system; definition and visual parameters are the only
|
|
type-specific pieces. The animal catalog remains isolated until the next
|
|
shared content-pack migration adds that record family without destabilizing
|
|
the already validated core pack.
|
|
|
|
## Situations and dialogue
|
|
|
|
Legacy `OpportunityStateRecord` vocabulary remains for save compatibility.
|
|
New emergent content uses typed `SituationDefinition` resources: reusable
|
|
predicates, evidence requirements, dedupe fields, priority/severity,
|
|
alternative objectives, exact ordinary resolution patterns, expiry/cooldown,
|
|
and dialogue topic IDs. Situation state saves the definition ID and causal
|
|
facts; progress is re-derived from authoritative state and `WorldEventStore`.
|
|
|
|
`DialogueIntentDefinition` owns semantic preconditions, score, response intent
|
|
IDs, template variants, and optional action metadata. Stable hashing selects a
|
|
variant from conversation/turn/intent/topics without consuming shared RNG.
|
|
Rendered prose and Dialogue Manager resources are presentation and never
|
|
authoritative state.
|
|
|
|
## Validation and authoring report
|
|
|
|
The catalog rejects:
|
|
|
|
- missing, empty, or duplicate pack/definition IDs;
|
|
- silent cross-pack overrides;
|
|
- unknown pack, handler, capability, item, profession, action, storage,
|
|
behavior-profile, or presentation-cue references;
|
|
- category-invalid item fields;
|
|
- incomplete or non-positive costs/effects;
|
|
- resources or storage routes with inconsistent item/action contracts;
|
|
- definition resources that fail to load.
|
|
|
|
`ContentCatalog.get_authoring_report()` exposes validity, sorted published IDs,
|
|
and exact errors for CLI/editor tooling. Tests prove transactional failure,
|
|
deterministic enumeration, core cross-references, boar behavior reuse, shared
|
|
goat/sheep behavior, and herb routing.
|
|
|
|
## Deliberate boundary
|
|
|
|
Definitions own reusable static metadata, not mutable inventory, reservations,
|
|
relationships, situation progress, entity ownership, or presentation nodes.
|
|
Handler implementations remain bounded typed strategies. A universal
|
|
reflection DSL, arbitrary scripts embedded in saves, and a full ECS are outside
|
|
the contract.
|
|
|
|
Selection, execution, target resolution, simulation authority, and visual
|
|
travel remain separate responsibilities. Extend definitions only after a real
|
|
consumer proves a stable shared field; extend a handler when the mechanic itself
|
|
is genuinely new.
|