# Radar/Map Display Drift Audit — binary vs port vs content (2026-08-14) **What this is:** the AI-facing ledger of the radar/map subsystem audit (3-agent, full reports preserved at `scratchpad/night17/radar_audit_{bin,port,content}.txt`; ~800k tokens of reads). Trigger: #49 (arena walls missing from radar) + the field report "many map items aren't showing on radar, like map boundaries." Companion fix: the static world feed, commit `c2193e2` (#49 CLOSED, operator-verified). ## The architecture, as the machine built it [T1 unless noted] - ONE radar picture for every map/mech: the 480×640 portrait `BTSEC1.PCX` + `BTSEC1OV.PCX` baked art (tick ring + crosshair — **no range rings exist**), with the live `map(` widget in the (366,367) scope rect at (58,229). There is **no per-map radar art and no map page** — the ModeMapping bit is the weapon-button CONFIG session, not cartography (aliased ModeNonConfig [T0]). - **Entity membership** (@004cbfa0, the interest feed): an entity reaches the scope iff (a) a type-0x12 GaugeImageStream pip exists for its resourceID AND (b) Mover-derived → moving list, else Terrain-GRAPH-derived → static list. The derivation graph parents UnscalableTerrain (0x2A), CulturalIcon (0x5E) and Landmark (0x56) onto Terrain [T0 TERRAIN.cpp:183, CULTURAL.cpp:27] even though their C++ bases differ. - **Draw order** (@004c22c4): wedge → static pips → moving pips → name labels, inside a stroke recorder (erase = replay last frame in bg color). - **DrawStatic** (@004c25b4): each in-capability static's pip drawn with the entity's FULL transform — walls/buttes/hills/ridges/buildings/trees rendered as world-rotated, metre-scaled staticColor(3) outlines. 110 authored GIMs ship (wall1-3, aw01-05, ab*/ar*/bld*, buttea-e, hillg/dhillg 652-byte contours, sr1e/n/s/w polar rails, tree, dish, …). - **DrawMoving** (@004c2788): every mover except the operator, color 7, target boxed (+4px, hotbox color 1). NO self-blip; NO pipless fallback (every shipped mech has a pip). - **DrawNames** (@004c28c4): ≤16 callsign labels (64×16 egg rasters via playerBitmapIndex); the target's label BLINKS at frame rate. - **Zoom**: 6-step exponential, RadarRange = 250·2^level (250…8000 m scope width), SLEWED smoothly; SCALE numeric shows it live. Capability radius = RadarPercent × 4000 m — radar damage shrinks detection (#105/#121 pending). - **Wedge**: hardcoded π/8 half-angle (45° total); the config's "180" param only sizes the DEAD shadow table. (Manual says "60° field of vision" — print-vs-code drift, the code wins for 4.10 [T1 vs manual].) ## Authenticity verdicts the port must respect 1. **The pure map boundary was INVISIBLE on the shipped machine.** Every outdoor map places one `wall10k` (collision solids only, ±4100 m ring — no pip, no video model). Players saw a "boundary" only where visible wall/ridge ENTITIES formed the perimeter (arena aw*, polar sr1* rails, rav buttes). Do NOT invent a boundary rectangle. (ExistanceBox type-26 extents: arena ±700, rav ±1000, others ±7000 — available if a design call ever wants one.) 2. **BuildRadarShadow (@004c228c) compiled EMPTY** — radar occlusion shading was cut before ship. The port's empty body is faithful. 3. **Authored pip omissions are design**: floors/sky, wall10k, overhead butte tops (butteeu), walkways/banners, snow banks have NO pips on purpose. Never force-draw them. 4. **Missile pips are authored dead content**: lrm/srm/strk/nrk GIMs ship, but Projectile/Missile are Entity-derived in the graph — they fail both class tests and never listed on the machine either. 5. **Landmark labels + DropZone blips: dormant/absent** (zero Landmark instances; DropZones carry rid −1). ## The #49 root cause + fix (2026-08-14, c2193e2) The port dropped the engine's per-entity interest feed and replaced it with `GaugeRenderer::RebuildEntityGrid` — which iterated DYNAMIC masters/replicants only. The 1008 statically-registered UnscalableTerrain instances (every wall, butte, hill, ridge, big building) never entered the static grid; DrawStatic (fully transcribed and working) had nothing to draw. Dynamic-registering CulturalIcon props (e.g. grass's 313 trees) were the only statics that ever showed. Fix: a third RebuildEntityGrid pass files non-dynamic Terrain-graph entities from `HostManager::AllEntityIterator`; pipless ones no-op at the pip lookup exactly as on the machine. Receipts: `[map-grid] worldStatics=` census + capped per-static `[map] static ent/cls/rid/pip/dsq` dump (BT_MAP_LOG). Benched grass (hill cls=42 rid=2190 pip=1 drawing + trees) and arena1 (126 world statics, aw walls rid 1918/1915 drawing, unpipped props skipped); operator-verified visually on arena1. ## Known port deviations (deliberate, inventoried) - Three visible-radius culls (DrawStatic/DrawMoving/DrawNames) drop contacts between scope radius and capability radius instead of the binary's draw-and-clip — justified by the shared gauge surface (out-of-port draws land on neighbors). Revisit only with a real GraphicsView clip. - Cross-blip fallback for pipless movers (dev content insurance; dead in the field — every shipped mech has a pip). - Dead-mover (state 2/9) radar drop: the wreck-blip removal. The binary's uninteresting-notification presumably did the same [T4 — unverified whether a pod wreck kept its blip]. - Per-frame O(all-entities) rebuild vs the authentic event-driven feed — acceptable at shipped populations; restoring the notify feed retires it. ## Stale notes corrected by this audit - `mech.cpp` "SetTargetRange is stubbed" — FALSE since the zoom work (btstubs.cpp body + the mapper slew); comment swept 2026-08-14. - `btl4rdr.cpp` header "Make has no exported caller" — stale; @004c1b4c IS in the 2026-08-06 re-export. - `docs/GAUGE_COMPOSITE.md` row 24 "cross-blip stand-in" — stale; pips are the live path since dd27238. ## Open follow-ups - ERA QUESTION (for the group): what did the ARENA EDGE look like on the pod's scope — just the wall outlines, or anything more? (Guards against inventing a boundary ring; the code says wall outlines only.) - #105/#121: RadarPercent is pinned 1.0 until sensor damage lands — the capability-shrink lane is authored and waiting. - The 45°-wedge vs the manual's "60° field of vision" — flag to testers comparing against memory; the 4.10 code hardcodes π/8·2. - Overlay-plane compositing into the dev sec cell (SECTOR/SCALE readouts) — existing polish item, unchanged.