feat: add provenance-aware npc communication

This commit is contained in:
Rijad Zuzo
2026-07-11 19:58:47 +02:00
parent 81409650df
commit 9a479ba182
18 changed files with 938 additions and 70 deletions
+9 -2
View File
@@ -72,8 +72,11 @@ 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`. It exposes knowledge, relationship, and cause
queries without moving social authority into UI.
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
@@ -94,6 +97,10 @@ queries without moving social authority into UI.
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
+3 -2
View File
@@ -15,7 +15,7 @@ SimulationClock
-> ActionTargetResolver resolves a stable target ID
-> VillageEconomy performs inventory/storage transactions
-> SimulationEventLog records completed facts
-> EventKnowledgeSystem records actor/nearby knowledge
-> EventKnowledgeSystem records actor/nearby knowledge and bounded transfers
-> RelationshipSystem applies evidence-gated social consequences
-> WorldViewManager presents travel and NPC state
-> ActiveWorldAdapter supplies loaded-world positions/capacity
@@ -33,7 +33,8 @@ would otherwise obscure that lifecycle:
- `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 and captures proximity witnesses at record time;
known objective events, immutable acquisition provenance, proximity witnesses
at record time, and one-hop direct fact transfer;
- `simulation/relationships/RelationshipSystem.gd` owns directed relationship
queries, event-driven trust changes, and deterministic social tie-breaking;
- `simulation/persistence/` owns save-slot file safety;
+8 -3
View File
@@ -689,12 +689,17 @@ Completed:
21. Witnessed event knowledge: objective food-deposit events create separate
known-event references for their actor and nearby living NPCs. Knowledge
gates trust, produces a real informed-versus-uninformed choice divergence,
survives schema-v5 save/load, and appears in the NPC inspector.
survives versioned save/load, and appears in the NPC inspector.
22. Co-worker fact communication: known-event records retain performed,
witnessed, communicated, or legacy acquisition provenance. An arriving NPC
can hear one direct fact from a nearby worker at the same non-storage
activity; the inspector names the speaker, the original event is not
replayed, and heard facts do not cascade yet.
Next:
1. Add one provenance-aware NPC-to-NPC fact transfer, then bounded
importance/retention rules, as sequenced in `LEARNING_ROADMAP.md`.
1. Add bounded importance/retention rules for known facts, as sequenced in
`LEARNING_ROADMAP.md`.
Do not start with GIS data, a full city, a large asset pack, or more NPC
mechanics. The next proof is a beautiful stage for the systems that already
+22 -10
View File
@@ -37,12 +37,13 @@ transfer occurred.
## Persistence and determinism
`SimulationStateRecord` schema v5 stores the ordered event stream,
`SimulationStateRecord` schema v6 stores the ordered event stream,
`next_event_id`, directed relationships that may reference an exact event, and
per-NPC known-event references. Schema v1 and v2 saves migrate to an empty
stream beginning at ID zero. Parsing rejects duplicate event IDs, invalid or
duplicate knowledge references, relationship causes the observer does not
know, and a next ID that could collide with restored history.
per-NPC known-event references with first-acquisition provenance. Schema v1 and
v2 saves migrate to an empty stream beginning at ID zero. Parsing rejects
duplicate event IDs, invalid or duplicate knowledge references, impossible
communicator sources, relationship causes the observer does not know, and a
next ID that could collide with restored history.
A successful food deposit can currently raise a hungry familiar NPC's directed
trust in its contributor only when that NPC knows the event. The actor and
@@ -53,6 +54,15 @@ rather than copied prose, so the inspector can resolve and display the real
completed fact. This is a first evidence-gated causal consumer of the event
stream, not general event sourcing.
Knowledge now records whether an NPC performed, witnessed, heard, or inherited
a fact from a legacy save. When an NPC arrives beside an already-working NPC at
the same non-storage activity site, the worker may communicate one newest
direct fact within 2.5 metres. The listener references the same immutable event
and retains the speaker ID; no transaction or event is replayed. Only
performed/witnessed facts can cross this one social hop, so this is not yet a
rumour cascade. Relationship appraisal uses the listener's state when the fact
is acquired, not a reconstruction of their needs when the old event occurred.
The food-loop regression verifies this chain:
```text
@@ -73,8 +83,10 @@ NPC record, so unloading presentation does not lose the fact.
The stream is currently kept in full for the small simulation garden. Before
large populations or long-running worlds, add measured retention,
archival/summary rules, and query indexes. Proximity is the only current witness
rule; line of sight, hearing, acquisition provenance, communication, secrecy,
false beliefs, multi-event causal graphs, and memory retention belong in later
event/history slices. They should extend this record family without making
prose authoritative or recomputing old evidence from current positions.
archival/summary rules, and query indexes. Proximity is the only current direct
witness rule, and communication is intentionally one-hop and tied to shared
activity arrival. Line of sight, hearing, acquisition timestamps, multi-hop
rumours, secrecy, false beliefs, multi-event causal graphs, and memory
retention belong in later event/history slices. They should extend this record
family without making prose authoritative or recomputing old evidence from
current positions.
+17 -7
View File
@@ -668,16 +668,26 @@ The first witnessed-knowledge slice is also complete:
- two equally familiar guards with different evidence now gain different trust
and choose helping versus ordinary patrol;
- the inspector resolves and displays the selected NPC's latest known fact;
- schema v5 migration, invalid-reference rejection, deterministic save/load,
- schema v6 migration, invalid-reference rejection, deterministic save/load,
and proximity/idempotence tests cover the complete slice.
This proves the first Milestone 6 evidence-to-choice exit path without claiming
full memory or belief simulation. The practical next sequence is:
The first communicated-knowledge slice is complete:
1. Add acquisition provenance and one bounded NPC-to-NPC fact transfer so
information can travel beyond direct witnesses without replaying events.
2. Add importance/retention rules for known facts before expanding into
distortion, secrecy, rumours, or opportunity generation.
- first acquisition is persisted as performed, witnessed, communicated, or
legacy, with the direct speaker retained for communicated facts;
- a villager arriving beside an already-working villager at a shared
non-storage activity can receive one newest direct fact within 2.5 metres;
- communication references the original immutable event, changes only the
listener's knowledge/relationship consequence, and cannot relay a heard fact
again in this bounded phase;
- the inspector names who communicated the fact, and schema-v6 migration,
malformed-provenance rejection, event-history invariance, save/checksum, and
informed-choice regressions cover the complete slice.
This advances the first Milestone 6 evidence-to-choice path without claiming
full memory or belief simulation. The practical next slice is importance and
retention for known facts before expanding into distortion, secrecy, rumours,
or opportunity generation.
Recently completed:
+20 -14
View File
@@ -414,8 +414,9 @@ Focused `RefCounted` collaborators keep rule ownership visible:
- `VillageEconomy` owns storage/inventory transactions and synchronized
village resource views;
- `SimulationEventLog` owns deterministic event history and queries;
- `EventKnowledgeSystem` owns per-NPC known-event references and captures
actor/nearby evidence when a witnessable event is recorded;
- `EventKnowledgeSystem` owns per-NPC known-event references, immutable
first-acquisition provenance, actor/nearby evidence capture, and bounded
one-hop communication;
- `RelationshipSystem` owns directed relationship state, event-driven trust
consequences, and deterministic social queries.
@@ -476,6 +477,7 @@ NpcVisual navigates through the active world
| |
| v
| SimulationManager marks NPC as working
| -> at a shared activity, one nearby worker may communicate one direct fact
| |
| v
| Later ticks complete work
@@ -521,12 +523,13 @@ NpcVisual navigates through the active world
│ ├── definitions/ Stable IDs and custom definition resources
│ ├── economy/ Inventory and storage transactions
│ ├── events/ Ordered event history and queries
│ ├── knowledge/ Per-NPC references to known objective events
│ ├── knowledge/ Per-NPC facts, provenance, and bounded transfer
│ ├── persistence/ Validated local save-slot storage
│ ├── relationships/ Directed social consequences and queries
│ └── state/ Versioned simulation-state records
├── tests/
│ ├── action_system_boundaries_test.gd
│ ├── communicated_knowledge_consequence_test.gd
│ ├── deterministic_simulation_test.gd
│ ├── food_storage_loop_test.gd
│ ├── jajce_world_scaffold_test.gd
@@ -568,7 +571,7 @@ These are expected prototype constraints, not necessarily isolated bugs:
gathering use `ResourceNode` instances with no fallback, food transfer uses
the typed pantry `StorageNode`, and patrol/study/rest use `ActivitySite`.
- Current NPC, village, resource, storage, event, knowledge, relationship,
clock, and RNG state serialize through world schema v5. F5/F9 provide one
clock, and RNG state serialize through world schema v6. F5/F9 provide one
validated local quicksave; a save menu, metadata, and player-transform
persistence remain deferred.
- Simulation-owned resource records retain live amounts, reservations, and
@@ -582,12 +585,13 @@ These are expected prototype constraints, not necessarily isolated bugs:
village storage. Other village metrics remain aggregate values rather than
located items.
- NPCs have home positions, schedule periods, carried food/wood, and directed
familiarity/trust. They can retain direct proximity-witness knowledge of a
food deposit, but do not yet have wider social dimensions, goals, line of
sight/hearing evidence, memory decay, false beliefs, or communication.
- The reason inspector exposes current decisions, utility rejections, and one
exact relationship cause plus the latest known fact, but deeper historical
decision traces are not yet retained.
familiarity/trust. They retain direct or one-hop communicated knowledge of a
food deposit with first-acquisition provenance, but do not yet have wider
social dimensions, goals, line-of-sight/hearing evidence, importance/decay,
false beliefs, or multi-hop rumours.
- The reason inspector exposes current decisions, utility rejections, one exact
relationship cause, and the latest known fact with its speaker when
communicated, but deeper historical decision traces are not yet retained.
- Active navigation is used as if all agents are local; no simulation LOD exists.
- Unloaded traveling NPCs preserve their state but do not yet advance through
abstract travel time.
@@ -827,10 +831,12 @@ simulation-garden runtime capture are complete.
The first relationship and knowledge consequences are also complete:
food-deposit events become separate known facts for their actor and nearby
living NPCs; only an informed hungry familiar NPC gains directed trust. The
exact event remains visible as both known fact and relationship cause, and that
trust can redirect ordinary work toward helping a starving acquaintance. One
provenance-aware NPC-to-NPC fact transfer is the next systems slice.
living NPCs; only an informed hungry familiar NPC gains directed trust. At a
shared non-storage activity, an already-working direct knower can tell one fact
to an arriving nearby villager. The same event remains visible as known fact
and relationship cause, the inspector names the speaker, and the listener's
future work can change without duplicating event history. Importance and
retention for known facts is the next systems slice.
The remaining simulation-garden target still aims for:
+26 -10
View File
@@ -3,7 +3,7 @@
## Current contract
`SimulationStateRecord` is the versioned JSON boundary for the current
simulation. The current world schema is v5 and captures:
simulation. The current world schema is v6 and captures:
- simulation seed, tick interval, tick count, clock remainder, and elapsed
clock ticks;
@@ -18,14 +18,14 @@ simulation. The current world schema is v5 and captures:
- directed relationship records with familiarity, trust, and the stable event
ID that last changed trust;
- per-NPC known-event records that reference objective event history without
copying it.
copying it, including first-acquisition method and communicator provenance.
The top-level identity is:
```json
{
"schema": "the_steward.simulation",
"schema_version": 5
"schema_version": 6
}
```
@@ -56,8 +56,8 @@ its future random sequence.
It also verifies clock remainder, resource amount/reservation/enabled
round-tripping, presentation unload/rebind, directed relationship/cause
round-tripping, divergent known-event state, and rejection of unsupported
schemas.
round-tripping, divergent known-event state, communicated provenance, and
rejection of unsupported schemas.
NPCStateRecord v2 adds the resolved travel destination and whether it is
active. Nested v1 NPC records migrate explicitly with no invented active
@@ -106,9 +106,24 @@ a food deposit performed by the relationship subject.
World schema v4 migrates relationship causes into known-event records. The old
schema used village-wide awareness, so this preserves the implied known fact
without falsely inventing spatial witness provenance. New v5 facts are created
only at event-record time from the actor and nearby NPC positions; historical
events are never re-evaluated against current positions.
without falsely inventing spatial witness provenance.
SimulationStateRecord v6 / KnownEventStateRecord v2 adds immutable
first-acquisition provenance: `performed`, `witnessed`, `communicated`, or
`legacy`. Communicated records also retain the stable NPC ID of the direct
speaker. New direct facts are created only at event-record time from the actor
and nearby NPC positions; historical events are never re-evaluated against
current positions. A co-located shared-activity encounter can add one
communicated reference to the original fact without appending or replaying the
event.
World schema v5 migrates actor-owned knowledge to `performed`; non-actor
knowledge becomes `legacy` because v5 may contain either a proximity witness or
an older implied relationship fact. Parsing never invents that missing
provenance. Current communicated records require a distinct existing source
who knows the same event through `performed` or `witnessed` acquisition. This
enforces the current one-hop boundary and makes validation independent of array
ordering.
## Resource authority
@@ -146,10 +161,11 @@ This phase does not yet provide:
- a save-slot menu, metadata, thumbnails, autosaves, or multiple profiles;
- migrations from any historical world schema other than the explicitly
supported v1v4 layouts;
supported v1v5 layouts;
- player inventory or player relationship records;
- broader relationship dimensions, line-of-sight/hearing evidence,
acquisition provenance, memory decay, or communication;
acquisition timestamps, importance/retention, memory decay, or multi-hop
rumours;
- persistence for the player transform or presentation-only scene state.
Those features should build on this boundary rather than inventing parallel