142 lines
6.0 KiB
Markdown
142 lines
6.0 KiB
Markdown
# The Steward — Action System Architecture
|
|
|
|
## Current flow
|
|
|
|
```text
|
|
SimulationManager tick
|
|
-> ActionExecutionSystem advances needs and working progress
|
|
-> ActionSelectionSystem chooses an action when the NPC is idle
|
|
-> SimulationManager stores the selected action
|
|
-> npc_target_requested
|
|
-> WorldViewManager supplies the active visual's current position
|
|
-> ActionTargetResolver consumes simulation state + ActiveWorldAdapter facts
|
|
-> SimulationManager stores/reserves the target
|
|
-> npc_travel_requested
|
|
-> WorldViewManager commands NpcVisual travel
|
|
-> arrival/navigation failure returns to SimulationManager
|
|
```
|
|
|
|
## Responsibilities
|
|
|
|
### ActionSelectionSystem
|
|
|
|
- reads NPC and village state;
|
|
- queries `RelationshipSystem` after personal survival/schedule overrides, so a
|
|
trusted starving acquaintance can redirect ordinary work toward food
|
|
gathering while the pantry is low;
|
|
- evaluates current utility scores;
|
|
- consumes the NPC's deterministic decision RNG;
|
|
- returns an action ID, optional urgent-duration override, branch reason,
|
|
compared utility scores, and definition-backed rejection reasons;
|
|
- does not mutate targets, navigation, or visuals.
|
|
|
|
### ActionExecutionSystem
|
|
|
|
- advances hunger, energy, starvation, death, and working progress;
|
|
- marks an action complete when its duration elapses;
|
|
- does not select the next action or resolve a target.
|
|
|
|
### ActionTargetResolver
|
|
|
|
- reads target metadata from ActionDefinition;
|
|
- consumes active-world facts through ActiveWorldAdapter;
|
|
- checks simulation-owned ResourceStateRecord availability;
|
|
- reserves and returns stable resource target IDs;
|
|
- skips full-capacity activity sites based on authoritative NPC target claims;
|
|
- returns typed activity-site, storage, or wander positions without owning
|
|
presentation.
|
|
|
|
### ActiveWorldAdapter
|
|
|
|
- exposes loaded resource interaction positions;
|
|
- exposes loaded storage and activity-site interaction positions;
|
|
- exposes activity-site capacity as an active-world fact;
|
|
- contains active-world query facts, not persistent mutable authority;
|
|
- does not choose actions or reserve resources.
|
|
|
|
### WorldViewManager
|
|
|
|
- spawns and tracks NpcVisual instances;
|
|
- supplies a visual's current position when resolution is requested;
|
|
- applies travel commands;
|
|
- reports arrival, navigation failure, and visual death state;
|
|
- does not map actions, select targets, write target IDs, or mutate resources.
|
|
|
|
### SimulationManager
|
|
|
|
SimulationManager remains the orchestrator and event boundary. It owns
|
|
simulation records, invokes the focused systems, stores selected actions and
|
|
targets, and translates presentation callbacks into simulation transitions.
|
|
It also publishes the latest `ActionSelectionResult` for presentation; the UI
|
|
does not recompute decisions. At completion it atomically pays any
|
|
definition-backed stored-resource cost before applying the action effect. A
|
|
late shortfall suppresses the effect and records a `task_blocked` fact. The
|
|
manager also captures actor/nearby knowledge before forwarding newly recorded
|
|
events into `RelationshipSystem`. When an NPC arrives beside a worker at the
|
|
same non-storage activity site, the manager may transfer one direct known fact
|
|
and applies its consequence only to that newly informed listener. It exposes
|
|
knowledge, provenance, relationship, and cause queries without moving social
|
|
authority into UI.
|
|
|
|
### VillageEconomy
|
|
|
|
- owns storage and NPC-inventory transfer operations;
|
|
- keeps `village.food` and `village.wood` synchronized as aggregate views;
|
|
- validates and pays definition-backed completion costs;
|
|
- emits completed transaction facts without owning their history.
|
|
|
|
### SimulationEventLog
|
|
|
|
- owns ordered economic and narrative event identity;
|
|
- answers recent-history, actor-history, and consumption-rate queries;
|
|
- restores persisted history without performing or replaying transactions.
|
|
|
|
### EventKnowledgeSystem
|
|
|
|
- stores stable `(knower_id, event_id)` references separately from objective
|
|
history;
|
|
- initially observes successful food-deposit events for the actor and living
|
|
NPCs within a fixed proximity radius;
|
|
- preserves first acquisition as performed, witnessed, communicated, or
|
|
legacy, with a stable source NPC ID for direct communication;
|
|
- permits one performed/witnessed fact to cross one co-located social hop, but
|
|
does not relay communicated or ambiguous legacy facts;
|
|
- captures evidence only when the event happens, never from current positions
|
|
during restore;
|
|
- answers deterministic known-event and knower queries without formatting
|
|
prose or choosing actions.
|
|
|
|
### RelationshipSystem
|
|
|
|
- owns directed familiarity/trust records and stable relationship queries;
|
|
- applies a bounded trust gain when a hungry familiar NPC knows about a
|
|
contributor's successful food-deposit event;
|
|
- stores the exact event ID as the trust cause and ignores replayed or older
|
|
events;
|
|
- selects trusted starving subjects deterministically for action selection;
|
|
- does not choose actions, perform transactions, or format presentation text.
|
|
|
|
These collaborators are `RefCounted` rule services, not additional scene-tree
|
|
managers. Further decomposition should follow measured pressure and a proven
|
|
gameplay consumer.
|
|
|
|
## Active-position contract
|
|
|
|
NpcVisual emits active position changes after successful movement.
|
|
WorldViewManager forwards those facts through
|
|
`SimulationManager.synchronize_npc_position()`. Arrival, navigation failure,
|
|
and visual unload also perform a final synchronization.
|
|
|
|
SimNPC stores both authoritative position and the resolved travel destination.
|
|
The destination is versioned simulation state, so reloading a visual resumes
|
|
the same route request without rerolling wander, resolving another resource, or
|
|
changing a reservation.
|
|
|
|
`tests/npc_visual_lifecycle_test.gd` proves that visual unload/reload preserves
|
|
action, target ID, travel destination, resource reservation, position, and
|
|
state checksum.
|
|
|
|
Unloaded NPCs do not yet resolve abstract travel time; they remain in their
|
|
current task state until an active visual or a future simulation-LOD travel
|
|
system advances them.
|