Pathfinding Route Modes (Fastest vs Direct)
1. Summary
Shared grid A* (flatland-pathfinding) serves player auto-nav, workers, schedule NPCs, and wildlife. Two route modes:
| Mode | Behavior |
|---|---|
| Fastest (default) | Minimize travel time (true ETA) using the same terrain speed multipliers that move actors |
| Direct | Minimize geometric path length on any walkable cell — no terrain preference |
Blocked / impassable cells stay blocked in both modes (buildings, props, Rock, DeepWater, etc.).
2. Decisions (locked)
| Topic | Decision |
|---|---|
| Default | Fastest |
| Cost fidelity | True ETA from terrain-kinds.yaml move_speed_mult (admin-editable) |
| Designer “feel” | Edit World → Terrain kinds → Movement (move_speed_mult); pathfinding follows after publish |
| Direct walkability | Anything not blocked is walkable — bog / shallow water / slow tiles use the same uniform walkable cost as grass |
| Direct meaning | Shortest walkable geometric route only — no soft avoid |
| Player setting | Persist auto_nav_mode: fastest | direct on ClientConfig (client.json); default fastest |
| Server agents | Workers, NPCs, wildlife, chase — always Fastest (player toggle does not apply) |
3. Terrain costs
3.1 Source of truth
Sim already applies per-kind modifiers in TerrainKind::modifiers() → (stamina_drain_mult, move_speed_mult). Pathfinding must not keep a separate hand-tuned cost table that drifts from those speeds.
Canonical Fastest cost (integer grid units):
cost(kind) = round(BASE / move_speed_mult(kind))
with BASE = grass baseline (today’s DEFAULT_COST 10), and impassable kinds (Rock, DeepWater) remaining non-walkable (u16::MAX / blocked).
Direct mode: every walkable cell uses BASE (uniform).
3.2 Feel without lying
Raising Road move_speed_mult makes the player actually faster on roads and makes Fastest prefer roads in proportion.
Corridor stickiness: when both path endpoints resolve to Road or Trail, Fastest multiplies off-path cell costs (×3) so A* stays on the pavement instead of cutting grassy corners. Direct is unchanged. Escape onto non-path still works if the corridor is blocked.
Building pads: nav blocking for buildings matches runtime collision (PLAYER_RADIUS only). Extra clearance must not seal road cells the player can still walk (that forced grass detours beside storage halls).
3.3 Admissible heuristic
A* octile h must scale by the minimum walkable Fastest cost (fastest terrain, e.g. Road) so paths stay optimal under variable costs.
4. API surface
pub enum PathMode {
Fastest,
Direct,
}
// find_path* / PathSession::plan / replan take PathMode
// AutoNavigator reads ClientConfig → PathMode
Call sites:
| Caller | Mode |
|---|---|
AutoNavigator (TUI + gfx click / map target) |
From ClientConfig |
| Workers / schedule NPC / wildlife / combat path | PathMode::Fastest |
5. Client UX
- Field:
ClientConfig.auto_nav_mode("fastest"|"direct", default fastest) - Settings: gfx Connection / play options (F2 or adjacent) — radio or toggle
- Optional later: keybind to flip mid-route and replan
- Changing mode while auto-nav is active → replan with the new mode
- Client version bump when shipping (client-path change)
No content-admin / YAML surface — this is a client preference, not authored content.
6. Implementation checklist
PathModeincrates/pathfinding— wire throughfind_path*, grid paint,PathSession✅- Derive costs from shared speed multipliers (or one shared table used by sim + pathfinding) ✅
- Fix heuristic for min walkable cost under Fastest ✅
ClientConfig+ AutoNavigator + gfx settings UI ✅- Server call sites — pass
PathMode::Fastestexplicitly ✅ - Tests — Fastest detours onto road when ETA wins; Direct crosses slow terrain when shorter; impassable still blocked ✅
- Docs — this plan + short cross-link from
11-entities-attributes-and-movement.html✅
7. Out of scope
- Per-NPC authored path mode overrides
- Stamina-minimizing routes (time-only for Fastest v1)
- Hierarchical / long-range road graphs beyond cell A*
- Native editor / content-admin map tools for the toggle