Commit Graph
939 Commits
Author SHA1 Message Date
Joe DiPrima 2c6dc001e3 Friday forensics net: all four player launchers set BT_DMG_LOG=1 -- named per-shot [emitter]/[dmghit]/[crit] receipts fleet-wide, making every weapon incident attributable by name (the #165/#171 verification recommendation). environ.ini deliberately NOT used (player-owned, never shipped by design). Verbosity rides the single-file log + SENDLOGS compression; flag comes out after the weapons-verification cycle 2026-08-13 19:11:07 -05:00
Joe DiPrima ca9e5ff5c0 #173 FINAL: port cadence defect FIXED -- the velocity ring now samples at the pod's 28Hz by default (BT_MYO_RING_HZ overrides). Measured [T2, six curves m173v2]: at ~59fps the |a| operand carried 64-66% gait-aliasing noise = drive heat 2x the machine's; at 28Hz + the authored loop-5 boost (detent 50 receipt-proven, flow 0.909) a vulture holds FULL supercharge 54-57 u/s indefinitely at stable Tm~1500 -- the machine's valve lever worked, the manual's Super Charged print was honest, witnesses 7-0 (Draco/Oracle/Elengil + the user's eyes beat the solver AND the first bench). Balanced seek-4 still cooks authentically (~18s); wrap trap stands; display pixel-verified in sync. BT_VALVE5 bench hook added (receipted detent presses). Post-promotion smoke: boosted vulture stable ~1500 dipping under. Gotcha 32 (sampled-history operands at render cadence; a validated model EXTRAPOLATES, only the bench INTERPOLATES); cadence census -> BTSimClock migration checklist in open-questions (gyro bounce timescale next, footstep smoothers, doppler; heatLoad was already pod-clocked #119 = the reference pattern). Guide 2B rewritten with the confession + the measured fix 2026-08-13 19:03:41 -05:00
Joe DiPrima 0f5c87dc84 drift audit: row 7 tracer-visual verdict flipped to FIXED-THIS-BUILD (the recovered TOF constants landed in b94636b; the row still carried the pre-landing 'close it' directive) 2026-08-13 18:00:05 -05:00
Joe DiPrima 25ed1ca627 #21 closed at the true root + 'arcade shipped a brick' RETRACTED (era witnesses 6-0): _DAT_004ba830 is a DOUBLE 1.0, not float 0.0 -- the entire brick claim was a constant-width misread (dword read of a qword; the low half of 1.0's mantissa is zeros). Binary truth [T1 raw disasm @004ba738]: overcharge CLAMPS to exactly 1.0f, the ==1.0 Loaded test passes next tick, the weapon fires the stored charge at normal top-gear damage (divisor is the recommended gear). Fix: clamp corrected to 1.0f; the rescue scaffolding REMOVED (it patched our own misread -- 38 'rescues' were 38 events the machine silently clamped); gauge-side zeroing inherits the fix, which is almost certainly #21's ORIGINAL field symptom (dark recharge arc + dark ready-dot = the dial reading our zeroed ratio while the rescue kept the weapon firing). seek21 bench PASS: 65 switches / 16 wraps / 9 overcharges -> fires through all, 13 post-overcharge gauge probes FULL, zero rescue prints. Docs: field guide section 2 rewritten as settled-by-testimony (credit to the group), decomp-reference block retracted with extracted constants, drift audit energy lane -> FAITHFUL, ZERO deviations. The witnesses' 'nah, that didn't happen' was worth eight bytes read at full width 2026-08-13 17:59:24 -05:00
Joe DiPrima 47826018cf #173 CLOSED-AUTHENTIC with measurements: chicken-walker seek-4 overheat is the machine's own balance -- heat plumbing byte-identical on all 18 chassis (loop 5 = GenD+Myomers only, the MINIMUM load; walkers carry the LARGEST banks), no speed-dependent cooling exists in the binary, and the decisive control is a HUMANOID Avatar cooking identically in the same speed class (14.3s vs vulture 13.9s). Manual speed cross-check kills the last defect avenue: the machine's walkers were PRINTED FASTER than the port runs them. Ticket's 16x premise corrected (gears 1-3 heat-identical; seek-4 = 2.04x). The authored lever validated: loop-5 valve at detent 50 = 2.7x capacity = sustained gear-4 vulture; the detent cycle 1->5->50->0 wrap explains 'boosted and still cooked'. Oracle's spawn-discharge claim CONFIRMED end-to-end. Field guide gains section 2B (sprint-gear doctrine + valve trick + wrap warning + the 15-second era question); Loki-family repro predicted for Friday. Residual [T3]: gait-surge |a| at render cadence vs the pod's 28Hz -- one bench + one era answer close it 2026-08-13 17:31:12 -05:00
Joe DiPrima ef90b6af8c audio: Yip voice zones EAR-VERIFIED at game rate via the soundboard (user, 2026-08-13) -- SOUNDBOARD_BT411.zip approved for tester distribution 2026-08-13 16:41:18 -05:00
Joe DiPrima 8e6697312f soundboard game-rate fidelity + distributable: rate formula fileRate x 2^((note-60)/12) [T1 L4AUDIO BTNotePitchFactor via AL_PITCH; notes come ONLY from AudioControlSequence]; BTL4.RES audio-stream record format cracked -- all 324 sequences parsed, 92 (sample,note) pairs play OFF file rate, headline: Warnings01/Yip voice zones trigger at notes 16-40 = x0.079-x0.315 (raw files play the voice 3.2-12.7x TOO FAST -- the long-remembered mismatch, now quantified); dead zones found (Death01 z8-11, AuxExplosion01 z6-7 unreachable by any authored note). tools/soundboard.py plays game rates (header-rewrite temp copies, per-note buttons, raw toggle); NEW tools/mksoundboard.py -> dist/SOUNDBOARD_BT411.zip (31.8MB): self-contained index.html, 603 cards, playbackRate+preservesPitch=false, per-note buttons, COPY reference strings for tester bug reports, no fetch (file:// safe), tester README. AUDIO_FIDELITY.md gains the authored trigger-note census 2026-08-13 16:39:18 -05:00
Joe DiPrima e4546923f8 weapons batch VERIFIED on the final tree + last two gaps closed: BYSTANDER SWEEP landed (guided damage rounds test the flight segment vs every mech, detonate on interposers like the binary's world sweep @0042291c -- 11 legitimate strikes in the sweep bench, zero self/phantom/fuze-race hits per forensics) + COAST GRAVITY (-6.5 after burnout). Comprehensive 2-node weapons_sweep bench PASS, all families: ENERGY 184 named FIRED / 79 hits; AC 17 type=1 hits ALL burst=1 + 84 ballistic pushes ALL dmg=0 (hitscan live-proven multi-node on final code); MISSILE 593 type=2 hits, 576 salvo bursts (4.0 fuze + drag speeds work); #174 guard worst-repeat=1 across 13 lives; detector SELF-TESTED against synthetic pre-fix shapes before any verdict trusted. Rig lessons -> test-harness.md: BT_FIRE_AT_ICON designates BUILDINGS (use BT_GOTO=enemy + throttled BT_AUTOFIRE/BT_AF_MISSILE, the kd pattern); mad2 'Zanin Neko' carries AFC50+ERPPC+LRM15+SRM6x2+ERMLaser -- all families on one engaging chassis; -net 1501 -> pilot :1502 mapping 2026-08-13 15:47:23 -05:00
Joe DiPrima bb4094fe7e field guide: file-editing is THE feedback method -- Discord-reply protocol removed; YOUR NOTES block (callsign-first entry lines) inserted after all 9 WE NEED YOUR MEMORY sections; head/tail instructions rewritten (edit the file, post it back) 2026-08-13 15:14:55 -05:00
Joe DiPrima 5272a3db64 field guide: second reply mode added -- mark up the file itself and post it back (the Oracle workflow from the issues handout; spreadsheet exports welcome), alongside the per-section Discord replies 2026-08-13 15:12:51 -05:00
Joe DiPrima 510f4f4c1b field guide updated post-drag-audit: missile section now pre-announces the SPEED DROP (drag governor restored -- LRM ~550/SRM ~775 terminals vs the old dragless 3000+; framed as the pod's real feel, confirmation-worthy) and the stale 'Streak speed authentic' claim softened (that corpus measured the dragless model); SRM range-pip era question added (manual prints 450 x3, content authors 800 -- revision-dating question, display-only either way) 2026-08-13 15:00:27 -05:00
Joe DiPrima b94636b607 velocity/dt audit: DRAG WAS THE GOVERNOR -- the binary applies -0.001*v^2 every frame, burn AND coast (@004bef78 + thruster @004be474, ctor precomputes terminal sqrt(T/COD) into +0x348 as the seeker lead base; authored COD 0.001 byte-read from BTL4.RES type-15 srm/lrm/strk/nrk). The port omitted it: LRM hit 3030 u/s at burnout vs the machine's 547.7 terminal (5.5x), 3912u downrange at t=5s vs 2108u -- a major slice of the 'missiles reach anything' field feel. Pool now integrates speed += (accel - 0.001*v^2)*dt. The dt MODEL itself verified FAITHFUL (Mover zeroes accel per frame + integrates x dt in seconds, matched line-for-line to T0 MOVER.cpp -- the 28Hz myomer idiom does NOT apply; open-question closed). AC cosmetic tracer TOF constants landed (2.0f @0x4bc678, 1/9.8 x87 EXTENDED @0x4bc67c, muzzleHeight term via ResolveLaunchVelocity deferred-first-use). Stale banners swept (misthrst @004be474 recovered; projweap #168 flight-contact banner gone). KB: decomp-reference Mover-gravity fix + flight-model bullet, coast gravity = 6.5 not 9.8. Drift audit: SSVELOCITY/DT + SSRANGE AUTHENTICITY (manual cross-check: PPC/AFC100 MATCH, SRM 450-vs-800 authoring drift; rangefinder ladder NOT miscalibrated -- fixed 0-1200 + authored pips both sides; -100m range-bias state unimplemented, parked). Build clean 2026-08-13 14:58:04 -05:00
Joe DiPrima 6517ebe505 weapons physics audit (7-agent, all classes): docs/WEAPONS_FIELD_GUIDE.txt (tester-facing per-weapon review doc for the playtest group) + docs/WEAPONS_DRIFT_AUDIT.md (engineering drift table with addresses/tiers). Headline corrections the audit itself produced: (1) GAUSS RETRACTION -- the fielded GAUSS record is classID 0xBCD ProjectileWeapon (BTL4.RES @0xf16e6 raw bytes), full AC hitscan WITH damage; GaussRifle 0xBCE + shell 0xBD1 are dead code BOTH sides (zero shipped records; content census 78x0xBC8/16x0xBCD/30x0xBD0/14x0xBD4); the 'port Gauss damage is an invention' claim retracted in KB + ticket. (2) effectiveRange K byte-confirmed 1.0f @004b9c98. (3) PPC EnergyDamage victim-side GAUGE SCRAMBLE rider identified (@004a0230 -> gauge renderer) -- unimplemented in port, and it is exactly what Cyd's held ppc-sync-distortion branch implements: that branch is an AUTHENTIC-feature candidate, not an invention. (4) AC tracer TOF constants recovered (2.0f @0x4bc678, 1/9.8 x87 EXTENDED @0x4bc67c) -- port's 1.0 stand-ins closable. (5) missiles verified FAITHFUL end-to-end (382-impact corpus matches the salvo roll). Era questions consolidated in the guide; #21 overcharge-brick rescue documented as the one deliberate energy deviation 2026-08-13 14:08:35 -05:00
Joe DiPrima bbb3b4ec82 #171 IMPLEMENTED: the AC is trigger-time hitscan again (@004bc104 restored: counter/TracerInterval batching, ComputeTimeOfFlight inside the tracer branch refreshing LIVE effectiveRange, dist<=+0x328 fire-time gate, ONE single-panel batched damage to the locked target via @004b9728; the flying round is the cosmetic 0xBCD tracer, damage 0 -- shell class 0xBD1 stays dead). Missiles keep flight, corrected to the binary: lock-drop = movementMode 2||9 exactly (@0049fb54, tracks THROUGH the fall), proximity fuze 4.0 (_DAT_004bf5a4 -- was misused as a turn gain), salvo roll floor-of-1 REMOVED (binary sender rolls 0; the receiver burst do-while is the floor, mech.cpp:1229). Gauss untouched pending the era witnesses (shipped binary deals NO Gauss damage -- group question on #171). Verification: line-by-line vs part_013.c:16023-16125/18260-18285 (verify workflow + review); end-to-end receipts from the engaged bench run: type=1 burst=1 hitscan hits incl. a 13-round batch, all DETs dmg=0. Local rig cannot form avatar locks for a clean re-run (rig, not feature) -- Friday's field receipts are armed and decisive. Closes the #168 mis-generalization; #112 single-panel restored 2026-08-13 13:19:18 -05:00
Joe DiPrima 80037a7c78 #171 verdict: the era witnesses were RIGHT and half of #168 was a mis-fix -- the AC is TRIGGER-TIME HITSCAN (@004bc104, recovered 2026-08-06 but hidden behind projweap.cpp's stale 'body NOT recovered' banner from the old export: the root cause -- #168 generalized the MISSILE launcher's body to ballistics). Binary truth [T1, cross-examined]: AC batches rounds, range-gates at fire time on live effectiveRange (same gate as energy), sends ONE single-panel damage to the locked target, spawns NOTHING (shell class 0xBD1 = dead code, 0xbd1 appears once in the whole export; the visible round is the 0xBCD renderer tracer); missiles genuinely fly with seeker-computed lead (4.0u fuze, swept contact, salvo randomization, lock-drop on death) so 'no leading' is right for them too; Gauss deals NO damage in the shipped binary (charge dump only -- port damage is an invention). #112 shotgun = port per-round scatter vs the binary's one batched message. KB corrected + swept (decomp-reference SS5, combat-damage, projweap banner). NO code behavior changed -- implementation awaits the #171 group decision per Oracle's HOLD; evidence package queued for the ticket (server down) 2026-08-13 03:20:07 -05:00
Joe DiPrima 3c1decdcc6 gitignore: scratchpad landmine patterns (session handoffs, agent dumps, run outputs, binaries) -- the 6a744ef near-miss: a stray bulk git add pushed a handoff file carrying the gitea credential; history force-rewritten same minute (5cde991), server-side the orphan lingers until gc -- credential rotation recommended regardless 2026-08-13 02:42:38 -05:00
Joe DiPrima 5cde991f56 #174 root-caused + fixed with a negative control: the binary's ONLY re-descend protection is the burst loop's zone-state guard wrapping the WHOLE per-burst application (@0x4a0446, part_012.c:14661 -- crit roll, TakeDamage, score tally, destroyed-flag; RecurseSegmentTable/SendSubsystemDamage have NO internal re-entry protection: no used-marking, no top gate). The port had narrowed the guard to the crit roll -- continued fire re-saturated dead zones (cascade re-fired: night-16 zone 18 x7, each pass re-pushing crit allotment = the ram 'crits worsened with each collision'), and hits on wreckage kept SCORING (binary awards zero -- a quiet farm-the-wreck exploit). Fix: guard restored to binary scope. Bench: BT_ZONE_HAMMER hook (4Hz explicit-zone self-damage) -- fixed build 1 cascade/10 hits/0 post-saturation applications; NEGATIVE CONTROL (fix stashed): 147 cascades. 147 -> 1. Gotcha 31: guard-scope narrowing -- diff the BRACE SCOPE when transcribing decomp ifs; and prove a bench detects the bug before trusting its pass 2026-08-13 02:42:07 -05:00
Joe DiPrima e693b481b3 commit-hygiene sweep: (1) the #170 L4STEAMNET.h contract comment never landed in 2fe58b8 -- the git add used the lowercase filename and the case-mismatch left the tracked (uppercase) path unstaged, silently; (2) the gauges-hud #172 correction was a silent no-op -- a python str.replace whose multi-line needle didn't match printed 'corrected' anyway. Both applied for real now (verified by grep, not by exit code). Note the pattern: two silent tool no-ops in one evening -- verify edits by READING the result, not by the tool's success message 2026-08-13 02:15:45 -05:00
Joe DiPrima 81b0887033 #172 corrected same day (user challenge upheld): the 6px-strip-was-invisible framing RETRACTED -- [lampblink] receipts prove the surround paints the flash at a metronomic 125ms (code-identical loop in 913), and Elengil's layout receipts show the stock surround with the lamp on screen. The real mechanism is EXPECTATION: a generator leak lights the button BY THE RADAR (authentically the only place -- no MFD carries a generator-leak indicator) while testers watch the MFDs. Ships: handout WHERE-TO-LOOK entry (#172) + the refined #136 voice-loop wording; the alert ring is GATED OFF by default (BT_ALERT_RING=1 keeps it available if Friday proves testers miss the lamp even knowing its location); [lampblink] shade-transition receipt added (BT_LAMP_LOG). Era question posted for Oracle: how prominent was the pod's physical generator button light? 2026-08-13 02:14:13 -05:00
Joe DiPrima 8b3d1c8113 #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) 2026-08-13 01:56:36 -05:00
Joe DiPrima e614924107 one night = ONE log file: the 8MB size roll-over retired (it cost field evidence the moment it existed -- night16: Elengil's incident window sat in an unsent pre-rotation part; testers attach 'the log' = the newest part). The 6am log-day boundary stays. Transport moves to players/SENDLOGS.bat (ships at the dist root): one double-click zips every log/matchlog/lastrun from the last 36h to a Desktop BTLOGS_<machine>_<date>.zip (~10:1 text compression -- a 13MB night = 1.8MB, well under Discord's 10MB free cap, which is what the roll-over was protecting against). Handout HOW TO REPORT updated; mkdist carries the bat 2026-08-13 00:45:21 -05:00
Joe DiPrima fcd592c0f2 #165 ROOT-CAUSED after three failed fixes -- the binary keeps ONE destroyed cell per subsystem (+0x40: fire gate, dial X, wire header, every writer) and the port split it into FOUR stores; the everyday CRIT-LOTTERY kill (MechWeapon::TakeDamage) bypassed the reconstructed base and wrote only the X store, so X'd weapons kept firing while every prior fix aimed at a gate that was never broken (the 4,213-refusal bench drove BT_KILL_SUBSYS, which writes all cells -- it validated readers, not writers). FIX: MechWeapon::TakeDamage chains to MechSubsystem::TakeDamage (@0x4ac0bc semantics); the port-authored FSM-from-damage tail is DELETED (it parked partial-crit weapons at level 1 -- no FSM case, the silent freeze, and with beamFlag armed the 883 hanging beam: #164's upstream writer, caught red-handed by berserker's 20x STUCK-ON receipts); the phantom uninitialized simulationState int is ctor-initialized and kept in lockstep at every destroyed write; always-on [crit] DESTROYED receipt makes crit kills field-visible. BT_CRIT_SUBSYS bench hook drives the REAL writer path; weaponx_bench PASS: kill phase 0 FIRED post / 5,664 refusals / X+gate agree, partial phase keeps firing. Gotcha 30; #174 filed (cascade re-descend) 2026-08-13 00:35:33 -05:00
Joe DiPrima 2fe58b8b89 #170 root-caused + fixed: the #163 SteamAPI_Shutdown was the crash -- at round end every peer's close events are ALWAYS in flight, and Shutdown tears client state down while steamclient's own service thread dispatches them (the field stack: a steamclient worker calling literal NULL, zero btl4 frames, 7 hits / 3 machines / one module-relative stack). BTSteamNet_ShutdownAll is now a QUIESCE: steamActive gated FIRST, linger closes ('round over' not timeouts), one SNS drain, 60ms grace, NO SteamAPI_Shutdown -- and every exit path dies via TerminateProcess (menu-quit no longer returns through the CRT; it uses BTOrderlyDie like everything else, so the 883 detach deadlock stays dead too). Status callback guarded for the dying window. Crash filter now names foreign DLL frames (module+offset via VirtualQuery/GetModuleFileName) so the next foreign-thread crash arrives pre-symbolized. Exit contract: steam-networking.md 2026-08-12 23:23:23 -05:00
Joe DiPrima c3258ee2e1 night-16 field intelligence (build 913, 20260812): tracker housekept -- 6 field-verified closes (#162/#156/#154/#135/#169/#128), #165 FAIL detail + #76 Nanook comment, 4 new tickets (#170 menu-relaunch NULL-callback crash = top defect, #171 ballistic hitscan era question ON HOLD, #172 leak first-flash edge, #173 chicken-walker myomer overheat); KB gains the night-16 section + the spawn-discharge/generator-bias heat note [T3] 2026-08-12 23:05:55 -05:00
Joe DiPrima 6ac62dff6f KB sweep: the game is NOT '1995' -- era witnesses say BT 4.10 shipped later, and the 1995 belief traced to the MUNGA library RCS strings inside BTL4OPT.EXE (library code date, not the game; the exe has no game-copyright year). ~120 era references across CLAUDE.md/context/glossary/handout rewritten to 'the original'/'the shipped machine'; genuine dated facts kept (RCS $Id strings, Borland 1994, the 30-Nov-1995 asset timestamp); dating note + evidence added to project-overview.md 2026-08-12 11:50:56 -05:00
Joe DiPrima 535dc8bfa7 tester handout regenerated for Friday (build 4.11.913): section A rebuilt around the week's 9 fielded fixes (#162 headliner + #156/#154/#164/#163/#135/#128/#166/#169, Cyd's #48-family, #136 explained-authentic), #167 added to monitor, #132 cross-referenced to the #164 beam family, counts recomputed (58 open) 2026-08-12 11:34:01 -05:00
Joe DiPrima 256c45f509 Merge Cyd's vPLASMA_fix: the desktop plasma marquee showed heap garbage from boot until the first callsign draw -- PixelMap8 allocates uncleared and the glass window blits the WHOLE buffer (the pod's serial path only sent changed lines, so hardware never showed it). Ctor memset to index 0; glass-only. 2026-08-12 10:57:19 -05:00
Joe DiPrima 3db7990d6c Merge Cyd's glass-palette-token: the dirty-skip repaint token now folds in a palette write generation -- the ColorMapper family (armor rosette tints, adpal damage flash) animates via CLUT writes with zero pixel churn, so palette-expanding glass windows held stale colors while the D3D surround tracked live. Generation bumps only on a REAL entry change (the flash writes identical RGB at zero damage every Execute). 2026-08-12 10:57:18 -05:00
Joe DiPrima c6c6ddad6c Merge Cyd's sec-phantom-fix: #48 refined -- out-of-range art indices map to plane BACKGROUND, not cycled in-plane (idx-254 art in SMODE.PCC + BTSEC1.PCX was landing on the live right-armor damage slot: the phantom mode-box fills and the stray bar by the heading dial). Background is the shipped machine's on-screen result. 2026-08-12 10:57:17 -05:00
Joe DiPrimaandClaude Fable 5 1282063cc7 #164 hardened to impossibility + the config theory tested NULL: the beam draw now requires the weapon to actually BE in Firing(0) -- the 1995 visual rode ContinueDischarge's per-frame re-messaging which stopped the instant the state left 0, so state-gated drawing is the faithful semantics and makes ANY beamFlag bookkeeping stick invisible by construction (Conn Man's screenshot: red laser, leg-level origin, dials green = a live weapon with a stuck flag). Receipts stand armed for the field: [beam] STUCK-ON (armed flag outside Firing) and DESTROYED-BUT-ON, each naming the weapon. The config-mid-discharge theory was tested deterministically (BT_CFGTEST waits for state 0 and dispatches ConfigureMappables to that weapon): the dispatch landed with beamFlag=1 and NO stick followed -- the handler does not disturb the discharge; theory retired with receipts. Upstream cause remains open; one field recurrence now names it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 02:14:34 -05:00
Joe DiPrimaandClaude Fable 5 f4feaea4c1 KB: the replicant StopMission authority leak (#156 layer 3) recorded in multiplayer's owner-only discipline + fade_bench registered in the bench suite table
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 01:57:42 -05:00
Joe DiPrimaandClaude Fable 5 d01409a48c #164 guard + smoking-gun receipt: the beam draw walk (DrawWeaponBeams) filtered by CLASS only -- a destroyed emitter with beamFlag still armed kept drawing, and a destroyed ARM's mount segment is gone so the muzzle falls back to the mech ORIGIN: Conn Man's feet-anchored rudder-riding hanging beam (his MS-FIREFLY log: every destruction all night was an ERPPC+ERSLaser arm pair). The walk now refuses destroyed weapons (dual-cell read, gotcha 22 accessors) and prints '[beam] DESTROYED-BUT-ON' when it catches an armed beamFlag on a dead weapon -- one field recurrence names the upstream stick; the visual cannot render regardless.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 01:52:35 -05:00
Joe DiPrimaandClaude Fable 5 880ee20005 #156 layer 2+3, both field-caught watching the fade live: (a) the fade-out completed into a phase-0 re-arm that RESTORED normal fog for the ~2s before teardown -- the binary's zone fog stays closed, so the machine now holds a terminal black phase until the next MissionStarting edge; (b) the 3.0s end window itself never existed on ANY node: a REPLICANT player copy mirrors the remote master's MissionEndingState through its record header, and its never-armed fadeTimeRemaining (<=0 at first tick) dispatched the second StopMission instantly -- Stop() killed the mission loop before the fade could render ([fade-clk] receipts: a clean 3->2.976->... countdown interleaved with a stray remaining=-0.976). ManageApplicationStatus is now owner-gated (a replicant player must never drive application state -- the same authority discipline as scoring). This was the FIELD half of the no-fade report too: steam nodes hold up to 7 replicant players, any of which cut the window to ~one record heartbeat. Receipts now: 124-tick single countdown, phases 1-5 on both nodes, fade rendered + black held to teardown.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 01:43:14 -05:00
CydandClaude Opus 4.8 6a60b46f8d plasma window: initialize the display area (junk shown until the callsigns)
The desktop plasma marquee showed heap garbage from boot until the gauge
renderer first drew the callsigns.  Root cause [T0]: PixelMap8(w,h) allocates
its pixel bytes UNCLEARED (GRAPH2D.cpp `new Byte[w*h]`, no memset) and
Video8BitBuffered never clears them either -- only changedLine[] is zeroed.
The real pod never showed it: the serial PlasmaDisplay transfers only CHANGED
lines, so the garbage never left the buffer and the hardware marquee sat at
its power-on blank.  PlasmaWindow::Update however blits the WHOLE buffer
every frame, exposing the junk for the window-up-to-first-draw gap (seconds
on slower rigs).

Fix: PlasmaWindow ctor memsets the pixelBuffer to index 0 (the near-black
background) -- the window comes up blank like the hardware did.  Glass-layer
only; the serial pod path is untouched.  Verified: glass boot shows a clean
marquee from the first visible frame.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 20:29:33 -05:00
CydandClaude Opus 4.8 937c9ad74c sec-surface phantoms: #48 wrap lit idx-254 art in live armor colors
Playtester report: (1) the CONTROL MODE stack showed filled boxes around the
inactive MID/ADV entries, (2) a phantom block between the HEADING dial and the
ARMOR rosette.  Root-caused [T1]:

  The #48 translation-table cycle-fill (6bb03ae, 2026-07-25) mapped
  out-of-range art indices in-plane as (index mod 2^bits) -- so art index 254
  landed on plane slot 62 = the LIVE colorMapperMultiArmor right-armor damage
  slot.  And idx-254 art EXISTS: every SMODE.PCC frame fills the INACTIVE
  mode-box interiors with 254, and BTSEC1.PCX carries a stray 52x13 idx-254
  bar at port (199-250,101-113) between the heading dial and the rosette (a
  scratch duplicate of the rosette quadrant bars).  Both lit up in the
  current right-armor color (adpal ramp green/orange/red) on EVERY render
  path.  On the shipped machine those regions rendered BLACK (the garbage
  entry's low plane bits were 0), which is why the 2026-07-19 smode audit --
  run before the cycle-fill landed -- verified CORRECT.

FIX (BuildSecondaryTranslation): map [2^bits..255] to translationTable[0]
  (plane BACKGROUND) -- the authentic on-screen result, same no-leak
  guarantee.  Verified on both desktop paths: MID/ADV back to authored
  borders+text (idx 5/9), no interior fills; the phantom bar gone; the BAS
  badge and the live armor rosette (in-range slots 60-63) untouched.

KB: gauges-hud #48 REFINED addendum; GAUGE_COMPOSITE audit row 33 corrected
  (binding is ControlsMapper/ControlMode, not DisplayMode) + re-verification
  note.

(The companion glass-token palette-generation fix lives on glass-panel-perf --
it depends on the dirty-skip code there.  The two branches touch disjoint
hunks and merge in either order.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 20:29:20 -05:00
CydandClaude Opus 4.8 7516eee4d8 glass dirty-skip: fold palette generation into the repaint token
Latent flaw in the c9e25e5 dirty-skip (now in master): the token hashes plane
PIXELS + lamp state only, but the ColorMapper gauge family (armor rosette
tints, the adpal/adpal2 damage flash) animates by writing CLUT entries with
ZERO pixel churn -- so a glass window whose plane is pixel-static held stale
colors while the D3D surround (which re-expands every frame) tracked live.

New SVGA16::paletteGeneration, bumped by the palette writers:
  - BuildSecondaryColor: only on a REAL entry change (the flash alternates
    palettes every Execute writing identical RGB at zero damage -- an
    unconditional bump would repaint every palette-expanding window every
    pump for nothing);
  - BuildSecondaryPalette / BuildAuxiliaryPalette / BlankPalette (full
    rebuilds): unconditionally.
GlassWindowToken folds it in for palette-expanding windows (monoTint < 0, or
all windows under BT_GLASS_MFD_PAL); mono-tint windows don't read the palette
and keep their pixel-only token.

KB: glass-cockpit.md gains the repaint-pump section (records f3d27f5 +
c9e25e5 + this).  Companion branch sec-phantom-fix carries the idx-254
translation-table fix -- disjoint hunks, merges in either order.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 20:29:06 -05:00
Joe DiPrimaandClaude Fable 5 fc71f9c0bb #156 the mission start/end fade RECONSTRUCTED: POVStartEndRenderable was an inert stub (rounds hard-cut) -- the binary's 5-phase fog machine (ctor @00454394, Execute @0045447c; constants byte-read @0x454740-50: flash 0.1s, fades 1.0s, plane floors 0.01/0.05) now runs at the renderer frame head keyed on the local player's SimulationState (3 MissionStarting -> white flash + 1.0s fade-in from white; 4 MissionEnding -> 1.0s fade-to-black, planes closing to the floors, re-arm). Drives the live fog pipeline (currentFogNear/Far + FOGCOLOR, which the frame Clear also samples -- the fade owns sky/void too) and re-reads the STYLE members per frame exactly as the binary re-reads live view fog (mid-fade searchlight swaps track). Armed by the now-real ctor in btl4vid.cpp (house pattern: inert object, module machine). Bench fade_bench.sh: 40s relay-clocked round, both nodes PASS armed + phases 1/2/3/4 in order with the end edge on simState=4. Rider: the [rio] STALL detector now keys on REPLY drought instead of request age (which the 50ms poll refreshed forever -- the detector could never fire; #160 telemetry).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 18:54:12 -05:00
Joe DiPrimaandClaude Fable 5 2938d4918c context-system housekeeping: the 2026-08-11 wave lands in the digests -- router Current-front refreshed + the four audit ledgers listed + the docs/ AI-vs-human split labeled; test-harness gains the standing bench-suite table (kd4/kd8/proj_ttl/gen_edge/xfire + rig notes: clone-the-pilot-page pattern, only map-defined dropzones are valid); multiplayer gains the K/D authority + #45 mirror section with the 4/8-node stress record; combat-damage gains the synchronous-death-transition section (gotcha 25 pointer, tripwire semantics); open-questions replicant-delivery entry gains the 0-of-35-deaths bench datapoint (needs field conditions); the #154 multi-agent audit lanes preserved from session temp as docs/GEN_WARNING_AUDIT_20260811.md (with the no-speech retraction lens noted). checkctx: CLEAN.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 18:37:59 -05:00
Joe DiPrimaandClaude Fable 5 4b986af94d KB: gotcha section 25 (same-pass edge latch sampling deferred state -- the #162 double-credit class) + decomp-reference gains the synchronous mode-9 timing fact (part_012.c:14761 reads it flipped in-pass) and the 4/8-node mirror-convergence bench record
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 18:16:39 -05:00
Joe DiPrimaandClaude Fable 5 1b6d247e51 #162 4-node retest CAUGHT + FIXED a same-frame double-credit: two lethal deliveries of one salvo (direct + splash, 2ms apart, no sim tick between) each read destroyedAtEntry=0 -- the entry latch samples movementMode 2||9 but our death transition (mode 9 write) ran NEXT TICK in UpdateDeathState, while the binary flips mode SYNCHRONOUSLY inside the same damage pass (its tail gate part_012.c:14761 reads 9||10 already set). Result: duplicate kill credit to the shooter (bench receipts: kills 1->2 in 2ms, awards 525.00/516.67) and a duplicate VehicleDead whose death cycle the receiver dedup swallowed -- but the kill report had already escaped. Invisible to every 2-node bench (direct kills deliver one lethal hit; splash+direct overlap needs crowds) -- the 8-player field 'kills way off' shape. Fix: the death tail now runs the once-per-death transition inline (mode 9 + type-6 + effects) before returning, exactly the binary's sequence; the next lethal message latches on both destroyedAtEntry and deathBlastArmed. The wrong 'synchronous' claim in the old comment corrected. Benches: kd4_bench (receipt-derived per-player invariants + bystander mirror convergence + no-mirror-exceeds-authority + inst=R audit) PASS 9/9/9/9 SWALLOWED=0; kd8_stress staged (8-node all-vs-all melee).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 17:52:51 -05:00
Joe DiPrimaandClaude Fable 5 7fa6dc536c #135 FIXED, two defects: (1) the generator lamp special was mis-reconstructed -- the binary @004cc27c is table_0051d070[generatorNumber] (bytes {0x29,0x1A..0x1D}, 1-based A..D, same shape as the condenser special), not an aux-screen placement probe generators never fill; a leaking generator now flashes its own lamp (benched: '[lamp] 0x1a <- 0x37 (FLASHING)' on a GeneratorA leak; was the field-logged 'NO LAMP RESOLVED'). (2) the eternal loop-button flash: Lamp::SetAlertState/SetState drop their panel notify when the edge lands off-page or in the one-frame mask race of a page transition, and the panel value latches the last-asserted flash forever -- Oracle's 'Loop 6 NEVER stopped' with Condenser6 SET/CLEARED balanced 3/3 in his log (the alarm manager was right; the lamp was stale). The skipped notify is now remembered and delivered at the lamp's next in-mode frame. KB: decomp-reference gains the 0x51d070 table + the stale-flash gotcha.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 17:08:48 -05:00
Joe DiPrimaandClaude Fable 5 14c62f184d #166 mechanism pinned + two input-layer fixes: Oracle's LRM jam = the ammo bin PARKED at Ejecting(3) with rounds aboard (his log: 'NoAmmo (gate2): rounds=18 binState=3', twice; eject tap cleared it exactly as the handler predicts). The MFD/HUD 'desync' is honest: the full green circle is the RECHARGE dial (untouched by the gate2 pin) and the btejam lamp keys only on weaponAlarm 5 (binary @004c9a38) -- state-7 pins show neither, authentically. The parking producer needs an unpaired eject PRESS, which pod hardware cannot make but our glass mouse layer could: (1) WM_CAPTURECHANGED now releases a held panel button when capture is stolen (Steam overlay/popups ate the WM_LBUTTONUP), (2) a new press releases any still-held previous button instead of orphaning it. Forensics: every EJECT message now logs data/bin/ejectState/binState/rounds always-on (ejects are rare) -- Friday names the producer if it recurs. Smoke: BT_EJECTTEST replays the full press/hold/dump receipt chain incl. the authentic mid-eject gate2 pin.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 16:45:12 -05:00
Joe DiPrimaandClaude Fable 5 18fba98298 #165 does not reproduce -- the destroyed-weapon fire gate HOLDS on the exact field path: bench (xfire_bench.sh) kills ERPPC_1+ERSLaser_1 via the cascade's own ForceCriticalFailure writer under held autofire -- ERSLaser_1 9 FIRED pre-kill, 0 post, 4213 refusals (destroyed=1), surviving ERMLaser fires on. Rajel's field read explained: the refusal tail recomputes output voltage every tick (binary-authentic), so a destroyed weapon's recharge dial keeps CYCLING under its X while the surviving torso lasers put the beams peers saw. Rider: the [emitter] FIRED receipt now NAMES its weapon under BT_DMG_LOG (the #110 nit) so the next field session can settle it by name.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 16:13:39 -05:00
Joe DiPrimaandClaude Fable 5 df4d1c8ac7 #169 rider: shorten the roster build-gate tag to [WRONG BUILD] -- the '-- WILL NOT LAUNCH' tail clipped at the 536px row edge (caught in the layout preview render)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 15:55:23 -05:00
Joe DiPrimaandClaude Fable 5 c8373f2407 #169 lobby room layout: LEAVE button was half-clipped because 560x360 was the OUTER window size (the caption bar ate the bottom ~47px of a client that needed 336+), and rosters past 6 members drew through the fixed LAUNCH frame at y=250 (rows flow to 268 at 8 players). Buttons now sit below the full 8-slot roster (LAUNCH 280-326, LEAVE 336-366) and the window is sized by CLIENT rect via AdjustWindowRect (560x382). Geometry-proven; visual verify = next lobby + Friday's 8-player night.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 15:51:07 -05:00
Joe DiPrimaandClaude Fable 5 fef6fad47a #154 phrase identity ear-verified: the generator trigger's sequence (Warnings01 z4/z0/z3) is Yip's spoken 'generator out' line -- the deviation now speaks the real voice at the trip. KB tier bumped to T2.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 15:47:15 -05:00
Joe DiPrimaandClaude Fable 5 8d2f48225b #154 correct the record: the warnings ARE VOICE -- Warnings01/AllWarning zones are Yip's recorded words, phrase-sequenced by the AudioControlSequences (our own #119 commit 42b0691 said so); the generator sequence z4/z0/z3 is the spoken 'Warning, generator out'. The same-day 'BT 4.10 shipped no speech / era memory is Firestorm' claim is retracted -- it rested on preset names and ignored repo history; with the voice real, the era memory of hearing it at the TRIP may be genuine (possibly a later floor revision fixing the same authored bit our deviation flips). The fix itself stands and is strengthened. KB entry rewritten + process lesson recorded (grep git log before asserting absence).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 15:27:07 -05:00
Joe DiPrimaandClaude Fable 5 08fc87ec6e #154 settled: the generator-out warning was authored on the WRONG EDGE in the shipped 1995 content -- BTL4.RES keys it (trigState=4, inverse=1, Start) = fire on LEAVING GeneratorOut, so a thermal trip was SILENT and the klaxon played at recovery/respawn (live-benched both ways; decode triple-verified: T0 read order, binary @0043e7d4/@0043eb40 semantics, independent byte parse; 144-row census = the game's ONLY inverse-Start fault trigger). DELIBERATE DEVIATION (user-approved, the port's only content override): AudioStateTrigger ctor flips it to enter-4 at stream time -- warning at the TRIP, silent at recovery + the respawn 4->0 edge; BT_GEN_WARN_SHIPPED=1 restores shipped. Threshold audit closes AUTHENTIC: recovery at heatAlarm NormalHeat = T<=1000 vs trip at 2000 = exactly the manual p23 half-cooled rule, and the heat bar's red fill maps to it to the tick. Era-witness reconciliation: BT 4.10 shipped NO speech samples (full AUDIO1/2.RES census) -- the remembered voice at trip is Firestorm's. Rig: BT_GEN_HEAT injection + BT_AUDIO_EDGE receipts, gen_edge_bench.sh PASS (4 fixups, trip FIRED, recovery 0). KB: decomp-reference generator section + no-speech note; manual p23 also answered #133 (X = crit-destroyed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 07:39:42 -05:00
Joe DiPrimaandClaude Fable 5 e2ab17665d #168 settled from the binary: projectiles are TIME-capped, never range-capped -- plain shell 5.0s (@4bddec), missile burnTime+10s + y<-1 kill-plane (@4bef78), WeaponRange is fire-control only (FireWeapon @4bcc60 has no range gate), so AFC50 hits at 2000+u are authentic. Two port defects killed: the invented len*1.3+60 flight cap (replaced by the authentic clocks) and the stale-point auto-hit (unguided contact tested the fire-time pick, so a locked AC could not miss a moving target -- the pool now tracks the live target). KB: decomp-reference gains the flight/expiry section, CLASSMAP's swapped authoritative/ghost Performance labels corrected (ReplicantInstance=4 [T0]), missile.cpp's misdecoded @4bf594 constant pool re-annotated, Missile proximity fuse 4.0u recorded. Bench: proj_ttl_bench.sh (probe fizzles 5.012/12.012 vs caps 5.0/12.0; 86 field launches, 0 early, 0 phantoms). Rides along: the #163 BTSteamNet_ShutdownAll header decl that missed d3f4b9a.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 04:39:37 -05:00
Joe DiPrimaandClaude Fable 5 dfefdfa1d0 #128 terrain-ram instant coolant leak FIXED at the eligibility tag: GUID 0x50e590 is the AGGREGATE BANK's node (0xBBE), not the HeatSink base family -- the family-wide reading made every coolant-bearing subsystem (myomers, condensers, reservoirs...) rattle-eligible, so one over-floor ram sub-hit sprang an instant leak (field: Michael's 3 rams all 'Myomers condition 2 SET' -- a subsystem 1995 can never select). Authentic set {HeatSinkBank .30, Gyroscope .35, Torso .25}; scrapes remain free via the byte-anchored 0.5-pt floor (the 30k-lines/night [crashdmg] spam now sampled). Audit: docs/RAM_LEAK_AUDIT_20260811.md. Bench ram_bench.sh: 20 rattles, zero ineligible strikes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 02:33:14 -05:00