docs: record player-citizen loop, care needs, regrowth, and seasons

This commit is contained in:
Rijad Zuzo
2026-08-11 00:46:00 +02:00
parent e51cde57be
commit e359e5253a
7 changed files with 150 additions and 38 deletions
+4
View File
@@ -41,6 +41,10 @@ would otherwise obscure that lifecycle:
advancement, deterministic routine selection, loaded binding, feed
reservations, exact NPC pantry-to-inventory-to-animal delivery, and the
bounded direct player pantry-to-animal operation;
- `simulation/player/player_citizen_system.gd` owns the persisted
`PlayerStateRecord` (hunger, energy, carried inventory), deterministic
needs advancement, and the player's carry/deposit/eat transactions through
the same storage and event contract as NPCs;
- `simulation/events/SimulationEventLog.gd` owns ordered event identity,
history queries, and rate calculations;
- `simulation/knowledge/EventKnowledgeSystem.gd` owns per-NPC references to
+26 -6
View File
@@ -836,15 +836,35 @@ Completed:
action; unload clears the note and restore re-derives saved facts while
awaiting the next transient reason. The note coexists with the `E` prompt,
remains in cinematic mode, and adds no saved state or simulation mutation.
46. `Jajce Field Note Need 13`: the same field note now surfaces the inspected
villager's exact open village need, its real progress, and whichever
authoritative response currently exists — the capable helper, the player
finite-source route, or an honest unavailable state. A real player
harvest-to-pantry deposit resolves it through the ordinary carry path
without dialogue, acceptance, or quest state.
47. `Jajce Citizen Player 14`: the player becomes a citizen. A persisted
`PlayerStateRecord` tracks hunger, energy, and carried inventory; gathering
fills the pack, depositing restocks typed storage, and eating eases hunger.
A bottom-center status line makes the loop readable, and nearby villagers
witness and can trust a real pantry restock.
48. `Jajce Care Needs 15`: two more village needs join the family — a starving
low-energy villager who cannot feed themselves (`feed_weak_villager`,
resolved only when that villager eats) and a damaged roof after a low-safety
night (`repair_home_roof`, resolved through the wood deposit path).
49. `Jajce Seasons 16`: a deterministic four-day seasonal cycle halves gather
yields and pauses berry regrowth on the cold day, so the garden keeps
producing real scarcity the player can help address.
Next:
1. Let an inspected villager who owns an open opportunity surface that exact
village need plus the authoritative direct-help route, capable helper, or
honest unavailable state that currently exists.
2. Prove that the ordinary finite-resource-to-storage harvest resolves an
available player route and updates the context without dialogue branching,
acceptance state, rewards, a quest log, or saved presentation state.
1. Let finite berry sources that the player helps regrow feel owned: a bounded
replanting interaction for depleted sources and, later, a planted resource
that appears at a fixed plot after a deterministic delay.
2. Let population growth emerge from a built house: a new named villager arrives
after a seeded delay and joins the profession registry, with arrival covered
by the scaling fixture.
3. Add a market/traveler cadence so the returning player finds something new:
a traveler who shares one rumour or a bounded food-for-wood exchange.
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
+17
View File
@@ -11,6 +11,8 @@ storage_deposited
storage_withdrawn
item_consumed
animal_fed
villager_weak
home_damaged
```
Each record contains a monotonically increasing event ID, event type,
@@ -25,6 +27,21 @@ stable animal ID at delivery. Player `animal_fed` remains a direct
pantry-to-animal fact; actor `-1` identifies that player-triggered feeding or
extraction until persistent player identity is introduced.
The player now lives as a citizen with a persisted `PlayerStateRecord`. Player
gathering records a `resource_extracted` move from the finite source to the
`player_inventory` holder; depositing at the pantry or woodpile records a
`storage_deposited` move from that holder into the typed storage; eating
records `item_consumed` from carried food or the pantry. All player events use
the stable `PLAYER_ACTOR_ID`, so nearby living villagers witness a pantry
restock as a knowable fact and a hungry familiar witness can gain directed
trust toward the player. The old direct harvest-into-pantry `resource_extracted`
facts remain legacy-compatible for v12 saves.
Two bounded narrative facts feed the care opportunity family: `villager_weak`
marks a starving, low-energy villager who cannot feed themselves from an empty
pantry, and `home_damaged` marks a villager who slept through critically low
safety. Both are knowable by their actor and nearby witnesses.
Events are immutable facts about completed transfers. They do not perform the
transaction and are not replayed to reconstruct current state. Resource,
inventory, and storage records remain authoritative.
+14
View File
@@ -984,6 +984,20 @@ resolve the need without adding a dialogue tree, quest acceptance, rewards, a
quest log, reputation, a generic conversation framework, or saved presentation
state in that slice.
That observation-to-agency slice is now complete: the player-facing field note
surfaces the inspected villager's exact open need and the currently
authoritative response, and a real player harvest-to-pantry deposit resolves
it through the ordinary carry path. The player is also a real citizen now: a
persisted `PlayerStateRecord` tracks hunger, energy, and carried inventory,
gathering moves yield into that carried inventory, depositing restocks the
typed storage, and eating eases hunger from carried or pantry food. Player
restocks are witnessed and can raise a hungry familiar villager's directed
trust toward the player. The opportunity family grew to four types
(`restock_empty_pantry`, `supply_missing_wood`, `feed_weak_villager`, and
`repair_home_roof`), finite berry sources regrow toward an authored cap, and a
cold season halves gather yields and pauses regrowth to create recurring
scarcity.
Recently completed:
- `Jajce Villager Field Note 12`: a separate player-facing note selects the
+45 -19
View File
@@ -226,12 +226,22 @@ plugin content, not game architecture.
follow/focus behavior, and exposes an opt-in presentation preset for
reproducible runtime captures.
- Pressing `E` near a berry bush or tree extracts its configured yield into the
village through the same `ResourceNode` contract used by NPCs.
player's carried inventory through the same `ResourceNode` contract used by
NPCs. At the pantry or woodpile the same `E` deposits carried food or wood;
at the pantry it can also eat from carried or village food.
- The player is a citizen: a persisted hunger/energy/carried-inventory record
advances on the simulation tick, gathering fills the carried inventory,
depositing restocks typed storage, and eating eases hunger. A compact
bottom-center status line shows hunger, energy, and carried goods, and nearby
villagers witness and can trust a real player pantry restock.
- Guard, study, rest, and food interactions now use typed world sites.
- A cardless bottom-center `E` prompt derives the exact current animal,
resource, storage, or activity target and its availability. Named goat care
reports pantry cost plus transient success or blockage, remains in cinematic
mode, and never enters saved state.
- The world runs a deterministic four-day seasonal cycle: the cold day halves
gather yields and pauses berry regrowth, surfacing a recurring shortage the
player and villagers can address.
- `Escape` releases captured mouse input.
### Village simulation
@@ -630,11 +640,19 @@ 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, animal, event, knowledge,
relationship, opportunity, clock, and RNG state serialize through world
schema v11. 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
usage definitions while ResourceNode scenes are unloaded.
relationship, opportunity, clock, RNG, and player-citizen state serialize
through world schema v13. F5/F9 provide one validated local quicksave; a save
menu, metadata, and player-transform persistence remain deferred.
- The player is a first-class citizen with persisted hunger, energy, and
carried inventory. Gathering moves yield into carried inventory, depositing
restocks the typed pantry or woodpile, and eating eases hunger from carried
or pantry food. Nearby villagers witness a real player pantry restock and a
hungry familiar witness can gain directed trust toward the player.
- Finite berry sources regrow deterministically toward an authored `max_amount`
cap, and a cold season (one of every four simulated days) halves gather
yields and pauses regrowth, creating recurring scarcity.
- Simulation-owned resource records retain live amounts, reservations, usage
definitions, and regrowth rules while ResourceNode scenes are unloaded.
- An explicit fixed-step clock converts frame delta into simulation ticks, but
orchestration still lives on the scene-tree `SimulationManager`.
- Automated coverage includes deterministic same-seed and save/restore
@@ -655,14 +673,16 @@ These are expected prototype constraints, not necessarily isolated bugs:
other knowledge is capped and reviewed after one simulated day. NPCs do not
yet have wider social dimensions, goals, line-of-sight/hearing evidence,
personalized reinforcement/decay, false beliefs, or multi-hop rumours.
- The bounded opportunity family supports one open `restock_empty_pantry` or
`supply_missing_wood` need from exact known evidence. Both have exact NPC and
player supply resolutions; the wood need also closes deterministically on
interested-party death or one-day staleness. One read-only query derives and
explains a capable helper, and the matching idle NPC can consume it through
ordinary action selection after urgent self-care and schedule precedence.
There is still no helper assignment, acceptance, rewards, free-form dialogue,
or quest log.
- The bounded opportunity family supports one open need from exact known
evidence: `restock_empty_pantry`, `supply_missing_wood`,
`feed_weak_villager`, and `repair_home_roof`. The pantry and weak-villager
needs resolve through real food supply (the weak need only when the
interested villager actually eats), the wood needs through the real
wood-deposit path, and all close deterministically on interested-party death
or one-day staleness. One read-only query derives and explains a capable
helper, and the matching idle NPC can consume it through ordinary action
selection after urgent self-care and schedule precedence. There is still no
helper assignment, acceptance, rewards, free-form dialogue, or quest log.
- The reason inspector exposes current decisions, utility rejections, one exact
relationship cause, and a compact person-history view that distinguishes
importance-ranked retained memories from objective personal actions.
@@ -1036,24 +1056,30 @@ route, a capable helper, or an honest unavailable state. An available player
route should resolve through the ordinary harvest path without dialogue
branching, quest acceptance, rewards, or saved UI state.
The remaining simulation-garden target still aims for:
The remaining simulation-garden target now adds the player-citizen loop on top
of the completed autonomous core:
- one attractive valley section;
- six named villagers;
- three visibly distinct workplaces;
- food and wood as location-based resources;
- visible gathering, carrying, storing, and consuming;
- hunger and energy;
- visible gathering, carrying, storing, and consuming for both NPCs and player;
- hunger and energy for NPCs and the player;
- one understandable shortage crisis;
- direct player assistance and priority influence;
- day/night presentation;
- an in-game reason inspector;
- deterministic replay or scenario reset;
- save/load for the slice;
- the player carried-inventory loop: gather → carry → deposit → eat;
- recurring cold-season scarcity and finite-source regrowth;
- four knowledge-gated village need types with honest helper/player routes;
- a stable 2030 minute session.
Safety and knowledge can remain present, but their deeper production chains
should follow a complete food loop rather than grow in parallel.
Still deferred: replanting, population growth from a built house, and a
market/traveler cadence. Safety and knowledge can remain present, but their
deeper production chains should follow a complete food loop rather than grow in
parallel.
## Out of scope until the simulation garden works
+22 -10
View File
@@ -56,21 +56,33 @@ unknown profession or executable action.
## Opportunity vocabulary
`SimulationIds` defines the two proven opportunity types,
`restock_empty_pantry` and `supply_missing_wood`, plus the stable `open`,
`resolved`, and `invalidated` statuses. Invalidation reasons currently
distinguish `interested_died` from `evidence_stale`. These are serialized
vocabulary, not editor-authored quest definitions. Dynamic trigger, interested
NPC, storage/resource goal, progress, exact resolution-event identity, and
close reason belong to `OpportunityStateRecord` and
`VillageOpportunitySystem`.
`SimulationIds` defines the four proven opportunity types,
`restock_empty_pantry`, `supply_missing_wood`, `feed_weak_villager`, and
`repair_home_roof`, plus the stable `open`, `resolved`, and `invalidated`
statuses. Invalidation reasons currently distinguish `interested_died` from
`evidence_stale`. These are serialized vocabulary, not editor-authored quest
definitions. Dynamic trigger, interested NPC, storage/resource goal, progress,
exact resolution-event identity, and close reason belong to
`OpportunityStateRecord` and `VillageOpportunitySystem`.
The shared record and lifecycle collaborator were extracted only after the
The shared record and lifecycle collaborator was extracted only after the
food and wood consumers proved those fields. Their evidence, care, resolution,
and invalidation rules remain explicit branches. Do not add a generic quest-
and invalidation rules remain explicit branches. `feed_weak_villager` opens on
a `villager_weak` fact when a starving low-energy villager cannot eat and
resolves only when that same villager actually consumes food; `repair_home_roof`
opens on a `home_damaged` fact when a villager sleeps through low safety and
resolves through the real wood-deposit path. Do not add a generic quest-
definition registry until real acceptance, assignment, reward, or dialogue
consumers establish a second shared contract.
## Player actor vocabulary
`SimulationIds.PLAYER_ACTOR_ID` (`-1`) is the stable event actor for
player-performed actions, and `SimulationIds.PLAYER_INVENTORY_ID` names the
carried-inventory holder in economic events. Player-performed pantry food
supply is witnessed by nearby villagers and can raise their directed trust
toward the player, with the player as a relationship subject.
## Validation
The registry rejects:
+22 -3
View File
@@ -3,7 +3,7 @@
## Current contract
`SimulationStateRecord` is the versioned JSON boundary for the current
simulation. The current world schema is v11 and captures:
simulation. The current world schema is v13 and captures:
- simulation seed, tick interval, tick count, clock remainder, and elapsed
clock ticks;
@@ -25,14 +25,17 @@ simulation. The current world schema is v11 and captures:
historical communicator provenance;
- opportunity records with stable type/status, interested NPC, trigger event,
target storage/resource/amount, exact later resolution event identity, or a
deterministic invalidation reason and close tick.
deterministic invalidation reason and close tick;
- a player record holding the player-citizen's hunger, energy, and carried
inventory. The player's world position remains presentation-owned and is
intentionally not serialized.
The top-level identity is:
```json
{
"schema": "the_steward.simulation",
"schema_version": 11
"schema_version": 13
}
```
@@ -214,6 +217,22 @@ SimulationStateRecord v11 preserves world-v10 animals and upgrades nested
idle, immediately due routine without inventing a destination; loaded-world
selection establishes the first real target later.
SimulationStateRecord v12 lets `RelationshipStateRecord` reference the player
sentinel (`PLAYER_ACTOR_ID`) as a subject, so a villager's directed trust can
point at the player. World v11 migration adds nothing but accepts the relaxed
validation; existing NPC-only relationship history is preserved. Player-triggered
food supply is recorded as a pantry `storage_deposited` from the player inventory
(or, for legacy v11 saves, as a direct harvest into the pantry).
SimulationStateRecord v13 adds the top-level `player` record
(`PlayerStateRecord` v1) with the player-citizen's hunger, energy, and carried
inventory. World schemas v12 and earlier migrate to a fresh default player
record (hunger 40, energy 100, empty inventory). Player needs advance on the
deterministic tick with exact binary fractions so continuation checksums stay
stable. Resource records also migrate to v4, adding `max_amount` and
`regrow_rate`; legacy v3 resources keep their current amount as the cap and
gain no regrowth.
Current-schema parsing requires unique animal IDs that do not collide with
resource or storage IDs. An animal reservation must belong to an existing NPC
whose active feed task targets that exact animal. Every `animal_fed` event