120 lines
6.5 KiB
Markdown
120 lines
6.5 KiB
Markdown
# The Steward — Architecture Overview
|
|
|
|
This project is organized around gameplay ownership, not scene-tree location.
|
|
Serializable simulation records are authoritative; loaded Godot nodes present
|
|
that state and contribute active-world facts such as positions and navigation
|
|
results.
|
|
|
|
## Runtime flow
|
|
|
|
```text
|
|
SimulationClock
|
|
-> SimulationManager orchestrates one deterministic tick
|
|
-> ActionExecutionSystem advances needs and work
|
|
-> ActionSelectionSystem chooses an action
|
|
-> ActionTargetResolver resolves a stable target ID
|
|
-> VillageEconomy performs inventory/storage transactions
|
|
-> SimulationEventLog records completed facts
|
|
-> EventKnowledgeSystem records, ranks, transfers, and retains bounded knowledge
|
|
-> RelationshipSystem applies evidence-gated social consequences
|
|
-> VillageOpportunitySystem projects one known unresolved need
|
|
-> WorldViewManager presents travel, NPC state, and world-state cues
|
|
-> ActiveWorldAdapter supplies loaded-world positions/capacity
|
|
-> NpcVisual performs local navigation, animation, and transient reactions
|
|
-> PantryStockVisual derives physical stock arrangement from storage state
|
|
```
|
|
|
|
`SimulationManager` is the scene-tree façade for the simulation. It owns the
|
|
tick lifecycle, authoritative NPC/village/resource records, reservations, and
|
|
the signals consumed by presentation. Focused collaborators own rules that
|
|
would otherwise obscure that lifecycle:
|
|
|
|
- `simulation/actions/` owns selection, progress, and target resolution;
|
|
- `simulation/economy/VillageEconomy.gd` owns storage/inventory transactions
|
|
and keeps village resource summaries synchronized;
|
|
- `simulation/events/SimulationEventLog.gd` owns ordered event identity,
|
|
history queries, and rate calculations;
|
|
- `simulation/knowledge/EventKnowledgeSystem.gd` owns per-NPC references to
|
|
known objective events, immutable acquisition provenance, proximity witnesses
|
|
at record time, one-hop direct fact transfer, and deterministic recent-fact
|
|
retention/importance ranking;
|
|
- `simulation/relationships/RelationshipSystem.gd` owns directed relationship
|
|
queries, event-driven trust changes, and deterministic social tie-breaking;
|
|
- `simulation/opportunities/VillageOpportunitySystem.gd` observes immutable
|
|
event references plus current NPC/storage state, then owns the bounded shared
|
|
open/resolved/invalidated lifecycle for the proven pantry-food and blocked-
|
|
work wood consumers without changing resources or assigning tasks;
|
|
- `simulation/persistence/` owns save-slot file safety;
|
|
- `simulation/state/` owns versioned serialized record contracts;
|
|
- `simulation/definitions/` owns stable IDs and immutable action/profession
|
|
definitions.
|
|
|
|
The manager deliberately remains a façade instead of being split into a
|
|
collection of scene-tree manager nodes. A new collaborator is justified when
|
|
one cohesive rule set has several real consumers or makes the tick lifecycle
|
|
hard to read.
|
|
|
|
## Folder ownership
|
|
|
|
| Path | Responsibility |
|
|
| --- | --- |
|
|
| `simulation/` | Headless-capable orchestration and core models |
|
|
| `simulation/actions/` | Action decisions, execution, and target queries |
|
|
| `simulation/economy/` | Authoritative inventory and storage transactions |
|
|
| `simulation/events/` | Immutable event history and derived event queries |
|
|
| `simulation/knowledge/` | Per-NPC knowledge of objective event IDs |
|
|
| `simulation/relationships/` | Directed social consequences and relationship queries |
|
|
| `simulation/opportunities/` | Knowledge-gated unresolved-condition projections |
|
|
| `simulation/state/` | Versioned, serializable mutable records |
|
|
| `simulation/definitions/` | Stable IDs and immutable gameplay definitions |
|
|
| `simulation/persistence/` | Validated local save-file storage |
|
|
| `world/` | Loaded-world interaction geometry and presentation adapters |
|
|
| `world/resource_nodes/` | Finite resource presentation bound by stable ID |
|
|
| `world/storage/` | Storage interaction geometry, never stored quantities |
|
|
| `world/activity/` | Rest/study/patrol interaction sites and capacity facts |
|
|
| `player/` | Player input, camera, and active NPC presentation |
|
|
| `tests/` | Deterministic headless gameplay scenarios |
|
|
|
|
Top-level core model scripts keep their stable paths because Godot's global
|
|
class cache records `class_name` locations. Moving them solely for cosmetic
|
|
nesting can break editor and headless startup for existing workspaces without
|
|
improving ownership.
|
|
|
|
## Dependency rules
|
|
|
|
- Simulation code must run without `main.tscn` or loaded world nodes.
|
|
- Persistent references are stable IDs, never `Node`, `NodePath`, or scene
|
|
ownership.
|
|
- Presentation may report facts and submit commands; it does not choose NPC
|
|
actions or own resource, storage, inventory, event, knowledge, relationship,
|
|
opportunity, or reservation state.
|
|
- Inspector history is a read-only façade query over objective events and
|
|
retained knowledge. Opportunity presentation is likewise query-only.
|
|
Relationship cues, interested-villager concern, physical pantry stock, and
|
|
refill feedback consume authoritative state or state-change signals and are
|
|
intentionally absent from saves and checksums. Stable visuals are rebuilt
|
|
from state after restore; transient reactions are not replayed.
|
|
- Resource changes go through `ResourceStateRecord`, NPC inventory, and
|
|
`VillageEconomy`; `village.food` and `village.wood` are synchronized views.
|
|
- New mutable features define serialization and deterministic continuation at
|
|
the same time as their first gameplay use. Cross-record causes use stable
|
|
event IDs rather than object references or prose.
|
|
- Opportunity records reference stable NPC, storage, resource, trigger-event,
|
|
and resolution-event IDs. Their generator may observe authoritative state
|
|
and history, but it does not mutate the economy or command NPC behavior.
|
|
- Prefer one tested vertical behavior over a generic framework with no proven
|
|
consumers.
|
|
|
|
## Where new code goes
|
|
|
|
Put a rule beside the state it governs. A relationship consequence belongs in
|
|
a focused simulation system plus serialized relationship records; its icon or
|
|
animation belongs in presentation. Add a world node only when the behavior
|
|
needs loaded-world geometry. Add a stable ID or definition when content must be
|
|
referenced across saves, scenes, or unloaded simulation.
|
|
|
|
The architectural decision and detailed contracts live in
|
|
[ADR 0001](decisions/0001-simulation-authority-boundary.md),
|
|
[the action system architecture](ACTION_SYSTEM_ARCHITECTURE.md), and
|
|
[the simulation state schema](SIMULATION_STATE_SCHEMA.md).
|