Add Brain enum with hunting foxes; move the A* into the sim
NPC strategy is now a Brain field on the entity (Idle, Wander, Hunt(Prey)) that Sim::think matches on, so behavior is data independent of species. Hunt follows the first step of an A* route to the nearest prey in sight, replanned every window; the pathfinder moves from game/ to sim/ for that. A greedy step-toward-target was tried first and oscillated at walls. Bumps between the same species no longer fight, and six foxes join the hens. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+18
-2
@@ -47,7 +47,7 @@ crate's `tick`/`set_action` interface is the seam a server could be wrapped arou
|
||||
(trees/rocks) and id 0 (empty / the invisible world border). A proper tile-data file
|
||||
format replaces this table later.
|
||||
- [x] Click-to-move: framebuffer click → world tile, A* over the world
|
||||
(`game/src/game/pathfind.rs`, 8-connected, Chebyshev heuristic), route fed into the
|
||||
(`sim/src/pathfind.rs`, 8-connected, Chebyshev heuristic), route fed into the
|
||||
sim one step per movement window. Keyboard input cancels the route; each step is
|
||||
re-validated at scheduling time and a blocked step replans toward the persistent
|
||||
goal. Click-and-hold steers continuously: while the button is held the route keeps
|
||||
@@ -74,7 +74,17 @@ crate's `tick`/`set_action` interface is the seam a server could be wrapped arou
|
||||
drained by the game with `Sim::take_events` after every window — which is the
|
||||
seam for sound, message log, camera shake, spawns. Player death quits for now.
|
||||
Click-to-move treats an occupied goal as a target (route ends in a bump) but
|
||||
walks around entities in the way; keyboard steps always bump.
|
||||
walks around entities in the way; keyboard steps always bump. A bump into the
|
||||
same `type_id` (species) is a refused move, not a fight.
|
||||
- [x] NPC brains: `Brain { Idle, Wander, Hunt(Prey) }` as a field on `Entity` — strategy
|
||||
is data, independent of species and swappable at runtime. `Sim::think` matches on
|
||||
it. `Hunt` takes the first step of an A* route (the pathfinder moved into `sim/`
|
||||
for this) to the nearest prey within `SIGHT_RANGE` (8), replanned every window;
|
||||
out of sight or unreachable it wanders. A greedy step-toward-target was tried
|
||||
first and oscillated at any wall between hunter and prey. Six foxes
|
||||
(`Hunt(Kind(hen))`, 8 hp / 2 dmg) clear 150 wandering hens off `map_test` in
|
||||
about a minute; `cargo test -p game population -- --ignored --nocapture` watches
|
||||
it headlessly.
|
||||
- [x] Entity interpolation: per-id lerp table (`EntityLerp` in `game.rs`) — previous/current
|
||||
tile plus a clock, rendered as a pixel lerp over one movement interval. Jumps of
|
||||
more than one tile (Chebyshev) snap. Purely cosmetic; game logic keeps using the
|
||||
@@ -117,6 +127,12 @@ budget model goes once there are enough NPCs to need it. The action-point model
|
||||
|
||||
- [x] `EntityKind::Npc`, `Sim::think` scheduling intents through the same intent table
|
||||
- [x] Bump-to-attack, death, `Event` queue
|
||||
- [x] `Brain` enum, `Hunt` via A*
|
||||
- A* per hunter per window is fine for six foxes; the think budget below becomes
|
||||
necessary once hunters number in the dozens (or `hunt` caches its route and replans
|
||||
only when the target moved).
|
||||
- Hunters don't defend themselves: a fox bitten by a hen does not retaliate unless
|
||||
the hen happens to be its nearest prey. `Brain::Hunt` could switch target on `Attacked`.
|
||||
- Stats beyond `hp`/`attack` (defense, speed) as plain fields; a `Stats` substruct once
|
||||
they crowd `Entity`. No ECS until entities actually differ in *which* components they
|
||||
carry — see the discussion of 2026-09-19.
|
||||
|
||||
Reference in New Issue
Block a user