docs: codify entity systems pattern and record combat extensions

This commit is contained in:
Rijad Zuzo
2026-08-12 00:19:48 +02:00
parent 661d53f31a
commit cd29da95e0
6 changed files with 69 additions and 15 deletions
+8
View File
@@ -79,6 +79,14 @@ would otherwise obscure that lifecycle:
- `simulation/definitions/` owns stable IDs and immutable action/profession
definitions.
`world/creatures/creature_visual.gd` is the shared root for creature
presentation: any `CreatureVisual` follows a simulation-owned position through
the navigation mesh, reports position changes, and plays a shared death
collapse. `HostileCombatant` extends it and builds its body from an
`EnemyDefinition`; `NpcVisual` and `AnimalNode` already follow the same
follow-the-authoritative-position contract, so future creatures (bears, boars,
archers) add a definition and a visual hook instead of a new movement system.
`world/resource_nodes/LoadedResourceSpatialIndex.gd` is a focused disposable
acceleration structure owned by `ActiveWorldAdapter`. It indexes loaded
interaction positions by action and horizontal cell, plus authoritative
+9 -7
View File
@@ -1005,13 +1005,15 @@ factions, hostility), the village and hill-tribe faction records, wolf hunger
attacks, the tribe war-motivation decision (tribe hunger + village surplus ->
desire; tribe strength vs NPC-derived village defence -> victory confidence;
watch one interval, then raid, plan, or abort), raid spawning, battle
resolution, and war consequences. Strong villagers automatically defend during
a raid. The player fights with an equipped sword and dash through a
`PlayerCombatController`, and `CombatPresentation` binds hostile raider/wolf
visuals to the authoritative combatants. Headless tests cover combat
determinism, wolf attacks, war motivation (raid only when confident, abort when
the village is strong), raid-to-resolution chains, player kills, and
save/restore.
resolution, and war consequences. Strong villagers take a real `defend` duty
action during raids. The player fights with an equipped sword and dash, has
persisted health, and can be downed by wolves or raiders before recovering.
Hostile raiders and wolves share a `CreatureVisual` movement root and are
described by data-driven `EnemyDefinition`s, so the next bear, bandit, or boar
is a definition plus a visual hook rather than a new movement or combat system.
Headless tests cover combat determinism, wolf attacks, enemy definitions,
player downing/recovery, defend duty, war motivation, raid-to-resolution
chains, player kills, and save/restore.
Recently completed:
+7 -3
View File
@@ -245,11 +245,15 @@ plugin content, not game architecture.
- Combat is playable: the player swings an equipped sword (left click) and
dashes (Shift) with cooldowns; hits land against hostile raiders and wolves
through a deterministic simulation `ConflictSystem`. Wolves hunt hungry
nearby villagers, and the hill tribe raids the village when it is short of
nearby villagers and the player, and can wound and even down the player
(brief forced recovery). The hill tribe raids the village when it is short of
food while the village holds plenty — unless the tribe reads the village's
strength (strong NPCs who can swap to defence) and judges victory unlikely,
in which case it plans or aborts. Strong villagers automatically defend
during a raid.
in which case it plans or aborts. During a raid, strong villagers and guards
take a real `defend` duty action and rally at the guard post. Hostiles follow
the navigation mesh through a shared `CreatureVisual` root, and enemies are
data-driven `EnemyDefinition`s so new types add with a definition plus a
visual hook.
- `Escape` releases captured mouse input.
### Village simulation
+16 -2
View File
@@ -24,8 +24,13 @@ Each executable action definition contains:
- optional completion-cost resource ID and amount.
The current actions are gather food, gather wood, feed animal, deposit food,
deposit wood, withdraw food, patrol, study, eat, rest, sleep, and wander. Idle
and dead are stable state sentinels, not executable action definitions.
deposit wood, withdraw food, patrol, study, eat, rest, sleep, wander, and
defend. Idle and dead are stable state sentinels, not executable action
definitions.
`defend` is the raid-response action: eligible strong villagers and guards
prefer it during an active raid, travel to the guard post, and raise village
safety while they work. Patrol activity sites accept it as a rally point.
SimNPC reads default duration and preferred-profession metadata from these
definitions. WorldViewManager reads target type and resource-action metadata
@@ -104,6 +109,15 @@ Combat, raid, and war narrative facts use the stable event types
`combatant_hurt`, `combatant_killed`, `raid_started`, `war_resolved`,
`war_aborted`, and `wolf_hunt`.
## Enemy vocabulary
`EnemyDefinition` is the data contract for hostile creatures and
`SimulationEnemies` is the current registry. Each enemy carries a `kind`
(raider/wolf), equipped weapon, health, move speed, body/accent colors, and a
visual scale, so a new bear, bandit, or boar is mostly one definition plus a
small `_build_*` visual hook on the shared `CreatureVisual` root. The current
enemies are `enemy_raider` (sword) and `enemy_wolf` (claw).
## Validation
The registry rejects:
+10 -3
View File
@@ -26,9 +26,9 @@ simulation. The current world schema is v14 and captures:
- 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;
- 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;
- a player record holding the player-citizen's hunger, energy, health,
downed state, and carried inventory. The player's world position remains
presentation-owned and is intentionally not serialized;
- combatant records (health, weapon, faction, position, hostility) for NPC
defenders and standalone raiders/wolves;
- faction records (food, warriors, aggression, morale, stance, war plan) for
@@ -248,6 +248,13 @@ to a binary-exact grid and faction food to a binary-exact step so that
arbitrary world floats round-trip through JSON without breaking deterministic
continuation checksums.
`PlayerStateRecord` v2 adds `health`, `max_health`, `downed`, and
`downed_ticks` so wolves and raiders can wound and down the player, with a
brief forced recovery that restores a fighting baseline. Nested v1 player
records migrate to full health and standing. The player combatant used by the
conflict system is derived state and is never serialized; hostile attacks
reduce the authoritative player health through the ordered event stream.
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