Wood now follows the same gather-carry-deposit pattern as food. NPCs put harvested wood into inventory, walk to the VillageWoodpile StorageNode, and deposit it. Village wood syncs from storage. Player harvesting also routes wood to the woodpile. ActiveWorldAdapter exposes woodpile routing for DEPOSIT_WOOD action targeting. WorldViewManager recognizes wood inventory changes. Tests verify woodpile node existence, storage ID, navigation reachability, and adapter routing.
Add home_positions export to SimulationManager. When configured, NPCs get homes assigned from the array wrapping around for more NPCs than homes. main.tscn now sets 6 home positions near the three village houses, so each NPC has a real home to walk to at night. Empty home_positions leaves the spawn-point-as-home backward-compatible behavior.
DayNightCycle now reads time_of_day from SimulationManager group node, falling back to self-tracked elapsed for lookdev scenes. Simulation starts at 06:00 morning (tick 50) by default. TimeDial reads directly from SimulationManager and displays HH:MM format with a 24-hour dial arc. Removed initial_cycle override from JajceLookdev.
A 60x60 circular dial drawn at the top-center of the screen shows the current position in the day/night cycle. A filled arc sweeps clockwise from the top; the color transitions from dark blue (night) through orange (dawn), gold (day), and pink (dusk). A small glow dot marks the leading tip; a phase label (Night/Dawn/Day/Dusk) sits below. Redraws only when the cycle fraction changes. References DayNightCycle via node_path so it stays in sync with the environment lighting.
Replace implicit randomness with seeded per-NPC RandomNumberGenerator
streams so the same seed always produces the same scenario outcome.
- Add SimulationClock (RefCounted): explicit fixed-step clock that
converts frame delta into simulation ticks while preserving sub-tick
remainder; replaces raw _process tick_timer accumulation
- Add simulation_seed export (int=1337) to SimulationManager; drive
per-NPC RNG streams via seed + npc_id + stream_id derivation
(stream 0=init, stream 1=wander)
- Add get_wander_offset(npc_id) to SimulationManager so wander targets
are deterministic per seed; WorldViewManager calls it instead of
local randf_range()
- Add get_state_snapshot() and get_state_checksum() to SimulationManager
for headless verification and future save/load
- Convert SimNPC/SimVillage const DEBUG_LOGS to instance var debug_logs
so headless tests can silence output without recompilation
- Pass RandomNumberGenerator through SimNPC._init() instead of using
global randf_range() for hunger/energy/position/scoring noise
- Remove obsolete farm_zone and forest_zone exports from
WorldViewManager and their marker/tree scene children from main.tscn;
NPC gather tasks use ResourceNode exclusively
- Rename TaskZone container to ActivityMarkers in main.tscn and update
all scene paths (player, WVM, tests) to match
- Add headless deterministic_simulation_test.gd: verifies clock
accuracy, same-seed equality, different-seed divergence, and
24-tick scenario checksum without loading main.tscn
Phase 1-2 of the ResourceNode migration plan:
- Create ResourceNode class (world/resource_nodes/) with extraction,
reservation, nearest-available selection, and debug label
- Place 4 resource instances in main.tscn (2 berry bushes, 2 trees)
- Add target_id to SimNPC for tracking which node an NPC is using
- Add set_npc_target_id and release_npc_reservation to SimulationManager
with cleanup on task change, completion, and death
- Update WorldViewManager to query available ResourceNodes first,
falling back to zone markers with a logged warning