feat(ecology): natural nodes are physical for movement (#255) #257

Merged
panda merged 1 commit from feat/ecology-nodes-physical into main 2026-08-02 15:01:39 +02:00
Collaborator

Summary

The movement half of #255 (epic #250 / ecology): natural nodes are now physical. A BlocksWalk node — a mature tree, a rock outcrop — is impassable to players and creatures on the authoritative server; a walkable-stage node (an uprooted pine, a depleted rock) stays passable.

  • NaturalNodeRegistry.BlocksWalkAt(cell) — does a node block walk at this cell right now (from its current stage).
  • MovementSystem.ApplyPending and CreatureSystem.Step gain a NaturalNodeRegistry and reject a step onto a blocked cell, alongside the map's own walkability + mobile occupancy; World.Tick passes _nodes to both (World.cs stays delegation-only).
  • Server-authoritative: a blocked player move increments IllegalMovesRejected (a modified-client tell, like an obstacle) — a modified client can't walk through a tree.

Closes the walk-through-trees desync flagged before F5. Two remainders, tracked (not blocking):

  • Line-of-sight node-blocking is the other half of #255HasLineOfSight lives in Shared/TileMapRules and can't see the GameServer node registry; a follow-up.
  • Cosmetic: GM/scripted placement (ResolveStart/Teleport) isn't node-checked, so a scripted spawn could visually overlap a tree — not a correctness bug (BlocksWalkAt only gates a move's target, never the actor's own cell). Noted on #255.

How it was tested

  • 4 unit tests against World (WorldNodeCollisionTests): a player and a creature each cannot step onto a BlocksWalk (mature) node, and each can step onto a walkable-stage node. (The tests use terminal stages so a node's block state doesn't drift with the wall clock — a non-terminal stage planted at the epoch would grow to a blocking stage by now; documented in the test.)
  • Whole solution builds 0 warnings; CSharpier 510 files clean; check-doc-refs resolves; full dotnet test green (GameServer.Tests 344).
  • Reviewed: ready to merge, no Critical/Important (two Minor: stale comments — fixed; the placement note above).

Screenshots: N/A — server-side movement, no visible surface (nodes render in F5).

Checklist

  • just lint (0 warnings) · [x] just test green (whole solution) · [x] whole build
  • check-doc-refs green · [x] server-authoritative (blocked move = IllegalRejected)
  • World.cs delegation-only; single-threaded, no lock
  • Tests added
  • Advances #255 (epic #250)
## Summary The **movement half of #255** (epic #250 / ecology): natural nodes are now **physical**. A `BlocksWalk` node — a mature tree, a rock outcrop — is **impassable to players and creatures** on the authoritative server; a walkable-stage node (an uprooted pine, a depleted rock) stays passable. - `NaturalNodeRegistry.BlocksWalkAt(cell)` — does a node block walk at this cell right now (from its current stage). - `MovementSystem.ApplyPending` and `CreatureSystem.Step` gain a `NaturalNodeRegistry` and reject a step onto a blocked cell, **alongside** the map's own walkability + mobile occupancy; `World.Tick` passes `_nodes` to both (`World.cs` stays delegation-only). - **Server-authoritative:** a blocked player move increments `IllegalMovesRejected` (a modified-client tell, like an obstacle) — a modified client can't walk through a tree. **Closes the walk-through-trees desync flagged before F5.** Two remainders, tracked (not blocking): - **Line-of-sight** node-blocking is the *other half of #255* — `HasLineOfSight` lives in `Shared/TileMapRules` and can't see the GameServer node registry; a follow-up. - Cosmetic: GM/scripted **placement** (`ResolveStart`/`Teleport`) isn't node-checked, so a scripted spawn could visually overlap a tree — **not** a correctness bug (`BlocksWalkAt` only gates a move's *target*, never the actor's own cell). Noted on #255. ## How it was tested - **4 unit tests** against `World` (`WorldNodeCollisionTests`): a player and a creature each cannot step onto a `BlocksWalk` (mature) node, and each can step onto a walkable-stage node. (The tests use **terminal** stages so a node's block state doesn't drift with the wall clock — a non-terminal stage planted at the epoch would grow to a blocking stage by now; documented in the test.) - Whole solution **builds 0 warnings**; CSharpier **510 files** clean; `check-doc-refs` resolves; **full `dotnet test` green** (GameServer.Tests 344). - Reviewed: **ready to merge**, no Critical/Important (two Minor: stale comments — fixed; the placement note above). **Screenshots:** N/A — server-side movement, no visible surface (nodes render in F5). ## Checklist - [x] `just lint` (0 warnings) · [x] `just test` green (whole solution) · [x] whole build - [x] `check-doc-refs` green · [x] server-authoritative (blocked move = IllegalRejected) - [x] `World.cs` delegation-only; single-threaded, no lock - [x] Tests added - [x] Advances #255 (epic #250)
feat(ecology): natural nodes are physical for movement — players + creatures can't walk through a BlocksWalk node (#255)
All checks were successful
ci / Lua content lint (pull_request) Successful in 10s
ci / Lint & Test (pull_request) Successful in 4m53s
a7bf00bcfe
MovementSystem and CreatureSystem reject a step onto a cell whose node blocks walk
(NaturalNodeRegistry.BlocksWalkAt, from the node's current stage), alongside the map's
own walkability. A walkable-stage node stays passable. Node-blocked line-of-sight
(HasLineOfSight lives in Shared, can't see the GameServer registry) remains — #255 follow-up.
panda merged commit b5a8d1b2ea into main 2026-08-02 15:01:39 +02:00
panda deleted branch feat/ecology-nodes-physical 2026-08-02 15:01:39 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marco/IsoMmo!257
No description provided.