Files
gamedev-the-steward/AGENTS.md
T
2026-08-31 00:09:36 +02:00

373 lines
17 KiB
Markdown

# Agent working guide for The Steward
This repository is a Godot 4.7 simulation prototype. Treat it as a living
systems project, not a content dump. The expected working style is:
## Start here and sources of truth
Begin with `docs/README.md`, then follow it to `docs/DEVELOPER_INDEX.md`. The
developer index is the shortest current map from a feature request to its code,
focused contract, tests, and known incomplete work.
When sources disagree, use this order:
1. Current code and focused tests establish implemented behavior; they do not
silently supersede an architectural decision.
2. Applicable Accepted records in `docs/decisions/` define durable architecture
within their stated scope until another Accepted record explicitly
supersedes them. Treat conflicting code as drift to fix or document.
`docs/ARCHITECTURE_OVERVIEW.md` is the current ownership/dependency map.
3. `docs/DEVELOPER_INDEX.md` and the focused architecture/schema guides define
the current documented contract.
4. `docs/LEARNING_ROADMAP.md` defines sequencing, not runtime truth.
Fix the smallest authoritative document after changing behavior. Do not create
a second implementation in prose or copy the same status table into many docs.
## Codebase discovery with codebase-memory
This repository is indexed as
`Users-rijadzuzo-dev-private-gamedev-the-steward` in codebase-memory. Treat the
name as a lookup hint, not proof that the graph is current.
- At session start, after a pull, and after changing branches, call
`list_projects` and `index_status`. Confirm the indexed root, branch, and HEAD
match the checkout; re-index after a large or external update.
- Use Verify/Tier 2 evidence by default: `search_graph` to find exact symbols,
`trace_path` in the material direction, and `get_code_snippet` for source.
Use `get_architecture` only for orientation, not as a substitute for exact
code.
- Check `has_more`/cursors and paginate relevant results. After candidate files
are known, call `check_index_coverage` once with every evidence path.
- A clean coverage result is best-effort, not proof of completeness. Read exact
source for partial, skipped, excluded, stale, pending, or unknown ranges.
- Use `rg` for string literals, resource paths, scene/config files, generated
data, and graph coverage gaps. Do not make negative or exhaustive claims from
a provisional graph search.
- Before a refactor, use `detect_changes` or inbound traces to inspect the blast
radius. Re-run focused searches after edits rather than relying on this file
as a frozen graph dump.
## Default development loop
1. Read the relevant roadmap/docs before changing code.
- Start with `docs/README.md` and `docs/DEVELOPER_INDEX.md`.
- Use `docs/DEVELOPER_INDEX.md` for current status and open gaps.
- Use `docs/LEARNING_ROADMAP.md` for milestone sequencing and exit tests;
reconcile any candidate slice with current code and focused tests.
- Use focused plans such as `docs/RESOURCE_NODE_MIGRATION.md` only within
their stated scope.
2. Inspect the current code and tests before assuming roadmap status is still
accurate. The user often changes things in parallel.
3. Implement the smallest useful vertical slice.
- Prefer functional systems progress over broad polish.
- Avoid deep rabbit holes unless the current slice needs them.
- Keep Jajce visual/design work bounded; prioritize simulation behavior,
validation, WorldEnvironment ambience, and readable presentation.
4. Validate with the local quality gate.
5. Update the smallest relevant docs after completing a phase or decision.
6. Commit with a conventional commit message.
## Validation
Only Godot 4.7 matters for this project.
Use the project quality gate for the current platform:
```bash
# macOS / Linux
./tools/quality.sh
```
```powershell
# Windows
powershell -ExecutionPolicy Bypass -File .\tools\quality.ps1
```
To narrow formatter/linter scope to changed GDScript files:
```bash
./tools/quality.sh --changed
```
```powershell
powershell -ExecutionPolicy Bypass -File .\tools\quality.ps1 -Changed
```
`--changed` narrows only the `gdformat` and `gdlint` file set. It still runs the
Godot import/parser check, every headless scenario, the compatibility-renderer
scenario, and GUT. Use it only while iterating; run the full current-platform
gate before every commit.
The quality scripts isolate Godot's user profile under `logs/quality/godot_profile`
so headless Godot 4.7 can run without crashing when platform user-data paths
are unavailable. Do not remove that behavior.
Useful extra checks:
```bash
git diff --check
```
If changing `project.godot`, `main.tscn`, autoload/plugin configuration, scene
UIDs or node paths, or startup/runtime scene wiring, also run the configured
main scene with the same Godot 4.7 binary used by the gate:
```bash
"$GODOT_BIN" --headless --path "$PWD" --quit-after 3
```
```powershell
& $env:GODOT_BIN --headless --path (Get-Location).Path --quit-after 3
```
Set `GODOT_BIN` when the gate auto-detected a binary instead. Inspect output as
well as exit status, and accept only diagnostics matching the quality gate's
exact allowlist. Read failures from `logs/quality/latest/`; do not weaken an
allowlist or skip a failing scenario merely to make the gate green.
## Current codebase map
Keep this map concise; `docs/DEVELOPER_INDEX.md` owns the detailed feature
matrix and extension workflow.
- `project.godot` starts `main.tscn`. The main scene wires the authored Jajce
world, player, `ActiveWorldAdapter`, `SimulationManager`,
`SaveSlotController`, `WorldViewManager`, and UI surfaces.
- `simulation/SimulationManager.gd` is the scene-tree facade and deterministic
tick boundary. It advances regional authority before committing the local
tick, then coordinates focused systems rather than duplicating their rules.
- `simulation/actions/`, `simulation/commands/`, and `simulation/economy/` own
selection/execution, target resolution, shared player/NPC command contracts,
and exact inventory or storage transactions.
- `simulation/events/`, `simulation/knowledge/`, `simulation/relationships/`,
`simulation/opportunities/`, `simulation/situations/`,
`simulation/dialogue/`, and `simulation/quests/` turn completed mutations
into causal facts and derived player-facing projections.
- `simulation/state/` owns versioned primitive records;
`simulation/definitions/` owns immutable definitions and stable IDs;
`simulation/regional/` owns scheduled distant work and caravan authority;
`simulation/persistence/` owns combined manifests and safe slot replacement.
- `world/active_world_adapter.gd` and `world/targets/` own contextual loaded-
world discovery, descriptors, capabilities, and transient handles. Resource,
storage, activity, and animal nodes are providers bound to simulation state.
- `world/world_view_manager.gd`, `world/presentation/`, `world/jajce/`,
`world/ui/`, and `player/` own input, geometry, navigation, and visible
feedback. They submit commands or report facts; they do not author saves.
- `tests/` contains deterministic headless scenarios and GUT tests;
`simulation/benchmark/` and `docs/benchmarks/` contain reproducible workload
evidence; `tools/` contains the cross-platform quality gate.
## Architecture direction
Preserve the simulation/presentation boundary.
- Simulation state owns authority: resources, storage, NPC inventory, events,
task state, target IDs, positions, RNG streams, and save records.
- World nodes are presentation and interaction geometry. They may register or
bind state, but they should not become the only owner of persistent facts.
- NPCs store stable IDs, not `NodePath`s or node references.
- Target discovery should go through `ActiveWorldAdapter` and
`ActionTargetResolver`.
- Visual movement belongs to `WorldViewManager`/`NpcVisual`; decision and task
execution belong to the simulation systems.
- Player and NPC callers use the same commands and capabilities. Revalidate the
actor, target, context, range, revision, cost, and permission at execution;
mutate atomically before recording facts or deriving projections.
- Target handles, generation tokens, spatial/population indexes, presentation
cues, and reason traces are disposable derived state. Persist stable
contextual IDs and primitives, then prove rebuilding derived state preserves
decisions and checksums.
- A local tick may advance only after the regional facade succeeds. Regional
work must remain deterministic, bounded, fail-closed, and rollback-safe.
- When regional authority exists, save and restore must use the combined
manifest and remain all-or-nothing. Preserve schema validation, size bounds,
restore rollback, temporary-file validation, and the atomic
temporary/backup/final replacement path; a failed restore emits no success
notification.
When adding a system, first prove the contract with one real gameplay use case.
Do not extract generic frameworks before multiple real consumers justify them.
## Emergent-world doctrine
These agent-facing guardrails summarize ADR 0001 and ADR 0002. The Accepted
records remain authoritative within their stated scopes.
The game world is the source of narrative truth. Dialogue, tasks, quests, and
visible happenings must arise from ordinary simulation state and events rather
than maintaining parallel scripted copies.
- Keep immutable definitions, authored instance placement, mutable state,
systems, and presentation as separate layers.
- Persist stable IDs and primitive data only. Saved state must never contain
scripts, nodes, `NodePath`s, callables, or resource paths.
- Mutate authoritative state before recording the fact that describes the
mutation. Facts may reference exact causes; they may not stand in for a
missing world change.
- Treat dialogue prose as presentation. Semantic intents, selected response
IDs, action commands, commitments, and their causal world events are the
authoritative contract.
- Treat quests as player-facing projections of real unresolved situations.
Never create quest-only enemies, items, damage, relationships, resources, or
completion facts.
- Route player and NPC interactions through the same authoritative action and
capability contracts. Presentation can suggest or submit a command, but the
simulation must revalidate it.
- Loaded visuals must not decide whether travel, work, growth, or distant
conflict completes. Presentation interpolates authoritative state and may
report local feasibility or obstruction.
- Every generated action, situation, helper, dialogue intent, or consequence
must expose a concise reason trace with the definition and causal fact IDs
that justified it.
- “Data-only content” means new combinations of existing typed predicates,
capabilities, effects, behavior profiles, and presentation cues. A genuinely
new mechanic adds one bounded reusable handler and tests; it does not add one
script per item, creature, quest, or conversation.
- Prefer typed Godot resources, composition, deterministic registries, and
explicit strategy handlers. Do not introduce a universal reflection DSL or
rewrite the project as a full ECS.
The intended extension path is therefore definition plus content pack, optional
presentation cue, and authored placement or simulation spawn. A berry, bear,
caravan, shortage, or conversation topic should reuse the same state, action,
event, and presentation contracts that existing content uses.
## Resource and target rules
Do not reintroduce abstract food/wood task-zone fallbacks.
Current resource gathering should use finite `ResourceNode` instances:
- food: berries, animal camps, village stock, future farms/crops;
- wood: trees, wood piles, future forestry contexts.
## Entity systems pattern
Build every resource, enemy, and animal as a reusable system with shared root
behaviour, not as a one-off object. Add a new type through data/definitions
plus a small behaviour or visual hook, reusing the root for movement,
presentation, serialization, and lifecycle:
- resources: immutable resource definitions plus authoritative
`ResourceStateRecord`; `ResourceNode` is the loaded provider and visual
binding;
- creatures: `CreatureVisual` is the shared navigation/death presentation root;
- enemies: `EnemyDefinition`/`SimulationEnemies` provide typed content,
`CombatantFactory` and `ConflictSystem` own authoritative instances and
lifecycle, and `HostileCombatant` presents them;
- animals: `AnimalDefinition`, `AnimalStateRecord`, `AnimalFactory`, and
`AnimalCareSystem` own content and lifecycle; `AnimalNode` is the loaded
interaction/navigation binding.
A new berry, tree, bear, bandit, boar, or goat should be mostly a definition
plus a bounded hook — never a new movement/combat/save system.
Resource additions should preserve:
- stable unique IDs;
- food/wood coverage;
- meaningful placement context;
- reachable interaction points;
- `safety_risk`, `comfort_distance`, and `discovery_priority` metadata;
- clear player interaction ranges so nearby storage/activity/resource targets
do not overlap accidentally.
Storage uses `StorageNode`. Rest, study, and patrol use `ActivitySite`. Do not
turn these back into generic marker zones.
## Vendored dependencies and Godot asset hygiene
- Treat `addons/dialogue_manager`, `addons/gut`, and `addons/terrain_3d` as
pinned vendor code. Do not reformat, refactor, or update them unless the task
explicitly owns that dependency.
- Preserve the complete cross-platform Terrain3D payload checked by the quality
gate. Do not replace a missing platform binary with a local-only artifact.
- Preserve `.uid` files, `class_name` locations, resource UIDs, and scene paths
when moving Godot scripts or scenes. Use `git mv` for intentional moves and
prove them with import plus headless startup.
- Never commit `.godot/`, `.venv/`, `logs/quality/`, or generated local editor
state. Do not hand-edit imported cache files to hide an error.
## Testing expectations
Add or update headless scenarios when a change affects:
- resource conservation;
- target selection or reservations;
- save/load or schema behavior;
- navigation/reachability assumptions;
- player/NPC parity;
- deterministic continuation;
- regional job ordering, rollback, or local/regional tick coordination;
- combined-manifest save/restore, migration, or atomic slot behavior;
- event causality, knowledge, situation, dialogue, or quest projections;
- UI/debug state that represents real simulation facts.
Keep tests deterministic. Prefer fixed seeds and stable IDs.
Any persistent-state change requires an explicit schema/migration decision,
exact validation, checksum and tamper coverage, rollback coverage, and a
deterministic continuation test.
## Documentation expectations
Update docs when the implemented behavior changes the roadmap, architecture, or
current contract. Keep updates local:
- `docs/DEVELOPER_INDEX.md` for the current feature map, extension routes, and
deliberately incomplete work;
- `docs/ARCHITECTURE_OVERVIEW.md` for ownership and dependency boundaries;
- `docs/PROJECT_CONTEXT.md` only when product intent or active constraints
change; dated implementation passages are historical context;
- `docs/LEARNING_ROADMAP.md` for next-item sequencing and milestone status;
- `docs/RESOURCE_NODE_MIGRATION.md` for resource-target migration status;
- `docs/SIMULATION_STATE_SCHEMA.md` for serialized state changes;
- `docs/SIMULATION_DEFINITIONS.md` for action/profession/ID contracts;
- `docs/ACTION_SYSTEM_ARCHITECTURE.md`, `docs/ECONOMIC_EVENTS.md`, and
`docs/REGIONAL_SIMULATION.md` for their focused runtime contracts;
- `docs/FEATURE_*.md` only when the corresponding implementation/extension
guide changes;
- `docs/BUILD_IN_PUBLIC_PLAN.md` for Jajce/demo/readability slices;
- `docs/decisions/` only for durable architectural decisions.
Do not duplicate full status tables across many docs. If docs and code differ,
trust code/tests first, then update docs.
## Git expectations
Preserve user changes. Check `git status --short --branch` before editing and
before committing, inspect the branch/upstream and recent history, and stage
only the files owned by the current slice. Do not use destructive cleanup
commands unless explicitly asked.
Every repository commit must use Conventional Commits with an imperative,
specific summary: `<type>(optional-scope): summary`. Common types are `feat`,
`fix`, `docs`, `test`, `refactor`, `perf`, `build`, `ci`, `chore`, and `merge`.
Examples:
- `feat: validate expanded resource discovery`
- `fix: stabilize godot 4.7 headless validation`
- `docs: capture agent workflow`
Before committing, review `git diff`, run `git diff --check` and the full
current-platform quality gate, then review `git diff --cached`. Validation is
explicit; do not assume a local hook ran it. One coherent vertical slice may
include its implementation, deterministic tests, required `.uid`/resource
files, and smallest necessary documentation update. Split unrelated fixes,
never stage pre-existing user work, and never use `--no-verify` to bypass a
repository gate.
Do not amend, rebase, drop, or fold user-owned commits unless explicitly asked.
Do not push implicitly. After committing, report the commit hash and the real
ahead/behind or remote-sync state.
## Product taste
The project is aiming for a readable, magical simulation garden that can grow
into a larger systemic game. Prefer honest visible cause-and-effect:
- NPCs should walk to real resources, storage, and activity sites.
- UI/debug overlays should explain actual simulation state.
- Beauty work should represent real state rather than fake activity.
- Each slice should leave the project easier to reason about than before.