docs: codify entity systems pattern and record combat extensions
This commit is contained in:
@@ -86,6 +86,25 @@ Current resource gathering should use finite `ResourceNode` instances:
|
|||||||
- food: berries, animal camps, village stock, future farms/crops;
|
- food: berries, animal camps, village stock, future farms/crops;
|
||||||
- wood: trees, wood piles, future forestry contexts.
|
- 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: `ResourceNode` + `ResourceStateRecord` (amount, yield, regrowth);
|
||||||
|
- creatures: `CreatureVisual` shared movement root (navigate to the
|
||||||
|
authoritative simulation position, report position, death), with per-type
|
||||||
|
visuals built from definitions;
|
||||||
|
- enemies: `EnemyDefinition` + `SimulationEnemies` registry driving combatant
|
||||||
|
spawns and hostile visuals;
|
||||||
|
- animals: `AnimalNode` + `AnimalStateRecord` following the same
|
||||||
|
follow-the-authoritative-position contract.
|
||||||
|
|
||||||
|
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:
|
Resource additions should preserve:
|
||||||
|
|
||||||
- stable unique IDs;
|
- stable unique IDs;
|
||||||
|
|||||||
@@ -79,6 +79,14 @@ would otherwise obscure that lifecycle:
|
|||||||
- `simulation/definitions/` owns stable IDs and immutable action/profession
|
- `simulation/definitions/` owns stable IDs and immutable action/profession
|
||||||
definitions.
|
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
|
`world/resource_nodes/LoadedResourceSpatialIndex.gd` is a focused disposable
|
||||||
acceleration structure owned by `ActiveWorldAdapter`. It indexes loaded
|
acceleration structure owned by `ActiveWorldAdapter`. It indexes loaded
|
||||||
interaction positions by action and horizontal cell, plus authoritative
|
interaction positions by action and horizontal cell, plus authoritative
|
||||||
|
|||||||
@@ -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 ->
|
attacks, the tribe war-motivation decision (tribe hunger + village surplus ->
|
||||||
desire; tribe strength vs NPC-derived village defence -> victory confidence;
|
desire; tribe strength vs NPC-derived village defence -> victory confidence;
|
||||||
watch one interval, then raid, plan, or abort), raid spawning, battle
|
watch one interval, then raid, plan, or abort), raid spawning, battle
|
||||||
resolution, and war consequences. Strong villagers automatically defend during
|
resolution, and war consequences. Strong villagers take a real `defend` duty
|
||||||
a raid. The player fights with an equipped sword and dash through a
|
action during raids. The player fights with an equipped sword and dash, has
|
||||||
`PlayerCombatController`, and `CombatPresentation` binds hostile raider/wolf
|
persisted health, and can be downed by wolves or raiders before recovering.
|
||||||
visuals to the authoritative combatants. Headless tests cover combat
|
Hostile raiders and wolves share a `CreatureVisual` movement root and are
|
||||||
determinism, wolf attacks, war motivation (raid only when confident, abort when
|
described by data-driven `EnemyDefinition`s, so the next bear, bandit, or boar
|
||||||
the village is strong), raid-to-resolution chains, player kills, and
|
is a definition plus a visual hook rather than a new movement or combat system.
|
||||||
save/restore.
|
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:
|
Recently completed:
|
||||||
|
|
||||||
|
|||||||
@@ -245,11 +245,15 @@ plugin content, not game architecture.
|
|||||||
- Combat is playable: the player swings an equipped sword (left click) and
|
- Combat is playable: the player swings an equipped sword (left click) and
|
||||||
dashes (Shift) with cooldowns; hits land against hostile raiders and wolves
|
dashes (Shift) with cooldowns; hits land against hostile raiders and wolves
|
||||||
through a deterministic simulation `ConflictSystem`. Wolves hunt hungry
|
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
|
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,
|
strength (strong NPCs who can swap to defence) and judges victory unlikely,
|
||||||
in which case it plans or aborts. Strong villagers automatically defend
|
in which case it plans or aborts. During a raid, strong villagers and guards
|
||||||
during a raid.
|
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.
|
- `Escape` releases captured mouse input.
|
||||||
|
|
||||||
### Village simulation
|
### Village simulation
|
||||||
|
|||||||
@@ -24,8 +24,13 @@ Each executable action definition contains:
|
|||||||
- optional completion-cost resource ID and amount.
|
- optional completion-cost resource ID and amount.
|
||||||
|
|
||||||
The current actions are gather food, gather wood, feed animal, deposit food,
|
The current actions are gather food, gather wood, feed animal, deposit food,
|
||||||
deposit wood, withdraw food, patrol, study, eat, rest, sleep, and wander. Idle
|
deposit wood, withdraw food, patrol, study, eat, rest, sleep, wander, and
|
||||||
and dead are stable state sentinels, not executable action definitions.
|
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
|
SimNPC reads default duration and preferred-profession metadata from these
|
||||||
definitions. WorldViewManager reads target type and resource-action metadata
|
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`,
|
`combatant_hurt`, `combatant_killed`, `raid_started`, `war_resolved`,
|
||||||
`war_aborted`, and `wolf_hunt`.
|
`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
|
## Validation
|
||||||
|
|
||||||
The registry rejects:
|
The registry rejects:
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ simulation. The current world schema is v14 and captures:
|
|||||||
- opportunity records with stable type/status, interested NPC, trigger event,
|
- opportunity records with stable type/status, interested NPC, trigger event,
|
||||||
target storage/resource/amount, exact later resolution event identity, or a
|
target storage/resource/amount, exact later resolution event identity, or a
|
||||||
deterministic invalidation reason and close tick;
|
deterministic invalidation reason and close tick;
|
||||||
- a player record holding the player-citizen's hunger, energy, and carried
|
- a player record holding the player-citizen's hunger, energy, health,
|
||||||
inventory. The player's world position remains presentation-owned and is
|
downed state, and carried inventory. The player's world position remains
|
||||||
intentionally not serialized;
|
presentation-owned and is intentionally not serialized;
|
||||||
- combatant records (health, weapon, faction, position, hostility) for NPC
|
- combatant records (health, weapon, faction, position, hostility) for NPC
|
||||||
defenders and standalone raiders/wolves;
|
defenders and standalone raiders/wolves;
|
||||||
- faction records (food, warriors, aggression, morale, stance, war plan) for
|
- 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
|
arbitrary world floats round-trip through JSON without breaking deterministic
|
||||||
continuation checksums.
|
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
|
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
|
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
|
whose active feed task targets that exact animal. Every `animal_fed` event
|
||||||
|
|||||||
Reference in New Issue
Block a user