feat: make pantry crises visible in the world

This commit is contained in:
Rijad Zuzo
2026-07-14 23:54:22 +02:00
parent c722e32a88
commit c23f6887c8
21 changed files with 800 additions and 73 deletions
+6 -3
View File
@@ -18,9 +18,10 @@ SimulationClock
-> EventKnowledgeSystem records, ranks, transfers, and retains bounded knowledge
-> RelationshipSystem applies evidence-gated social consequences
-> FoodShortageOpportunitySystem projects one known unresolved need
-> WorldViewManager presents travel and NPC state
-> 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
@@ -89,8 +90,10 @@ improving ownership.
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 consume state-change signals and are intentionally absent
from saves and checksums.
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
+11 -2
View File
@@ -711,11 +711,20 @@ Completed:
NPC or player supply actor. The repeatable debug capture stages this from
live simulation state; world framing and the elevated follow camera remain
unchanged.
26. Physical pantry crisis payoff: the pantry now replaces its inherited
generic crate with empty, low, and stocked arrangements driven by real
storage state. Only the interested villager receives a small state-derived
concern cue; a real deposit clears it and briefly animates the refilled
pantry. The capture tool writes an edit-ready empty/restocked close pair
while leaving gameplay camera defaults and simulation authority unchanged.
Next:
1. Prove the same opportunity lifecycle with one missing-wood `task_blocked`
condition before extracting shared generation rules, as sequenced in
1. Package one 2030 second, repeatable pantry-crisis sequence that communicates
shortage, purposeful gathering, visible carrying, deposit, and recovery
without debug UI. Treat any art or timing work as support for that single
readable cause-and-effect loop. Resume the second missing-wood opportunity
proof after this public-demo exit test, as sequenced in
`LEARNING_ROADMAP.md`.
Do not start with GIS data, a full city, a large asset pack, or more NPC
+20 -5
View File
@@ -730,11 +730,26 @@ The first bounded Milestone 7 opportunity proof is complete:
quest-only event, acceptance, reward, dialogue, multi-hop rumour, or generic
quest framework.
Milestone 7 is not complete. The practical next slice is a second bounded
unresolved-condition consumer: surface missing-wood `task_blocked` facts from
patrol or study as a cared-about woodpile-restock need, resolve it through real
NPC/player wood supply, define deterministic interested-party death/staleness
handling, and only then extract the lifecycle shared by two proven consumers.
The first build-in-public presentation checkpoint for that proof is also
complete:
- authoritative pantry food selects a physical empty, low, or stocked pantry
arrangement instead of leaving a generic storage crate unchanged;
- only the interested villager shows a restrained empty-bowl concern cue;
- a real NPC deposit changes the pantry props, clears concern, and produces one
brief refill response, while restore derives the stable presentation without
replaying that transient effect;
- the repeatable runtime capture now includes an empty/restocked close pair in
the established elevated third-person visual language.
Milestone 7 is not complete. The immediate outcome-defined slice is now one
short, repeatable pantry-crisis sequence that reads without debug UI: shortage,
interested villager, finite-resource trip, visible carrying, deposit, and
physical recovery. Improve route timing, work feedback, and village composition
only where that sequence exposes a readability problem. Once that public-demo
loop passes, prove a second bounded unresolved-condition consumer from a real
missing-wood `task_blocked` fact, include deterministic interested-party
death/staleness handling, and only then extract shared opportunity machinery.
Recently completed:
+24 -13
View File
@@ -2,7 +2,7 @@
> Agent-facing context for understanding the project quickly.
>
> Snapshot basis: repository state on July 13, 2026. Treat the code as the
> Snapshot basis: repository state on July 14, 2026. Treat the code as the
> source of truth when this document and the implementation differ.
See the [documentation map](README.md) for the authority and scope of each plan.
@@ -200,8 +200,8 @@ study, and patrol target typed activity sites. The migration is documented in
`docs/baselines/jajce_lookdev_01.png` with
`tools/capture_jajce_lookdev.gd`
- **Runtime baseline:** `Simulation Garden 01` is captured as paired debug and
cinematic `main.tscn` images under `docs/baselines/` with
`tools/capture_simulation_garden.gd`
cinematic `main.tscn` images plus an empty/restocked pantry close pair under
`docs/baselines/` with `tools/capture_simulation_garden.gd`
- **Terrain compatibility floor:** Godot 4.4 according to the bundled extension
- **Version control:** Git
- **Primary branch:** `main`
@@ -338,8 +338,9 @@ distance with resource `safety_risk`, `comfort_distance`, and
- deterministic shaped terrain data and six game-owned surface layers;
- fortress, houses, mill, bridge, shader river/waterfall, mist, and smoke;
- authored dirt path strips that make the current village task loop readable;
- compact silhouette props for the ridge landmark, pantry, guard, study, and
rest sites;
- compact silhouette props for the ridge landmark, guard, study, and rest
sites, plus a physical pantry whose empty/low/stocked arrangement follows
authoritative food storage;
- warm sky, fog, shadows, coherent wind-reactive foliage, and breeze-aligned
chimney smoke;
- one sparse terrain-aware calligraphic gust field with two or three soft
@@ -382,7 +383,10 @@ A small village panel displays:
NPC name/profession labels, definition-driven colors and props, carried-food
visuals, compact task glyphs, and a brief amber blossom on real trust gains make
active simulation state readable in the world. The F10 cinematic mode hides
debug labels while preserving task glyphs and transient social reactions.
debug labels while preserving task glyphs and transient social reactions. An
open pantry opportunity adds a restrained empty-bowl concern cue only to its
interested villager; a real refill changes the pantry props, clears concern,
and produces one brief pantry response.
## Runtime architecture
@@ -441,7 +445,9 @@ than duplicating these responsibilities across additional manager nodes.
- synchronizes successful visual movement into authoritative NPC position;
- applies visual death state;
- turns authoritative relationship-change signals into observer-only transient
presentation cues without queuing or persisting them.
presentation cues without queuing or persisting them;
- derives pantry stock props and interested-villager concern from authoritative
storage/opportunity state, including state-only rebuilding after restore.
### `player/npc/NpcVisual.gd`
@@ -452,7 +458,8 @@ than duplicating these responsibilities across additional manager nodes.
- moves and rotates toward path points;
- reports arrival;
- presents definition-driven profession silhouettes, carried resources, task
glyphs, walk motion, brief trust-gain blossoms, and death state.
glyphs, walk motion, brief trust-gain blossoms, opportunity concern, and
death state.
### `player/player.gd` and `player/camera_rig.gd`
@@ -870,12 +877,16 @@ stable trigger, interested villager, pantry/food target, status, and later
resolution event; active evidence remains lasting. A real later NPC deposit or
player harvest into the pantry resolves it without quest-only history, economy
mutation by the generator, or AI assignment. The compact village/inspector UI
shows this lifecycle without changing the elevated follow camera.
shows this lifecycle without changing the elevated follow camera. The same
facts now have a cardless world expression: empty/low/stocked pantry props, one
interested-villager concern cue, and a brief refill response. Save/load rebuilds
the stable state without replaying the response.
Milestone 7 remains in progress. The next systems slice should prove the same
lifecycle with a missing-wood `task_blocked` condition and deterministic
interested-party death/staleness handling before extracting common opportunity
machinery.
Milestone 7 remains in progress. The immediate next slice is an outcome-defined
2030 second pantry-crisis demo loop—shortage, finite-resource travel, visible
carrying, deposit, and physical recovery—without debug UI. The second
missing-wood consumer and deterministic interested-party death/staleness rules
follow that visual exit test, before common opportunity machinery is extracted.
The remaining simulation-garden target still aims for:
+27 -6
View File
@@ -1,11 +1,13 @@
# Simulation Garden 01
Captured: 2026-07-13
Captured: 2026-07-14
## Files
- `docs/baselines/simulation_garden_01_debug.png`
- `docs/baselines/simulation_garden_01_cinematic.png`
- `docs/baselines/simulation_garden_02_empty_pantry.png`
- `docs/baselines/simulation_garden_02_restocked_pantry.png`
- `tools/capture_simulation_garden.gd`
## Capture Command
@@ -32,9 +34,11 @@ The script warms up `main.tscn`, verifies that the simulation and active NPC
visuals exist, stages a real food-deposit/trust consequence, a one-food pantry
shortage, the hungry interested villager's ordinary gather-food replan, and one
wind gust. It captures the F10 debug presentation, then the cinematic
presentation with development labels and UI hidden. The trust blossom is
restarted only for the second framing so both captures show the same real
consequence clearly.
presentation with development labels and UI hidden. It lets the earlier trust
reaction finish so the crisis remains the single visual idea, then records a
tighter empty-pantry view. A real NPC deposit resolves the opportunity and
produces the matching restocked view; the capture-only close framing keeps the
same elevated third-person perspective and does not change gameplay defaults.
## Review
@@ -124,5 +128,22 @@ find food` instead of a stale pre-shortage decision.
The inspector still fits the 1280×720 frame without adding another panel, and
the cinematic capture remains free of UI while preserving the task glyph,
trust blossom, and sparse calligraphic gust. Neither gameplay camera defaults
nor the established capture framing changed.
interested-villager concern, and sparse calligraphic gust. Gameplay camera
defaults remain unchanged.
## July 14 physical-crisis follow-up
The pantry is no longer a generic crate whose appearance stays constant. Its
presentation reads the authoritative food amount and swaps between a large
empty terracotta bowl, a low basket with berries/sack, and a fuller stocked
arrangement. The active opportunity adds one small empty-bowl concern mark to
its interested villager only. A real NPC deposit clears that concern and emits
one short amber refill ring/mote response; restoring the same state rebuilds
the stock and concern without replaying the transient response.
The two `simulation_garden_02_*` images form a deterministic before/after pair
for editing or public progress posts. They deliberately keep UI panels out and
use a tighter version of the same elevated camera language. The broader
environment remains prototype-grade; the next useful visual proof is the full
2030 second gather/carry/deposit/recovery loop rather than another isolated
ornament pass.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 KiB

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 KiB

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://csdwcuh4q0n08"
path="res://.godot/imported/simulation_garden_02_empty_pantry.png-8afdd59748244e4706aba1dd7c45f6ef.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://docs/baselines/simulation_garden_02_empty_pantry.png"
dest_files=["res://.godot/imported/simulation_garden_02_empty_pantry.png-8afdd59748244e4706aba1dd7c45f6ef.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bt0wgkeg8rhbf"
path="res://.godot/imported/simulation_garden_02_restocked_pantry.png-e95422ae67d7940f919886822d5c8ab1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://docs/baselines/simulation_garden_02_restocked_pantry.png"
dest_files=["res://.godot/imported/simulation_garden_02_restocked_pantry.png-e95422ae67d7940f919886822d5c8ab1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1