fix(gameserver): marsh move-cost parity — charge creatures the entry step (#182) #204

Merged
marco merged 1 commit from fix/marsh-creature-parity into main 2026-07-25 18:01:47 +02:00
Collaborator

Summary

Fixes #182: marsh (and any MoveCost > 1 terrain) was charged asymmetrically to creatures vs players. A grounded creature got one free fast step when stepping from dry ground into slow terrain — only slowing once already standing in it — so a chasing creature gained ground on a fleeing player at every slow-terrain edge, contradicting CreatureSystem's own "no mob-favoured trap" comment.

Cause

MovementSystem (players) gates on MoveCostTicks(cooldown, from, target) = Max(cost(from), cost(into)), so the entry step is charged. CreatureSystem gated on MoveCostTicks(base, creature.Position, creature.Position) = the current tile only — it charged leaving/standing but never entering.

Fix

Kept the eligibility gate on the current tile (the leaving cost) and added the entry cost in the Move case, once the AI's target tile is known: MoveCostTicks(baseCadence, creature.Position, target). This is exactly the player's Max(from, into) rule.

Deliberately did not move Ai.Think before the gate: Think has side effects (advances the wander RNG, clears CombatTarget), so calling it more often would change behaviour and break the seeded tests. The two-phase gate keeps Think's call frequency unchanged, and on uniform terrain the entry cost equals the outer gate — so nothing changes there (the existing marsh/flying tests stay green). Flying kinds (IgnoresTerrainMoveCost) remain exempt.

How it was tested

  • New unit test GroundedCreature_EnteringMarsh_IsChargedTheEntryStep against World with a deterministic east-walking creature: the grass→marsh entry step now costs the marsh cadence, not the grass one. Verified red before the fix (entering marsh (2) should cost more than a grass step (2)), green after.
  • Existing GroundedCreature_MovesLessInMarshThanOnGrass and FlyingCreature_IsNotSlowedByMarsh unchanged and green.
  • Whole solution builds 0 warnings; all tests green (GameServer 233).

Closes #182.

## Summary Fixes #182: marsh (and any `MoveCost > 1` terrain) was charged **asymmetrically** to creatures vs players. A grounded creature got one *free* fast step when stepping from dry ground into slow terrain — only slowing once already standing in it — so a chasing creature gained ground on a fleeing player at every slow-terrain edge, contradicting `CreatureSystem`'s own "no mob-favoured trap" comment. ## Cause `MovementSystem` (players) gates on `MoveCostTicks(cooldown, from, target)` = `Max(cost(from), cost(into))`, so the **entry** step is charged. `CreatureSystem` gated on `MoveCostTicks(base, creature.Position, creature.Position)` = the current tile only — it charged *leaving/standing* but never *entering*. ## Fix Kept the eligibility gate on the current tile (the leaving cost) and added the entry cost in the `Move` case, once the AI's target tile is known: `MoveCostTicks(baseCadence, creature.Position, target)`. This is exactly the player's `Max(from, into)` rule. Deliberately did **not** move `Ai.Think` before the gate: `Think` has side effects (advances the wander RNG, clears `CombatTarget`), so calling it more often would change behaviour and break the seeded tests. The two-phase gate keeps `Think`'s call frequency unchanged, and on **uniform** terrain the entry cost equals the outer gate — so nothing changes there (the existing marsh/flying tests stay green). Flying kinds (`IgnoresTerrainMoveCost`) remain exempt. ## How it was tested - New unit test `GroundedCreature_EnteringMarsh_IsChargedTheEntryStep` against `World` with a deterministic east-walking creature: the grass→marsh **entry** step now costs the marsh cadence, not the grass one. **Verified red before the fix** (`entering marsh (2) should cost more than a grass step (2)`), green after. - Existing `GroundedCreature_MovesLessInMarshThanOnGrass` and `FlyingCreature_IsNotSlowedByMarsh` unchanged and green. - Whole solution builds 0 warnings; all tests green (GameServer 233). Closes #182.
fix(gameserver): charge creatures the marsh entry step — move-cost parity with players (#182)
All checks were successful
ci / Lint & Test (pull_request) Successful in 1m48s
74781815b0
marco approved these changes 2026-07-25 18:01:45 +02:00
marco left a comment

Correct, minimal parity fix — Move now gated on Max(from,into) exactly like MovementSystem; two-phase gate preserves Think frequency on uniform terrain; red-before/green-after test. CI green.

Correct, minimal parity fix — Move now gated on Max(from,into) exactly like MovementSystem; two-phase gate preserves Think frequency on uniform terrain; red-before/green-after test. CI green.
marco merged commit 5313140de6 into main 2026-07-25 18:01:47 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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!204
No description provided.