Skip to content

Pathfinder graph hardcodes plane=0; upper floors and many undergrounds unreachable #8

@iamacoffeepot

Description

@iamacoffeepot

Summary

Storage supports all 4 planes, but every computed graph layer (blobs, ports, transits, crossings, map_link blob ids, gate links) hardcodes WHERE plane = 0. As a result, anything on plane ≥ 1 is invisible to find_path — Cam Torum, Lassar Undercity, every wizards' tower / castle upper floor, etc.

This was masked until now because the (deleted) compute_walkability.py script wrote 8344 phantom walkable-typed map_links between Voronoi-neighbor cells. Those were the only edges that ever bridged into the upper-plane graph nodes, and they bridged in places where no real connection exists — e.g. routing Civitas → Cam Torum via "walkable" hops between three isolated underground blobs (30709 → 32202 → 16828) that have no walkable tile path between them at all.

Reality check

Confirmed in-game: Cam Torum proper is at (1439, 9599, plane=1). The surface entrance gate is object 51375 at (1435, 3129, plane=0). So even the canonical "walk through the gate" route requires a plane=0 → plane=1 transition, which the current schema can't even express on a map_link.

Inventory

Has plane support (✓):

  • map_squares table — collision/water/color rasters dumped for all 4 planes
  • MapSquare API in src/ragger/map.pyplane parameter throughout
  • object_locations table — plane column populated

Hardcoded to plane=0 (✗):

  • scripts/pipeline/compute_blobs.py:322,419
  • scripts/pipeline/compute_ports.py:133
  • scripts/pipeline/compute_port_crossings.py:79
  • scripts/pipeline/compute_port_transits.py:141
  • scripts/pipeline/compute_map_link_blobs.py:67
  • scripts/pipeline/compute_gate_links.py:62
  • scripts/pipeline/fetch_ground_items.py:35

Schema gaps (✗):

  • blobs table: (id, location_id, tile_count) — no plane
  • ports table: no plane column
  • map_links table: has src_x/y and dst_x/y but no src_plane / dst_plane. Cross-plane teleports (ladders, stairs, gates that warp you up/down a level) cannot be represented honestly.
  • find_path PathStep is 2D; A* node keys like ("port", pid) have no plane component.

Spawn counts give a sense of scale

object_locations by plane:
  plane 0 → 56708 spawns
  plane 1 →  9784
  plane 2 →  5050
  plane 3 →  3309

So ~25% of interactive objects sit on a plane the graph can't reach.

Suggested ordering

  1. Schema migration: add plane to blobs, ports; add src_plane, dst_plane to map_links. Backfill existing rows with 0.
  2. De-hardcode the six compute_* scripts to iterate planes 0..3 (or all planes present in map_squares of type collision).
  3. Update find_path to key nodes by (kind, id, plane) and propagate plane through PathStep. Heuristic stays admissible since plane shifts are zero-cost.
  4. Update MapLink.departing / arriving and other APIs to round-trip plane.
  5. Backfill plane on existing portal-type map_links (entrance/exit/teleport/charter/etc.) by reading the cache CS2 destination scripts where available, or by inferring from object spawn planes near the wiki coord.

Out of scope but adjacent

  • Cleaning up the 8344 stale Voronoi walkable map_links from the old compute_walkability.py (separate issue).
  • Building the surface↔underground / inter-floor pairing pipeline that uses object_locations + the plane-aware schema to discover entrance / ladder pairs automatically.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions