From 81df7b59390fbefa62af53e8d0349d83282c5ba1 Mon Sep 17 00:00:00 2001 From: Rijad Zuzo Date: Sun, 5 Jul 2026 13:35:42 +0200 Subject: [PATCH] docs: mark simulation definitions phase complete --- docs/BUILD_IN_PUBLIC_PLAN.md | 2 +- docs/LEARNING_ROADMAP.md | 29 ++++---- docs/PROJECT_CONTEXT.md | 12 ++- docs/README.md | 5 +- docs/RESOURCE_NODE_MIGRATION.md | 14 ++-- docs/SIMULATION_DEFINITIONS.md | 74 +++++++++++++++++++ docs/SIMULATION_STATE_SCHEMA.md | 5 ++ .../0001-simulation-authority-boundary.md | 2 + 8 files changed, 118 insertions(+), 25 deletions(-) create mode 100644 docs/SIMULATION_DEFINITIONS.md diff --git a/docs/BUILD_IN_PUBLIC_PLAN.md b/docs/BUILD_IN_PUBLIC_PLAN.md index 8ab2570..838802f 100644 --- a/docs/BUILD_IN_PUBLIC_PLAN.md +++ b/docs/BUILD_IN_PUBLIC_PLAN.md @@ -362,7 +362,7 @@ learning roadmap: - fixed-seed headless scenarios and final-state checksum; ✅ - versioned serializable NPC, village, resource, clock, and RNG records; ✅ - resource amount and reservation authority outside scene nodes; ✅ -- stable action/profession IDs and initial definitions; +- stable action/profession IDs and initial definitions; ✅ - separate action selection, execution, target resolution, and visual travel; - explicit active-position synchronization. diff --git a/docs/LEARNING_ROADMAP.md b/docs/LEARNING_ROADMAP.md index 32f6abd..73236b8 100644 --- a/docs/LEARNING_ROADMAP.md +++ b/docs/LEARNING_ROADMAP.md @@ -54,7 +54,7 @@ The gate is complete when the same scenario produces the same checksum without loading `main.tscn`, and loading or unloading a visual does not change authoritative NPC or resource state. -**Current progress:** the first three architecture slices are implemented: +**Current progress:** the first four architecture slices are implemented: - `SimulationClock` advances explicit fixed ticks while preserving remainder; - NPC decisions and visual wander requests use controlled per-NPC random @@ -70,9 +70,14 @@ authoritative NPC or resource state. geometry; - an unload/rebind regression proves resource state remains authoritative while its scene node is absent. +- stable StringName IDs and validated custom resources define all current + actions and professions; +- NPC duration/preference logic, resource target metadata, generation, and + serialized references resolve through the definition registry. -The gate remains open. Stable definitions, responsibility separation, and NPC -visual load/unload invariance are still required. See +The gate remains open. Responsibility separation and NPC visual load/unload +invariance are still required. See +[the simulation definitions](SIMULATION_DEFINITIONS.md) and [the simulation state schema](SIMULATION_STATE_SCHEMA.md). ## Three vertical slices @@ -620,21 +625,19 @@ Completed foundations: The practical next sequence is: -1. Replace free-form task and profession strings with stable IDs and - definitions. -2. Separate action selection, execution, target resolution, and visual travel; +1. Separate action selection, execution, target resolution, and visual travel; remove decision mutation from `WorldViewManager`. -3. Define active-position synchronization and prove visual unload/reload. -4. Pass the architecture gate's deterministic headless and unloaded-visual exit +2. Define active-position synchronization and prove visual unload/reload. +3. Pass the architecture gate's deterministic headless and unloaded-visual exit tests. -5. Build location-based food storage, inventory, and transactions. -6. Emit structured economic events while making one NPC visibly gather, carry, +4. Build location-based food storage, inventory, and transactions. +5. Emit structured economic events while making one NPC visibly gather, carry, store, retrieve, and eat food. -7. Add save-slot persistence and explicit schema migrations before schedules +6. Add save-slot persistence and explicit schema migrations before schedules or social state expand. -8. Resume Terrain3D sculpting, runtime integration, and the simulation-garden +7. Resume Terrain3D sculpting, runtime integration, and the simulation-garden beauty pass. -9. Add stylized character and profession readability plus the reason +8. Add stylized character and profession readability plus the reason inspector. This order strengthens the simulation while regularly producing visible diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md index 9daa6aa..e1f8def 100644 --- a/docs/PROJECT_CONTEXT.md +++ b/docs/PROJECT_CONTEXT.md @@ -465,12 +465,14 @@ NpcVisual navigates through the active world │ ├── SimVillage.gd │ ├── SimulationClock.gd │ ├── SimulationManager.gd +│ ├── definitions/ Stable IDs and custom definition resources │ └── state/ Versioned simulation-state records ├── tests/ │ ├── deterministic_simulation_test.gd │ ├── flat_map_baseline_test.gd │ ├── jajce_world_scaffold_test.gd │ ├── resource_node_player_parity_test.gd +│ ├── simulation_definitions_test.gd │ └── simulation_state_serialization_test.gd ├── terrain/jajce/ Dedicated Terrain3D seed data and assets ├── tools/ @@ -495,7 +497,8 @@ NpcVisual navigates through the active world These are expected prototype constraints, not necessarily isolated bugs: -- Task names and task-to-activity-marker mappings are duplicated strings. +- Action and profession IDs are stable and definition-backed, but activity + marker mapping and several action effects remain hard-coded. - Temporary activity markers remain for eating, rest, study, and patrol; NPC and player food/wood gathering use `ResourceNode` instances with no fallback. - Current NPC, village, resource, clock, and RNG state serialize through schema @@ -716,7 +719,7 @@ Food and wood migration and the deliberately minimal `JajceWorld` scaffold, greybox, navigation spike, and stable-ID placement proof are complete. Do not proceed directly from that proof into open-ended beauty production. -The architecture gate is now the active milestone. Its first three slices are +The architecture gate is now the active milestone. Its first four slices are complete: - explicit fixed-step simulation clock; @@ -725,11 +728,12 @@ complete: - versioned JSON records for NPC, village, resource, clock, and RNG state; - deterministic save/restore continuation with exact 64-bit RNG preservation; - simulation-owned resource amount/reservation state with ResourceNode - presentation binding and unload/rebind coverage. + presentation binding and unload/rebind coverage; +- stable StringName action/profession IDs plus validated custom definition + resources used by simulation, targeting, generation, and persistence. The remaining gate work is: -- data-defined action and profession IDs; - separated action selection, execution, target resolution, and visual travel; - explicit synchronization of active NPC position. diff --git a/docs/README.md b/docs/README.md index 6704ad7..8f677c0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,7 +15,10 @@ sources of truth. 4. [`RESOURCE_NODE_MIGRATION.md`](RESOURCE_NODE_MIGRATION.md) is a focused migration plan. Phases 1–4 are complete; its Phase 5 hands world placement to the visual-slice plan. -5. [`decisions/`](decisions/) contains durable architectural decisions, +5. [`SIMULATION_DEFINITIONS.md`](SIMULATION_DEFINITIONS.md) and + [`SIMULATION_STATE_SCHEMA.md`](SIMULATION_STATE_SCHEMA.md) document the + current data contracts. +6. [`decisions/`](decisions/) contains durable architectural decisions, including consequences and revisit conditions. When documents disagree: diff --git a/docs/RESOURCE_NODE_MIGRATION.md b/docs/RESOURCE_NODE_MIGRATION.md index 1fa4e47..3cc03f3 100644 --- a/docs/RESOURCE_NODE_MIGRATION.md +++ b/docs/RESOURCE_NODE_MIGRATION.md @@ -218,19 +218,21 @@ signal reservation_changed(node_id: StringName, agent_id: int) @export var node_id: StringName @export var action_id: StringName = &"gather_food" @export var resource_id: StringName = &"food" -@export var amount_remaining: float = 10.0 +@export var initial_amount: float = 10.0 @export var yield_per_action: float = 2.0 -@export var enabled: bool = true +@export var initial_enabled: bool = true @export var can_npcs_use: bool = true @export var can_player_use: bool = true @export var hide_visual_when_depleted: bool = false @onready var interaction_point: Marker3D = $InteractionPoint +var state: ResourceStateRecord ``` -Use `StringName` IDs as a small migration step away from duplicated free-form -`String` values. Later, action and resource definitions can become custom -`Resource` assets without changing every world node's conceptual contract. +Action IDs now use canonical `SimulationIds` values and resolve through +validated `ActionDefinition` resources. ResourceNode's exported amount and +enabled values are initialization defaults only; its bound +`ResourceStateRecord` owns live mutable state. ### Avoid duplicated state @@ -239,7 +241,7 @@ Derive it: ```gdscript func is_depleted() -> bool: - return amount_remaining <= 0.0 + return state.is_depleted() if state != null else initial_amount <= 0.0 ``` If regeneration or non-depleting sources later require more states, introduce diff --git a/docs/SIMULATION_DEFINITIONS.md b/docs/SIMULATION_DEFINITIONS.md new file mode 100644 index 0000000..3a5285e --- /dev/null +++ b/docs/SIMULATION_DEFINITIONS.md @@ -0,0 +1,74 @@ +# The Steward — Simulation Definitions + +## Purpose + +Stable IDs and immutable definitions now form the vocabulary shared by +simulation state, systems, world adapters, scenes, tests, and future save +migrations. + +`SimulationIds` is the canonical source for code-facing `StringName` IDs. +`ActionDefinition` and `ProfessionDefinition` are editor-readable custom +resources. `SimulationDefinitions` loads, resolves, and validates the complete +prototype set. + +## Current action contract + +Each executable action definition contains: + +- stable `action_id`; +- display name; +- default duration; +- optional preferred profession ID; +- target type: resource, activity, or free movement; +- resource action ID when the action targets a ResourceNode. + +The current actions are gather food, gather wood, patrol, study, eat, rest, and +wander. Idle and dead are stable state sentinels, not executable action +definitions. + +SimNPC reads default duration and preferred-profession metadata from these +definitions. WorldViewManager reads target type and resource-action metadata +instead of maintaining a separate gather-action map. + +## Current profession contract + +Each profession definition contains a stable `profession_id` and display name. +The current professions are farmer, woodcutter, guard, scholar, and wanderer. + +NPC generation chooses from the registry's stable IDs. NPC state stores and +restores those IDs as `StringName`, and rejects records that reference an +unknown profession or executable action. + +## Validation + +The registry rejects: + +- missing or duplicate IDs; +- empty display names; +- non-positive action durations; +- invalid target types; +- resource actions without a resource-action ID; +- references to unknown professions or resource actions; +- definition resources that fail to load. + +`tests/simulation_definitions_test.gd` verifies registry integrity, +definition-backed behavior, unknown-ID rejection, and serialization +round-tripping. + +## Deliberate boundary + +Definitions currently own identity and the static metadata already proven by +the prototype. They do not yet own: + +- utility thresholds and consideration curves; +- preconditions or costs; +- completion effects; +- interruption and failure policy; +- reservation strategy; +- target resolution implementation; +- presentation hints beyond target type. + +Those concerns move during the next architecture phase, which separates action +selection, execution, target resolution, and visual travel. Keeping this first +definition contract small avoids encoding the existing manager's mixed +responsibilities as permanent data architecture. diff --git a/docs/SIMULATION_STATE_SCHEMA.md b/docs/SIMULATION_STATE_SCHEMA.md index b57ab42..2064a4a 100644 --- a/docs/SIMULATION_STATE_SCHEMA.md +++ b/docs/SIMULATION_STATE_SCHEMA.md @@ -27,6 +27,11 @@ Unknown schema versions and structurally incomplete records are rejected. Add an explicit migration function before accepting a future version; never silently reinterpret old data as the newest layout. +NPC action and profession references are serialized as stable strings and +restored as `StringName`. Records referencing unknown executable actions or +professions are rejected against the validated definition registry. See +[the simulation definitions](SIMULATION_DEFINITIONS.md). + ## Deterministic continuation RNG seeds and internal states are encoded as decimal strings. They are signed diff --git a/docs/decisions/0001-simulation-authority-boundary.md b/docs/decisions/0001-simulation-authority-boundary.md index c2729f2..0dfef9e 100644 --- a/docs/decisions/0001-simulation-authority-boundary.md +++ b/docs/decisions/0001-simulation-authority-boundary.md @@ -57,6 +57,8 @@ random streams, and no dependency on a loaded gameplay scene. Schema v1 and its deterministic continuation contract are documented in [the simulation state schema](../SIMULATION_STATE_SCHEMA.md). +Stable action/profession identity and immutable metadata are documented in +[the simulation definitions](../SIMULATION_DEFINITIONS.md). ## Consequences