Gitea #43: the Comm pilot list now shows EVERY pilot -- three stacked fixes
1. Roster count used the binary's raw entry+0x29&0x40 read on our compiled objects (databinding trap) -> garbage latched pilotCount=1. Decoded: the flag is Player::NonScoringPlayerFlag (bit 14 = Entity::NextBit); both loops now use IsScoringPlayer(). Also closes the pilotIDs[1] overrun. 2. The build-once latch races async replicant arrival (rig-proven 1-then-2): rebuild on scoring-census change [T3 accommodation, demand-latch precedent]; also un-dangles departed peers. Forensic: '[score] pilot roster built: N'. 3. Name icons were a NULL stub + zeros blank authentically -> rows invisible. Wired BTPilotNameBitmap (playerBitmapIndex -> Mission small callsign raster, the radar-label chain); replaces the raw pilot+0x1e0 key. Rig-verified: Aeolus + Boreas rows with callsigns on both nodes incl. the staggered-start race; solo unregressed (1 scoring pilot). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0166KTsC7ADm7VXEi1HF1jNg
This commit is contained in:
co-authored by
Claude Opus 5
parent
7494e2ec6c
commit
b7107b1020
+23
-7
@@ -304,13 +304,29 @@ screen paint over the shared Eng plane, pinning it on the highest screen). Pixel
|
||||
`BT_PRESET_TEST=<frame>`, `BT_CTRLMAP_LOG`.
|
||||
|
||||
## pilotList (Comm KILLS/DEATHS) row semantics + the −1 [T1/T2]
|
||||
**BUG (Gitea #43, 2026-07-24, rig-reproduced): in LIVE MP only the LOCAL row renders — remote
|
||||
players never get a row.** The "2-player MP = 2 rows" below is decomp row SEMANTICS [T1], not a
|
||||
verified MP observation (the audit's live evidence was solo-only). Suspect:
|
||||
`BuildPilotArray`'s count loop (mechmppr.cpp:1133) sizes the roster via the binary's RAW
|
||||
`entry+0x29 & 0x40` spectator-flag read on our compiled objects (databinding trap; the fill
|
||||
loop's same check was already TODO-removed) → pilotCount latches 1 (build-once latch),
|
||||
`GetPilot(1)` bounds-rejects the remote. Fix + MP re-verify pending — see the issue.
|
||||
**FIXED + RIG-VERIFIED (Gitea #43, 2026-07-24; awaiting live playtest).** Field report
|
||||
("never lists anyone in MP") reproduced on a 2-node rig, THREE stacked causes, all fixed:
|
||||
1. **Raw-flag miscount**: `BuildPilotArray`'s count loop used the binary's raw `entry+0x29 &
|
||||
0x40` read on our compiled objects (databinding trap) → garbage → roster latched at 1 row.
|
||||
DECODED: +0x29 bit 0x40 = bit 14 of `simulationFlags` @+0x28 = **`Player::
|
||||
NonScoringPlayerFlag`** (= `Entity::NextBit`, PLAYER.h:392) — the roster authentically
|
||||
lists SCORING players (flag cleared when the mech links its player, mech.cpp:688, all
|
||||
nodes). Both loops now use `Player::IsScoringPlayer()`; also closes a `pilotIDs[1]` heap
|
||||
overrun the undercount exposed.
|
||||
2. **Latch race**: the binary's build-once latch assumes 1995 synchronous pod loads; over
|
||||
async relay TCP the faster node ticks InterpretControls before the peer's replicants
|
||||
arrive (rig-proven: staggered node logged roster 1 → then peer arrival). [T3
|
||||
accommodation, demand-latch precedent]: rebuild whenever the scoring CENSUS changes —
|
||||
also un-dangles a departed peer's freed Player from the roster. Forensic: always-on
|
||||
`[score] pilot roster built: N scoring pilot(s)` per census change.
|
||||
3. **Invisible rows**: `LookupPlayerNameBitmap` was a NULL stub + numerals are authentic
|
||||
`signedBlankedZerosFormat` (zeros draw blank) → an unselected 0/0 row rendered as a black
|
||||
box: invisible even with a correct roster. Wired `BTPilotNameBitmap` (btplayer.cpp bridge:
|
||||
compiled `playerBitmapIndex` → `Mission::GetSmallNameBitmap`, the same 64×16 egg rasters
|
||||
the radar labels use; replaces the binary's raw pilot+0x1e0 key read). Rig-verified:
|
||||
Aeolus (local, center box) + Boreas (remote, roster strip) both render with callsigns.
|
||||
NOTE: rows need the egg to carry name bitmaps (operator-console eggs do; bare rig eggs
|
||||
like MP2.EGG don't → authentic cache-miss blank box).
|
||||
One ROW PER PILOT in the mission (2-player MP = 2 rows — not duplicate displays). KILLS =
|
||||
`killCount` (the victim's ScoreMessageHandler credits the shooter cross-player, works for both
|
||||
rows); DEATHS = `Player::deathCount`: engine-inits to **−2** (PLAYER.cpp:759), the LOCAL
|
||||
|
||||
Reference in New Issue
Block a user