#172 root-caused: the leak-lamp chain was NEVER broken -- all 35 night-16 leak events flashed same-frame (Elengil's 'fatal no-flash' lamp flashed 28.4s in the ~6px glass radar-rail strip; the 'delayed' weapon-leak flashes are the AUTHENTIC page gate delivering at eng-page entry; the leak voice is a LOOPING sequence so 5-6 repetitions carried zero edge information -- the testers' clock was the bug's best disguise). Ships: the ALERT BLOOM (glass-only #154-class deviation -- an alternating surround lamp paints a +8px halo UNDER the surfaces, so only the outward bloom shows, respecting the twice-field-broken no-overlay rule) + two always-on receipts closing the observability holes this hunt fell into: [seqloop] START/STOP (looped alarm sequences -- voice-vs-lamp timing now log-readable) and [lamppx] alert ON/OFF (lamp state -> PIXELS, with cell size). Verified live: GeneratorB=0.6 leak -> seqloop START + lamp 0x1b FLASHING + lamppx bloom8 same cluster. #136 refined: edge-started, level-LOOPED, edge-stopped. KB: gauges-hud leak-lamp routing map (generator=rail-only authentic, condenser 0x2c gap authentic, weapon page-gating authentic, cond 1/3 have NO authored lamps)

This commit is contained in:
Joe DiPrima
2026-08-13 01:56:36 -05:00
parent e614924107
commit 8b3d1c8113
4 changed files with 106 additions and 2 deletions
+31
View File
@@ -826,3 +826,34 @@ classes (PlayerStatus/pilotList/...) with the config interpreter, which let
more of the authored page furniture parse + draw than before -- the leaking
high-index pixmaps rode in with that. [T3 for this correlation detail; the
leak itself and its fix are T2 live-verified.]
## Coolant-leak LAMP ROUTING (#172, night-16 hunt 2026-08-13) [T1 resolver + T2 field]
The leak lamp chain is INTACT -- every staged leak all night (35 events, 4 machines, incl. the
"fatal" case) asserted its lamp the SAME FRAME as the [techstat] cond-2 SET. The field reports
were three different presentation facts:
- **Generator leak -> the radar-rail generator button ONLY** (kBTGeneratorLamp @0051d070; both
authored item codes 0x80+0x87 collapse to that one lamp, mode 0xffffffff = the ALWAYS-ACTIVE
sentinel, never mode-gated). NO MFD carries any generator-leak indicator -- binary-authentic
(@004cc2fc). In glass surround that rail cell renders at the minimumStrip floor (~6px,
L4RIOBANK.cpp) -- Elengil's fatal lamp FLASHED for 28.4s, effectively invisible. FIX (glass-
only deviation, #154-class): the ALERT BLOOM -- an alternating lamp paints a grown halo
(+8px) under the surfaces in BTDrawCockpitPanels; only the outward part shows. Receipt:
[lamppx] alert ON/OFF with cell size, per edge.
- **Condenser (loop) leak -> the per-loop button** (@0051d058, 1-based '2F 2E 2D 2B 2A 29';
the 0x2c gap is AUTHENTIC -- 0x2c belongs to the DISTINCT coolingLoop set of the code<0x80
path). Also always-active. No gate, immediate flash.
- **Weapon leak (AFC50 family) -> PAGE-SCOPED lamps only** (quad-select + its eng-page button):
the mode gate (@00444e64 == LAMP.cpp) skips the notify while the page is hidden and the
page-entry force-notify delivers it when the player pages there -- "flash appeared at the
second voice line" = the player paging to engineering after voice loop #1. AUTHENTIC;
documented for testers, not fixed. Coolant-cooled guns leak in PAIRS (weapon bit + serving
condenser bit) -- one page-gated lamp, one always-active loop lamp.
- **The VOICE is a LOOPING sequence** (0E4ACE50, tempo 160): Start on the coolantActive 0->1
edge, self-repeats, Stop on 1->0 (the #136 model REFINED: edge-started, level-looped,
edge-stopped; hysteresis flap = restart). Voice repetitions carry NO edge information --
the field testers used the voice as a clock and mis-dated the lamp. Receipt: [seqloop]
START/STOP, always-on for looped sequences.
- Authored no-lamp facts (from the mechalrm item census, [galm-item]): conditions 1 (Damaged)
and 3 (Overheating) have NO lamp items for ANY subsystem; cond 0 (Destroyed) resolves lamps
only for weapon-slot subsystems. A heat alarm never flashes a cockpit button -- authored.
+8
View File
@@ -1235,5 +1235,13 @@ consistent with internals-only, see #103). Logs: `scratchpad/night16/` + Oracle
re-descend re-entrancy (zone 18 x7 re-rolls, own ticket); (iii) incident-(b) "no damage on
target": shooter log computed FULL damage (11.76) -- wire/victim-side loss, needs paired
matchlogs (fleet-wide BT_DMG_LOG + matchlog next night would make this attributable).
- **#172 RESOLVED (2026-08-13, 4-agent hunt): the lamp chain was NEVER broken** -- all 35
staged leak events flashed same-frame. Three presentation facts: generator lamp = the ~6px
radar-rail strip in glass (fatal case: flashed 28.4s unseen -> ALERT BLOOM deviation);
weapon-leak lamps are page-gated AUTHENTICALLY (the "delayed" flash = the player paging to
engineering); the leak voice LOOPS off one edge (testers' clock was wrong). See
[[gauges-hud]] SSCoolant-leak LAMP ROUTING. Receipts armed: [seqloop], [lamppx]. Residual:
Lynx's loop-6 report unstaged (his machine, no log); Elengil's AFC50 pre-rotation log still
wanted for the pair-leak confirmation.
- Nanook lost the coolant MFD glass window, recovered only by config edit -> #76 comment
(in-game layout-reset recovery path).
+15
View File
@@ -401,6 +401,17 @@ void
<< " tempo=" << (int)tempo
<< " divPerBeat=" << (int)divisionsPerBeat << std::endl; } }
// #172 field receipt, ALWAYS-ON for LOOPED sequences (the alarm family --
// leak warning, lock beeper; a handful per mission): night-16 proved the
// voice loop is the testers' CLOCK ("it said coolant leak 5-6 times") yet
// no field receipt tied voice to leak edges -- the fatal-case timeline had
// to be reconstructed from matchlog wallclocks. One line per Start/Stop
// EDGE makes voice-vs-lamp timing readable straight from any field log.
// (Looped only: one-shot effects fire constantly and would spam.)
if (isLooped && !isRunning)
DEBUG_STREAM << "[seqloop] START seq=" << (void *)this
<< " tempo=" << (int)tempo << "\n" << std::flush;
Check(this);
//
@@ -438,6 +449,10 @@ void
if (!isRunning)
return;
if (isLooped) // #172 receipt (see StartSequence)
DEBUG_STREAM << "[seqloop] STOP seq=" << (void *)this
<< "\n" << std::flush;
//
// Find next on or off event
//
+52 -2
View File
@@ -1180,17 +1180,67 @@ void BTDrawCockpitPanels(LPDIRECT3DDEVICE9 device)
CkFill(device, 0, L.viewY, L.viewX, L.viewH, band); // left
CkFill(device, L.viewX + L.viewW, L.viewY, L.canvasW - (L.viewX + L.viewW), L.viewH, band); // right
// 2) Button lamp faces (UNDER the surfaces -- only the protruding edge shows).
// 2a) #172 ALERT BLOOM (glass-only deviation, #154-class, user-approved
// family): an ALERTING lamp in a surround strip bank is a ~6px sliver
// (minimumStrip) -- Elengil's fatal GeneratorB leak FLASHED lamp 0x1b
// for 28.4s and nobody saw it (night-16, ticket #172; the pod's
// physical backlit buttons don't have this problem). Draw a GROWN
// halo rect FIRST, under everything: neighbors repaint their own
// faces and the surfaces cover the inward part, so only the outward
// bloom survives -- which respects the "no on-top overlay" rule
// (twice field-broken, see the note below step 3). Fires ONLY while
// the lamp genuinely alternates (flash bits set AND the two levels
// differ), so steady lamps and same-level pulses are untouched.
unsigned long tick = GetTickCount();
const int kAlertBloom = 8;
for (int i = 0; i < L.buttonCount; i++)
{
const BTCockpitBtn &b = L.buttons[i];
int shade = BTLampBrightnessOf(CkLampState(b.address), tick);
int state = CkLampState(b.address);
if ((state & 0x3) != 0
&& (((state >> 2) & 0x3) != ((state >> 4) & 0x3)))
{
int shade = BTLampBrightnessOf(state, tick);
D3DCOLOR fill, border;
CkLampColors(b.colorClass, shade, b.inert, &fill, &border);
CkFill(device, b.x - kAlertBloom, b.y - kAlertBloom,
b.w + 2 * kAlertBloom, b.h + 2 * kAlertBloom, fill);
}
}
// 2b) Button lamp faces (UNDER the surfaces -- only the protruding edge shows).
for (int i = 0; i < L.buttonCount; i++)
{
const BTCockpitBtn &b = L.buttons[i];
int state = CkLampState(b.address);
int shade = BTLampBrightnessOf(state, tick);
if (gCkPressed == b.address || gCkLatched[b.address & 0x7F]) shade = 3;
D3DCOLOR fill, border;
CkLampColors(b.colorClass, shade, b.inert, &fill, &border);
CkFill(device, b.x, b.y, b.w, b.h, border);
CkFill(device, b.x + 1, b.y + 1, b.w - 2, b.h - 2, fill);
// #172 paint receipt: one line per ALERT edge per lamp -- the night-16
// forensics could prove the lamp STATE but had zero visibility into
// pixels ("the seam-to-pixels observability hole"). Cheap: fires only
// when a lamp's alternating-status flips.
{
static unsigned char s_wasAlert[128];
int alerting = ((state & 0x3) != 0
&& (((state >> 2) & 0x3) != ((state >> 4) & 0x3))) ? 1 : 0;
int slot = b.address & 0x7F;
if (alerting != s_wasAlert[slot])
{
s_wasAlert[slot] = (unsigned char)alerting;
DEBUG_STREAM << "[lamppx] 0x" << std::hex << b.address
<< (alerting ? " alert ON" : " alert OFF")
<< " cell=" << std::dec << b.w << "x" << b.h
<< "+bloom" << (alerting ? kAlertBloom : 0)
<< " at " << b.x << "," << b.y
<< " state=0x" << std::hex << state << std::dec
<< "\n" << std::flush;
}
}
}
// 3) Gauge surfaces on top (green-tinted mono / palette sec). Reuses the