From 6517ebe505d82be89a49031953391fa682da795f Mon Sep 17 00:00:00 2001 From: Joe DiPrima Date: Thu, 13 Aug 2026 14:08:35 -0500 Subject: [PATCH] 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 --- context/combat-damage.md | 4 +- context/decomp-reference.md | 8 +- docs/WEAPONS_DRIFT_AUDIT.md | 384 ++++++++++++++++++++++++++++++ docs/WEAPONS_FIELD_GUIDE.txt | 448 +++++++++++++++++++++++++++++++++++ 4 files changed, 841 insertions(+), 3 deletions(-) create mode 100644 docs/WEAPONS_DRIFT_AUDIT.md create mode 100644 docs/WEAPONS_FIELD_GUIDE.txt diff --git a/context/combat-damage.md b/context/combat-damage.md index b89176c..9d71cc2 100644 --- a/context/combat-damage.md +++ b/context/combat-damage.md @@ -210,7 +210,9 @@ DEVIATION, not arcade behavior; "a locked AC could not miss a mover" IS the arca (#168's "stale-point auto-hit" kill removed an authentic design while fixing its stale-point detail). Missiles: genuinely flying + seeker-led (the machine leads for the player), 4.0u proximity fuze, swept contact, salvo randomization — the #168 flight direction stands THERE. -Gauss: NO damage in the shipped binary (charge dump only; port damage is an invention). +Gauss CORRECTED (2026-08-13 audit): the FIELDED Gauss record is CLASS 0xBCD (ProjectileWeapon) +— full AC hitscan WITH damage; port agrees. GaussRifle 0xBCE = dead code both sides (zero +shipped records). The earlier no-damage claim was class-level truth mis-applied to the field. #112 (AFC multi-zone shotgun) is the port's per-round scatter vs the binary's one batched message. Full chain + evidence: [[decomp-reference]] §5 (corrected); port fix pending the #171 group decision (Oracle's HOLD). diff --git a/context/decomp-reference.md b/context/decomp-reference.md index 8f26b12..66f8830 100644 --- a/context/decomp-reference.md +++ b/context/decomp-reference.md @@ -264,8 +264,12 @@ From the weapon `.SUB` records + the charge-curve `.data` constants (PE-parsed a Out of range = batch silently discarded (tracer still renders). The visible AC round is the 0xBCD renderer TRACER (tracerModel+0x41C, TOF @004bc06c) — cosmetic. MissileLauncher @004bcc60 (no fire-time damage, no range read) is the genuinely-flying family. - **Gauss @004bdca4 deals NO damage in the shipped binary** (charge dump only — projectile - launch designed, never implemented; port damage is an invention pending the #171 decision). + **GAUSS CORRECTED (weapons audit 2026-08-13): the FIELDED Gauss is a 0xBCD ProjectileWeapon + record** (BTL4.RES @0xf16e6, bytes cd0b verified raw — 20 pts Ballistic, 900 range, 8s cycle, + 16 rounds, yellow pip) — it runs the FULL AC hitscan chain WITH damage; port and binary agree. + The GaussRifle class 0xBCE (@004bdca4 charge-dump-only FireWeapon) + shell 0xBD1 are real code + with ZERO shipped content records — dead on both sides. (The earlier "port Gauss damage is an + invention" claim was wrong at the fielded level and is retracted.) **Every FireWeapon (all classes) requires a LOCKED target**: both sims gate the trigger on *(mech+0x388) != 0 — no lock, no fire [T1]. - **Plain Projectile (shell) class 0xBD1 is DEAD CODE in the shipped binary**: 0xbd1 appears diff --git a/docs/WEAPONS_DRIFT_AUDIT.md b/docs/WEAPONS_DRIFT_AUDIT.md new file mode 100644 index 0000000..f13563e --- /dev/null +++ b/docs/WEAPONS_DRIFT_AUDIT.md @@ -0,0 +1,384 @@ +# Weapons Drift Audit — binary vs port, per weapon lane (2026-08-13) + +**What this is:** the AI-facing ledger of the per-weapon-class physics audit +(the #171 batch + this session's raw-byte verifications). The tester-facing +twin is `docs/WEAPONS_FIELD_GUIDE.txt` — keep the two in sync; the field +guide translates every address below into behavior and carries the era +questions to the group. + +**Evidence tiers:** T1 = decomp/raw-byte verified · T2 = runtime receipts · +T3 = port approximation · T4 = guess. Addresses are `@ADDR` in the rebuilt +2026-08-06 export (`reference/decomp/all/part_*.c`). + +**HOLD notice:** corrections in the "Corrections owed" section are HELD for +the #171 group decision per Oracle's HOLD — do not sweep them into the KB or +the queued ticket comment until the group signs off. + +--- + +## Verdict summary + +| # | Lane | Verdict | +|---|------|---------| +| 1 | Lasers (Emitter 0xBC8, 6 marks) | FAITHFUL | +| 2 | PPC/ERPPC fire chain (0xBD4) | FAITHFUL | +| 3 | PPC rider (a) victim display scramble | KNOWN-DIVERGENCE [T3] (unimplemented; visual OPEN) | +| 4 | PPC rider (b) victim generator short | FAITHFUL (tag-label scope OPEN) | +| 5 | Seek-voltage gears + #21 overcharge brick | KNOWN-DIVERGENCE (deliberate rescue) | +| 6 | Autocannons AFC25/50/100 (0xBCD) | FIXED-THIS-BUILD (#171; T2 field receipts pending) | +| 7 | AC cosmetic tracer visual | KNOWN-DIVERGENCE [T3] (cosmetic; constants recovered — close) | +| 8 | GAUSS (fielded, 0xBCD record) | FAITHFUL (correction sweep owed, HELD) | +| 9 | GaussRifle class 0xBCE (+ shell 0xBD1) | FAITHFUL (dead code both sides) | +| 10 | MissileLauncher core (0xBD0, all racks) | FAITHFUL | +| 11 | Missile presentation (salvo visuals/gains) | KNOWN-DIVERGENCE [T3] (presentation-only) | +| 12 | Missile bystander sweep | KNOWN-DIVERGENCE [T3] (largest remaining gap) | +| 13 | Missile splash (@0042fad0) | FAITHFUL under stock content (gate wiring [T3] on custom eggs) | +| 14 | LRM flight + loft | FAITHFUL | +| 15 | Streak racks (strk model) | FAITHFUL | +| 16 | NRK5 / nrk-fed racks | FAITHFUL (KB model-table wording sweep owed) | +| 17 | Shared reload/ammo/eject chain | FAITHFUL | +| 18 | Jam roll | KNOWN-DIVERGENCE [T3] (extra gate — remove) | +| 19 | Incoming-missile warning | OPEN (consumer unlocated; era testimony wanted) | + +--- + +## Per-lane entries + +### 1. Lasers — Emitter 0xBC8 (SLaser/ERSLaser/MLaser/ERMLaser/LLaser/ERLLaser) +One C++ class, data-differentiated; **no pulse variants exist** in shipped +content. +- **Binary [T1]:** trigger-time hitscan beam @004bace8: charge-gear state + machine (4 states, no jam/ammo), lock required (`*(mech+0x388)!=0`), + viewFireEnable look-direction arming, `dist<=effectiveRange` gate AT FIRE. + K byte-confirmed **1.0f @004b9c98** → effRange = (1.0 − zoneDamage) × + WeaponRange. Damage = authored × (charge/seekV)². ONE aimed single-panel + message. Out-of-range: beam draws, damage silently discarded. 0.2s + target-tracking afterglow. Hard heat-FAILURE stop (no gradual + degradation). Heat/gear-toggle vet-expert only. +- **Port [T2]:** `emitter.cpp` live-verified same machine end-to-end; 60Hz + sub-stepped Loading tick (±1% snap-window robustness, port mechanism); + beam from real `ermlaser.bgf` tube via `BTPushBeamKind` ([T3] dpl layer + unported, #164 stuck-beam guards). +- **Verdict:** FAITHFUL. + +### 2. PPC / ERPPC — 0xBD4 fire chain +- **Binary [T1]:** one-line tail-call into `Emitter::FireWeapon` + (@004bb878); vtable/ctor/CSS otherwise identical — everything distinctive + is authored data (EnergyDamage(4), 12/16 pts, 900/950 range, 5.0s + recharge, blue pip). +- **Port [T2]:** same tail-call structure; full charge = authored 12/16 + verified live; blue beam under its own renderer case. +- **Verdict:** FAITHFUL. + +### 3. PPC EnergyDamage rider (a): victim display scramble +- **Binary [T1 call, T4 visual]:** @004a0230 (~0x4a03f3): damageType==4 → + no-arg virtual on app-global +0x4c — identified via the port's own app + decode as THE GAUGE RENDERER (`DAT_004efc94+0x4c` = GetGaugeRenderer, + `btl4mppr.cpp:249`, cf. `btl4galm.cpp:404`) — a cockpit gauge/MFD scramble + per Energy hit. Exact visual/duration unread (which vtable slot +0x4c does + visually: OPEN). +- **Port:** NOT implemented — grep of the port `TakeDamageMessageHandler` + body finds no damageType==4 gauge call. Candidate for the #156/ + weapon-state polish list. +- **Verdict:** KNOWN-DIVERGENCE [T3] (unimplemented rider; visual detail + OPEN — era testimony wanted BEFORE building; question shipped in the + field guide). + +### 4. PPC EnergyDamage rider (b): victim generator short +- **Binary [T1]:** @0049c690: damageType==4 + critical subsystems in struck + zone → one random critical rolls `ForceShortRecovery` @004b11bc + (brownout, charge stall, cockpit electronics dip). Tag 0x50f4bc + Generator-vs-PoweredSubsystem label conflict still open. +- **Port [T2]:** implemented — `mechdmg.cpp:471-477` (damageType==4 && + criticalSubsystemCount>0 → ForceShortRecovery). +- **Verdict:** FAITHFUL (tag-label scope OPEN). NOTE: the two riders' + port status differs — never lump them in vet-facing docs. + +### 5. Seek-voltage gears + #21 overcharge brick (all energy weapons) +- **Binary [T1]:** `ToggleSeekVoltage` @004ba478 (vet/expert only): wrap + from gear 4→1 skips `ResetFiringState` → charge above snap window → + `ComputeOutputVoltage` overcharge reads ZERO → weapon PERMANENTLY + BRICKED. The arcade shipped this latent brick. +- **Port [T3 deliberate, documented]:** overcharge counts as Loaded (issue + #21, 38 benched rescues) — the port's ONE deliberate energy-lane + divergence; lives in the deviations appendix. +- **Verdict:** KNOWN-DIVERGENCE (deliberate rescue of a shipped latent + brick). + +### 6. Autocannons — AFC25/50/100 (ProjectileWeapon 0xBCD) +- **Binary [T1]:** trigger-time hitscan @004bc104: lock required, batched + per TracerInterval (all authored 1), fire-time `dist<=live + effectiveRange` gate, ONE single-panel Ballistic message to the locked + target, out-of-range batch silently discarded (round consumed, tracer + flies), gyro recoil kick dmg/16 dir (0, 0.6, −1.5) (constants + 3.0f/0.0625 byte-confirmed), jam p=0.41·T/Tfail clamped [0.05,1.0] + vet/expert-only, EJECT tap=one round / hold 3.0s=dump bay, shell 0xBD1 + dead code. +- **Port [T2 bench]:** `projweap.cpp` at bbb3b4e implements the hitscan + line-by-line (13-round batch + DET dmg=0 receipts); closes #112 + single-panel and the #168 mis-fix. Field verify armed for Friday (local + rig can't form avatar locks). +- **Verdict:** FIXED-THIS-BUILD (#171 batch; T2 field receipts pending + Friday). The field guide carries the #27 "rounds can genuinely miss" + RETRACTION. + +### 7. AC cosmetic tracer visual +- **Binary [T1 weapon-side, T4 renderer-side]:** `launchVelocity.z = + −effRange/sqrt(2.0·(1/9.8)·muzzleHeight)` — both constants BYTE-CONFIRMED + this audit: @0x4bc678 = 2.0f (float32); @0x4bc67c = 1/9.8 stored as an + **80-bit x87 EXTENDED** (bytes `8a 6c 37 99 43 c6 fa d0 fb 3f` — does NOT + decode as float32, likely why it stayed "unresolved") → ~1s to cross full + range for a ~5u muzzle. Drawn by the unported 'Tracer' dpl renderable; + renderer feed unrecovered. +- **Port [T3]:** `projweap.cpp` still ships 1.0f stand-ins for both + constants (marked 'unresolved' — now false) and drops the muzzleHeight + term: tracer speed = effRange/1.0. Numerically close for ~5u muzzles by + accident. +- **Verdict:** KNOWN-DIVERGENCE [T3] (cosmetic-only; constants recovered — + CLOSE IT next build; stale 'unresolved' comments must go in the same + change). + +### 8. GAUSS — the fielded weapon (lok2 'GAUSS' record) +- **Binary [T1 raw bytes]:** BTL4.RES @0xf16e6: classID **0xBCD + ProjectileWeapon** (bytes `cd 0b` / `d0 01` size 0x1D0, verified this + session) — the pod's Gauss ran the FULL AC hitscan chain WITH damage: + 20 pts Ballistic single-panel out to 900, 8s cycle, 16 rounds + (AmmoBinGAUSS 0xBCB), near-cold (1e6 heat), yellow pip, 1.25 gyro kick. + Class histogram across all 18 streams: 78×0xBC8 / 16×0xBCD / 30×0xBD0 / + 14×0xBD4, **ZERO 0xBCE**. +- **Port [T1]:** factory dispatches 0xBCD → + `CreateProjectileWeaponSubsystem` (`mech.cpp:1939-1942`) — the port's + fielded GAUSS ALSO deals AC-hitscan damage. The "port damage is an + invention" framing (commit 80037a7, queued #171 comment, projweap + banner) is WRONG at the fielded level — port and binary agree. +- **Verdict:** FAITHFUL (mechanics match). Correction sweep owed — HELD + (see below). Era question reframed and shipped in the field guide + (headline). Chassis attribution (lok2 vs the weapsub scan's nearest-name + 'blh') rides the flagged heuristic — the field guide asks the vets which + mech carried it rather than asserting. + +### 9. GaussRifle class 0xBCE (+ shell 0xBD1) +- **Binary [T1]:** real code, dead content: `FireWeapon` @004bdca4 = one + store (charge=0), no damage/beam/heat; zero shipped records instantiate + it. Shell 0xBD1 `Make` @004be384 has zero callers; flight body + unreachable. +- **Port [T1]:** same classes exist (GAUSS.CPP shipped source), same + factory case, never constructed by shipped content; equally dead. +- **Verdict:** FAITHFUL (dead code both sides). The CLASS-level "@004bdca4 + is a no-op" claim stands even after the fielded-Gauss correction. + +### 10. Missile family core — MissileLauncher 0xBD0 (SRM/LRM/Streak/NRK) +One class, data-differentiated. +- **Binary [T1]:** genuinely flying, the ONE ungated family: lock-to-fire + via the shared Loaded case (no dumb-fire trigger path, no Streak-special + code), one entity per salvo, per-missile dmg = authored/count, seeker + homes on the fire-time picked panel point with constant-bearing lead, + 4.0u fuze + swept contact (bystanders hittable), lock-drop on target + death (@0049fb54 movementMode 2||9), WeaponRange is fire-control display + only — reach is physics (burn + 10.0s coast, y<−1.0 kill plane, expiry + fizzles), impact cluster roll `min(Random(n)+n/4, n)` then zone −1 + lottery with per-burst re-roll on the victim. +- **Port [T2]:** full chain live-verified (382-impact night-9 corpus + matches the roll exactly; Streak 277 u/s; fuze/lock-drop benched); + direct Dispatch instead of the SubsystemMessageManager (deliberate, + preserves burstCount, #95). +- **Verdict:** FAITHFUL. + +### 11. Missile presentation (salvo visuals + steering gains) +- **Binary [T1]:** ONE Missile entity per salvo (single spawn call + @004bcc60 — the pod drew one flying round + one explosion); body-turn + slerp at authored MaxThrusterRotationRate; velocity slaved to nose while + burning. +- **Port [T3]:** N-round visual ripple (lead round carries damage; N−1 + damage-0 tracers), ±2.5° deterministic tube spread, steering gains + 4.0/8.0 port-tuned (the old 'MissileTurnGain=4.0' attribution was the + proximity fuze), muzzle safety clamp. +- **Verdict:** KNOWN-DIVERGENCE [T3] (presentation-only; damage economy + identical). + +### 12. Missile bystander sweep +- **Binary [T1]:** FUN_0042291c swept real world geometry including movers + each tick — a third mech in the flight path could be struck by someone + else's missile. +- **Port [T3]:** pool rounds contact only the locked target + terrain; a + mech between shooter and target is flown through (splash alone can touch + bystanders). +- **Verdict:** KNOWN-DIVERGENCE [T3] — largest remaining missile-physics + gap. Field-guide watch item for Friday ("hit by missiles aimed at + someone else" beyond splash range). + +### 13. Missile splash — Explosion::SplashDamage @0042fad0 +- **Binary [T1]:** gated on the FIRING player's advancedDamage (+0x264; + every stock egg stamps 1 → splash WAS live on the pods), radius 30 + authored on all missiles, baseBurst = FULL rack count (post-roll restore + @part_013.c:18283-18284, read + confirmed this session), falloff bursts + = round(base/dist^1.25) floored 1 (1.25 = shipped double; divide + grounded in T0 EXPLODE.cpp), excludes the explosion + direct victim; + shooter self-exclusion **unprovable from the export**. +- **Port [T2 mechanics / T3 gate]:** same math, full-count baseBurst (now + [T1]-pinned correct), excludes shooter + direct victim; enable = + SplashRadius>0 instead of the advancedDamage gate — coincides under all + shipped eggs, diverges only on custom eggs. +- **Verdict:** FAITHFUL under stock content (gate wiring KNOWN-DIVERGENCE + [T3] on custom eggs — site option; shooter self-splash OPEN — era + question shipped). + +### 14. LRM family flight (lrm model) + loft +- **Binary [T1]:** lrm rid=319: turn 60°/s, burn 10s @ 300 u/s², climb 50, + splash 30 — climb>threshold triggers the seeker loft (aim.y += + 0.1×min(range−200, 300), up to +30u): the signature climb-then-plunge + arc; soft 30 u/s eject, some mounts +5 up-tilted. +- **Port [T2]:** #84 fixed the thrust resolution (pre-fix 10× slow WAS the + 'missiles are slow' field report); loft constants exact + (@004bec18/24/28). +- **Verdict:** FAITHFUL. + +### 15. Streak racks (strk model — 'SRM6' bins on at least one chassis) +- **Binary [T1]:** strk rid=323: turn 360°/s (3× SRM — 6× the lrm), burn + 3s @ 300, climb 0 — the round that out-turns evasion. NO Streak class or + special lock code exists; the ammo model alone is the identity. +- **Port [T2]:** same records resolved; 277 u/s impact speed verified + live. +- **Verdict:** FAITHFUL. + +### 16. NRK5 'Narc' + every nrk-fed rack +Several 'LRM5/10/15' bins author nrk ammo. +- **Binary [T1]:** no beacon mechanism exists anywhere in the binary + (single launcher class, no beacon input on the seeker). nrk rid=327 + byte-dumped this session: turn 360°/s, burn 10s @ 300, **CLIMB 50**, + splash 30 — the shipped NRK5 is a light LRM-profile rack WITH + Streak-grade tracking AND the loft (missileB's 'no loft' corrected; + dataA right). Field-visible agility difference between visually + identical 'LRM' racks is authentic. +- **Port [T2]:** same data-driven resolution; nothing Narc-special to + port. +- **Verdict:** FAITHFUL (KB model-table wording needs the nrk climb/turn + correction — sweep owed). + +### 17. Shared reload/ammo/eject chain (0xBCD + 0xBD0) +- **Binary [T1]:** recoil countdown only while generator route powered, + heat-scaled (hot generator reloads slower), MinVolt% 0.3 freeze; EJECT + (@004bb9b8, read this session): TAP = one round out + weaponAlarm→3 + Loading UNCONDITIONALLY if rounds remain — the in-mission UNJAM (clears + Jammed(5)); HOLD 3.0s = DumpAmmo whole bay → NoAmmo(7) roach motel (only + re-arm/respawn Reset clears); novice locked out of eject. +- **Port [T2]:** same machine (`projweap.cpp:751-968`); tap-unjam + semantics match (the #166 advice rides on it). +- **Verdict:** FAITHFUL. + +### 18. Jam roll (ballistic + missile racks) +- **Binary [T1]:** @004bbfcc: rolled after each shot whenever simLive AND + the weapon's own heatAlarm != 0; p = 0.41·T/Tfail (0.41 byte-confirmed) + clamped [0.05, 1.0]. Practically vet/expert-only (std/novice heat model + off → never heat-alarms). +- **Port [T3 marked bring-up gate]:** rolls only at heatAlarm >= + DegradationHeat (`projweap.cpp:692`) — added when temps were static; + now that the heat economy is live it masks authentic warm-weapon jams. + Binary rolls at ANY nonzero heat alarm. +- **Verdict:** KNOWN-DIVERGENCE [T3] (minor; REMOVE the extra gate next + build — announced in the field guide). + +### 19. Incoming-missile warning +- **Binary [T1 registration, T4 consumer]:** Missile ctor registers with a + MECH target via a virtual on target+0x418; the consumer (threat lamp? + beeper tempo?) is unlocated in the decomp. +- **Port [T3]:** structurally dead: the authored beeper/tempo attributes + latch (`mech4.cpp:8536`) but the only producer lives in the dormant + Missile TU — the pool never reports; the beeper never fires (#83). +- **Verdict:** OPEN (needs the consumer decomp + era testimony — question + shipped in the field guide). + +--- + +## Contradictions resolved this audit (evidence log) + +1. **GAUSS (the headline):** BTL4.RES @0xf16e6 GAUSS record = classID + 0xBCD (bytes `cd 0b`, size 0x1D0); class histogram 78×0xBC8 / 16×0xBCD + / 30×0xBD0 / 14×0xBD4, zero 0xBCE; port factory 0xBCD → + CreateProjectileWeaponSubsystem (`mech.cpp:1939-1942`). The fielded + Gauss is FAITHFUL on both sides; the earlier "port damage is an + invention" audit examined the content-dead 0xBCE class. CLASS-level + claim (@004bdca4 no-op) stands. +2. **K constant:** `_DAT_004b9c98` dumped: CODE file+0xb9a98 = `0000803f` + = 1.0f. [T4] closed → [T1]; undamaged effRange = exactly authored + WeaponRange; port's 1.0 (`mechweap.cpp:558`) correct. +3. **AC launch-speed constants:** @0x4bc678 = 2.0f (float32); @0x4bc67c = + 0.10204081 = 1/9.8 as a 10-byte x87 EXTENDED (`8a6c379943c6fad0fb3f`) — + not float32-decodable, hence the stale "unresolved". projweap.cpp 1.0f + stand-ins + dropped muzzleHeight term now closable. +4. **Jam recovery:** @004bb9b8 (part_013.c:15709-15723): eject RELEASE + path calls FeedAmmo and unconditionally SetLevel(weaponAlarm, 3 + Loading) when rounds remain — a tap clears Jammed(5). missileB's "jam + permanent until re-arm" refuted; in-sortie unjam = YES (novice locked + out). +5. **nrk flight model:** BTL4.RES type-15 rid=327: turn 360°/s, burn 10s, + accel 300, climb 50, splash 30. dataA right; missileB's "no loft" + corrected. KB sweep owed (combat-damage.md "LRM … the only climber"). +6. **SRM6 count-4 variant:** the record authors MissileCount=4, Damage=20 + → 5.0/missile (dataA's 3.33 assumed count 6). ALL per-chassis + attributions ride the nearest-name heuristic — re-verify against the + egg/VehicleTable before any chassis-specific claim ships to the vets + (the field guide deliberately names no chassis in Appendix A). +7. **Splash baseBurst:** part_013.c:18271-18290: cluster roll stored to + +0x338 for direct dispatch, then IF splash enabled the ORIGINAL full + count is RESTORED (+0x338 = uVar3 at :18284) before SplashDamage — the + port's full-missileCount baseBurst exactly faithful. +8. **PPC display-scramble callee:** DAT_004efc94+0x4c = the GAUGE RENDERER + (`btl4mppr.cpp:249`, `btl4galm.cpp:404`) — the Energy-hit rider is a + gauge/MFD-side scramble virtual. Still open: what slot +0x4c does + visually. Port does not implement the call; the generator-short rider + IS ported — statuses differ. +9. **SRM2 flight profile — UNRESOLVED:** dataA says the ava1 SRM2 bin + feeds 'strk'; missileB groups SRM2 under 'srm'. The weapsub scan + printed weapons only (no bin ammoModelFile column). Needs the bins + pass before any SRM2 homing claim ships (field guide explicitly + declines to state it). +10. **@004bb9b8 relabel:** it is the EJECT handler, not fire-consume; + FeedAmmo @004bd4f4 is the consume. Carry into any KB address table + that copied the old tasking label. + +--- + +## Corrections owed — HELD for the #171 group decision (Oracle HOLD) + +- Commit 80037a7's "Gauss deals NO damage in the shipped binary / port + damage is an invention" framing. +- `scratchpad/night16/queued_171_comment.md` — Gauss section + the queued + era question (the reframed question now lives in the field guide). The + #112/#168 sections are correct as written. +- `context/decomp-reference.md` §SS5 and `context/combat-damage.md` Gauss + claims. +- Any `projweap.cpp` / gauge banner repeating the no-damage framing. + +## Stale banners confirmed present (sweep with the next projweap change) + +- `projweap.cpp:990` still reads "the #168 flight-contact model" above the + implemented hitscan body — same failure genus as the stale banner that + caused #168 (gotcha: verify banners when the body changes). +- The "unresolved" comments on `_DAT_004bc678`/`67c` are now false + (constants byte-confirmed, see entry 7). + +## Actionable closures queued (next build) + +1. AC tracer launch speed: land 2.0f + 1/9.8 + the muzzleHeight term in + `projweap.cpp`; delete the stale comments and the :990 banner. Cosmetic; + era question 14 (round pace) tunes the final feel. +2. Jam roll: remove the `heatAlarm >= DegradationHeat` gate + (`projweap.cpp:692`) — binary rolls at any nonzero heat alarm. + Announced to the vets in the field guide §9. +3. PPC gauge-scramble rider: BLOCKED on era testimony (field guide §3) — + build the visual only after the group answers. +4. Missile bystander sweep: design exists; field guide §6 arms the Friday + watch item. + +## Era questions shipped to the vets + +The 14 questions live in `docs/WEAPONS_FIELD_GUIDE.txt`, distributed into +the per-section "WE NEED YOUR MEMORY" blocks: Gauss killed + carrier +chassis (headline, §5); PPC hit visuals + generator short (§3); splash +proximity + shooter self-splash (§7); ballistic recoil, AFC25 eaten +trigger, out-of-range round fate, round pace (§4); vet-only jams + +tap-eject unjam, NoAmmo latch with ammo remaining (§9); gear-wrap brick +(§2); incoming-missile warning (§10); generator switching mid-charge, +out-of-range beam (§1); rack-name quirks, homing agility + Narc-did- +nothing (§8). diff --git a/docs/WEAPONS_FIELD_GUIDE.txt b/docs/WEAPONS_FIELD_GUIDE.txt new file mode 100644 index 0000000..f7ce052 --- /dev/null +++ b/docs/WEAPONS_FIELD_GUIDE.txt @@ -0,0 +1,448 @@ +============================================================================= + BT411 -- WEAPONS FIELD GUIDE: EVERY WEAPON, AS THE ORIGINAL BUILT IT + Updated 2026-08-13 -- reconstruction review edition, for the whole group. +============================================================================= + WHAT THIS IS: we have now read the original machine's firing code for + every weapon family and compared it, behavior by behavior, against what + our port does. This document is the result. For each family you get: + what the shipped machine really did, what our port does today, what + changes in the next build, and -- where the code alone cannot settle + it -- what we need from your memory. + + HOW TO REVIEW: you flew the real pods; we only read their code. Read + each section and mark anything that CONTRADICTS your memory of the + machine -- and anything that confirms it. Silence is not confirmation: + if a section simply matches what you remember, a one-word "matches" is + genuinely useful data. + + HOW TO REPLY: in the Discord weapons thread, one reply per section, + starting with the section name in caps (e.g. "GAUSS:"). Then + MATCHES / CONTRADICTS / CAN'T RECALL, then whatever detail you have. + Which floor, which revision, which mech you flew -- machine-room + details turn weak memories into strong evidence. + + ONE RETRACTION UP FRONT: the last issues handout (#27) told you + ballistic rounds could now "genuinely MISS a moving target". The + deeper dig behind this document proved that framing wrong: the + original decides a cannon hit AT THE TRIGGER, and the round you watch + fly is a tracer drawn for show. We were wrong; details in the + AUTOCANNONS section. Your review of that section is part of the + group's sign-off on the correction. +============================================================================= + +----------------------------------------------------------------------------- +1. LASERS -- SMALL / MEDIUM / LARGE, STANDARD AND ER +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + - A charge-and-release energy weapon. No ammo, no jam. Six marks, one + mechanism -- only the numbers differ (Appendix A). No pulse lasers + exist anywhere in the shipped content. + - Firing needs three things at the trigger: a LOCKED target, your + view actually on the target (the weapon only arms while you are + looking where it points), and the target inside effective range. + - The beam is instant. The hit is decided the moment you fire -- no + travel time, no leading. What you see is the discharge drawing + itself, plus a 0.2-second afterglow that tracks the target. + - Damage scales with the SQUARE of the charge: a full-charge shot + does the listed number; a half-charge release does a quarter. + - Out of range: the trigger works and the beam draws, but the damage + is silently thrown away. No hit, no denied tone we can find. + - Effective range shrinks in proportion to damage on the body zone + carrying the weapon: a half-wrecked arm fires at half reach. An + undamaged weapon reaches exactly its listed range -- confirmed + down to the byte this week. + - Overheat is a hard stop: a heat-failed laser quits outright. There + is no gradual weakening on the way down. + - Each hit lands on ONE panel of the target. + +OUR PORT TODAY + Same machine, verified live end to end. The beam is drawn from the + real laser-tube art. Charge timing is smoothed for modern frame + rates -- a robustness measure, not a behavior change. (The #164 + stuck-beam guards are already in.) + +CHANGING IN THE NEXT BUILD + Nothing mechanical. + +WE NEED YOUR MEMORY + - Firing past range: do you remember shots that visibly fired at a + distant target and just did nothing? That is what the machine did. + - Generator switching mid-charge: did switching or re-routing + generators while a laser was charging COST you the in-flight + charge (with an electrical alarm)? A yes pins down a control path + we have not been able to identify from the code alone. + +----------------------------------------------------------------------------- +2. THE CHARGE GEAR (ALL ENERGY WEAPONS) -- AND THE BRICK THE ARCADE SHIPPED +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + Veteran/expert pilots could cycle an energy weapon's charge gear + (four settings). The machine shipped with a latent flaw: cycling + PAST the top gear wrapped to the bottom without resetting the firing + state. The stored charge now sat above the new gear's release + window, the output read zero, and the weapon went permanently dark + -- charged, lit, and unable to fire until re-arm. The arcade + shipped this. + +OUR PORT TODAY + We deliberately rescue it: an overcharged weapon counts as loaded + and fires (#21; 38 rescues proven on the bench). This is the port's + ONE deliberate deviation in the energy lane, and it stays on the + deviations list so nobody mistakes it for the original. + +CHANGING IN THE NEXT BUILD + Nothing -- unless the group votes for the authentic brick. + +WE NEED YOUR MEMORY + - Did cycling a laser's gear past the top setting ever leave the + weapon DARK -- charged but refusing to fire until re-arm? If pods + genuinely ate weapons this way, some of you will remember it. + +----------------------------------------------------------------------------- +3. PPC AND ER PPC +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + - The firing machine is literally the laser's -- the same code, the + same rules (lock, look, range gate, square-law charge). Everything + distinctive is the numbers: hardest energy hit (12; ER 16), + longest energy reach (900 / 950), a slow 5-second recharge, and + the only BLUE pip. + - What makes a PPC special is what it does to the VICTIM. Energy + hits -- and only energy hits -- carry two riders: + (a) DISPLAY SCRAMBLE: every energy hit pokes the victim's cockpit + display system once -- some kind of gauge/MFD disturbance per + hit. What it looked like and how long it lasted is NOT + recoverable from the code. + (b) GENERATOR SHORT: if the struck zone holds critical equipment, + one random critical component takes a forced short -- + generator brownout, charge stall, cockpit electronics dip. + +OUR PORT TODAY + The firing machine and the generator short are in and verified. The + display scramble is NOT implemented -- right now your screens shrug + off a PPC hit, and that is a known gap on the polish list. + +CHANGING IN THE NEXT BUILD + Not yet. We will not invent the visual: the scramble gets built + AFTER your testimony, not before. + +WE NEED YOUR MEMORY (this one really matters) + - Taking a PPC hit, from inside the pod: what happened on your + screens? Static or interference? A flash? Gauges and MFDs going + briefly to garbage? How long did it last? + - Separately: after taking PPC hits, do you remember the generator + browning out or your weapons losing charge (the short rider)? + +----------------------------------------------------------------------------- +4. AUTOCANNONS -- AFC25 / AFC50 / AFC100 +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + - The cannons are point-and-hit, not fly-and-hit. At the trigger, + with a lock, the machine checks the range; in range, the damage + lands THEN -- one solid ballistic hit on ONE panel of the locked + target. The shell you watch fly is a TRACER, drawn for show after + the decision is already made. + - No leading. The lock does the aiming, and a dodging target does + not shake a round already fired. + - Out of range: the round is consumed, the tracer flies anyway, and + the damage is silently discarded. No hit, no warning. + - Recoil: every shot with real punch (damage over 3) kicks your own + pod up and back through the gyro, in proportion to the shot -- + the AFC100 kicks about 3.5 times as hard as the AFC25. + - Jams roll after each shot only while the weapon itself is running + a heat alarm -- in practice veteran/expert only, since the lower + sim levels never heat-alarm a weapon. Chance grows with weapon + temperature. + - One panel per pull. The old "shotgun across zones" spread in our + port (#112) was our bug, never the machine's. + +OUR PORT TODAY + Until now our cannons flew a real shell that could miss -- + reasonable, and wrong. The trigger-time machine is now implemented + against the original's code line by line and bench-verified: full + batches land as one hit, out-of-range rounds are consumed and + discarded. What it needs now is a real night of fire. + +CHANGING IN THE NEXT BUILD + - The trigger-time cannon goes live in the build you test next. + This is the big #171 correction -- please hammer the cannons. + - The tracer's flight speed: the original derives it from the gun's + range and muzzle height (roughly one second to cross full range). + Our stand-in speed was close by accident; the recovered authentic + numbers go in. + +WE NEED YOUR MEMORY + - When YOU fired cannons, did the pod's view visibly kick up and + back (distinct from being hit)? Was the AFC100's kick noticeably + harder than the AFC25's? + - The AFC25 specifically: did it occasionally eat a trigger pull + silently -- a click, no shot, on an apparently ready gun? (Its + ammo feed timer exactly equals its firing cycle -- the only gun + where the two can race.) + - Firing beyond range: did the visible round fly on forever, or + vanish? (The code consumes the round and discards the damage; the + tracer's visual fate is the one part we cannot recover.) + - Round pace: roughly how fast did cannon rounds visibly fly? + About a second to cross full range, or very different? + +----------------------------------------------------------------------------- +5. GAUSS ** THE HEADLINE QUESTION ** +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR (as best we can prove it) + - The Gauss the pods actually fielded is built ON THE CANNON + MACHINE. The shipped content authors it as an autocannon-class + weapon: about 20 points of solid shot out to 900 (tied with the + AFC25 for longest ballistic reach), a slow 8-second cycle, only + 16 rounds, runs nearly cold, and the only YELLOW ballistic pip. + It hit, and it hurt. + - The code ALSO contains a second, "true" Gauss-rifle mechanism + that charges up and does NOTHING when fired -- no damage, no + heat, nothing. No shipped content anywhere uses it. Dead code. + - Full honesty: for a while our audit believed the pods fielded the + do-nothing Gauss and that our port's Gauss damage was an + invention. Reading the raw content bytes settled it the other + way -- the fielded Gauss is the cannon-class one. + +OUR PORT TODAY + Same content, same machine: our Gauss already deals cannon-class + damage. Port and original agree. Nothing changes. + +WE NEED YOUR MEMORY (the headline) + - Confirm the Gauss KILLED: heavy single hits at extreme range, a + slow cycle, a small magazine, a gun that never warmed up, and a + yellow pip on the display. We expect YES. + - Which mech do you remember carrying it? (We believe the Loki; + your memory checks our content map.) + - If instead you remember a Gauss that charged up and did NOTHING + when fired -- say so loudly. That would be evidence that some + floor revision shipped content for the dead mechanism, content + we do not have. + +----------------------------------------------------------------------------- +6. MISSILES -- HOW EVERY RACK REALLY FIRES +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + - Missiles are the one family that genuinely FLIES. Everything else + in the game decides its hit at the trigger; a missile earns its + hit in the air. + - Lock required, same as every weapon. There is no dumb-fire path + anywhere in the machine -- the trigger will not take without a + lock. (No special Streak lock code exists either; all racks fire + through the same gate.) + - ONE flying round was drawn per salvo, plus one explosion -- the + pod drew a single missile even for a 15-tube volley. The damage + bookkeeping rides that one round. + - The seeker LEADS: it flies a constant-bearing intercept toward + the exact spot on the target picked at the moment of fire, and + detonates on a close-proximity fuze with a swept contact check. + - If the target dies mid-flight, the lock drops and the round goes + stupid. + - A rack's listed "range" is fire-control display only. Real reach + is physics: motor burn, then up to 10 seconds of coasting. Rounds + that hit the floor die; rounds that time out fizzle. + - On impact, the cluster roll: out of an n-missile salvo, between + roughly a quarter and all of them count as hits, scattered across + the victim's zones with a fresh scatter every burst. + +OUR PORT TODAY + The whole chain is live-verified: a 382-impact night corpus matches + the original's cluster roll exactly, the fuze and lock-drop are + benched, and Streak impact speed measures at the authentic value. + Presentation deliberately differs: we draw the full ripple of N + rounds (the lead round carries the damage, the rest are tracers) + with a small tube spread. The damage economy is identical. + +CHANGING IN THE NEXT BUILD -- AND WHAT TO WATCH + The bystander gap. The original's rounds swept everything in the + flight path every tick -- a third mech between shooter and target + could eat someone else's missile. Our rounds currently contact only + the locked target and the terrain: a mech in between gets flown + through, and only splash can touch it. This is the largest + remaining missile-physics gap; the fix is designed but not landed. + WATCH FRIDAY: if you take missile hits aimed at someone else -- + beyond splash distance -- report it with the shooter's name. + +----------------------------------------------------------------------------- +7. MISSILE SPLASH +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + Splash was LIVE on the pods -- every stock mission enables it. An + impact splashes a radius of about 30 around the hit point; strength + scales from the FULL rack size and falls off steeply with distance; + the mech that took the direct hit is excluded from its own splash. + One thing the code cannot prove either way: whether the SHOOTER was + protected from splashing themselves at point-blank. + +OUR PORT TODAY + Same math, verified -- including the full-rack-size splash strength, + pinned to the original's code this week. We exclude both the direct + victim and the shooter. The on/off wiring differs slightly from the + original in a way that only matters for custom missions -- a site + option question for later, not a Friday one. + +WE NEED YOUR MEMORY + - Do you remember splash hurting mechs standing NEAR an impact? + - Critically: could you hurt YOURSELF firing missiles point-blank + into a wall or an adjacent mech? Our port says no; the original's + code will not tell us. Your memory is the tiebreaker. + +----------------------------------------------------------------------------- +8. HOMING AGILITY, THE LRM ARC, AND THE NARC +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + - Three flight profiles exist in the shipped content: + LRM round: sluggish 60 deg/sec turn, 10-second burn, and the + LOFT -- at long range the seeker aims high and + the round flies the signature climb-then-plunge + arc. + Streak round: 360 deg/sec turn -- six times the LRM -- short + 3-second burn, no loft. The round that out-turns + evasion. + Narc round: the surprise -- Streak-grade 360 deg/sec tracking + PLUS the loft PLUS the long 10-second burn. A + light rack that flies like a hawk. + - There is NO beacon mechanism anywhere in the machine. The Narc + never tagged anyone for anything; it is a light, hard-tracking + rack and nothing more. + - Several racks LABELED "LRM" actually feed Narc-profile rounds, + and at least one "SRM6" feeds Streak rounds. Two visually + identical racks homing very differently -- one sluggish, one + snapping onto target -- is authentic, not a bug. + - Rack names lie in other ways too, all authentic authored data: + an "SRM6" that fires 4 tubes, an "SRM4" that fires 2, LRM10s that + hit nearly twice as hard on one chassis as another. + +OUR PORT TODAY + Same data-driven resolution -- the racks read the same content, so + all of the above carries over for free. One detail we are NOT + stating yet: which profile the 2-tube SRM racks fly -- our two + content reads disagree and the pass that settles it has not run. + +CHANGING IN THE NEXT BUILD + Nothing mechanical. + +WE NEED YOUR MEMORY + - Do you remember visually identical LRM racks homing very + differently on different mechs? And can you confirm the Narc did + nothing special -- no tag, no beacon, just a fast light rack? + - Do you remember SRM racks that fired FEWER missiles than their + name -- a 4-tube "SRM6", a 2-tube "SRM4"? Or LRM10s/LRM15s that + hit noticeably harder on one chassis than another? + +----------------------------------------------------------------------------- +9. AMMO, EJECT, AND JAMS (CANNONS AND RACKS) +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + - The reload countdown runs only while the weapon's generator route + is powered, and a HOT generator reloads slower. Below minimum + voltage the countdown freezes entirely. + - The EJECT control (novice pilots are locked out of it): + TAP = eject one round, and the weapon resets to loading if + rounds remain. This is the in-mission UNJAM. + HOLD (3 seconds) = dump the entire bay. The weapon is out of + ammo for good until re-arm or respawn. + - Jams roll after each shot while the weapon itself runs a heat + alarm; the chance grows with weapon temperature. Standard and + novice sims never heat-alarm a weapon -- so in practice only + veteran/expert pilots ever jammed. + +OUR PORT TODAY + Same machine, tap-unjam included -- it is the mechanism behind + #166's "tap EJECT" advice. One divergence: our jam roll currently + waits for a higher weapon temperature than the original -- a + leftover safety from before the heat economy went live. + +CHANGING IN THE NEXT BUILD + The leftover jam gate comes out. Warm cannons and racks on + veteran/expert may jam a touch more often. That is the authentic + rate. + +WE NEED YOUR MEMORY + - Did weapons only ever jam for veteran/expert pilots? And could + you CLEAR a jam mid-sortie by tapping EJECT to cycle one round + out? + - Did a rack or cannon ever go permanently dark WITH ammo remaining + after sustained fire? At what firing intensity? (Field case from + our own nights: an SRM6 latched out with 19 rounds left. Whether + that could happen at authentic intensity is an open question.) + +----------------------------------------------------------------------------- +10. INCOMING-MISSILE WARNING +----------------------------------------------------------------------------- +THE ORIGINAL'S BEHAVIOR + Every missile launched at a mech announces itself to its target -- + the machinery for a warning is there. What CONSUMED that + announcement (a warning tone? a beeper tempo change? a threat lamp?) + we have not located in the original's code. + +OUR PORT TODAY + The beeper plumbing exists but nothing feeds it -- the warning is + structurally dead (#83 on the known-gaps list). + +WE NEED YOUR MEMORY + - Did the pod audibly warn you of inbound missiles? A tone, a tempo + change, a lamp -- anything. If it did not, #83 closes for free. + If it did, describe it and we build exactly that. + +----------------------------------------------------------------------------- +APPENDIX A -- THE AUTHORED NUMBERS (straight from the shipped content) +----------------------------------------------------------------------------- +Range is in the same units your fire-control shows. Cycle in seconds. + +ENERGY (damage = full-charge shot; scales with the square of charge) + WEAPON DMG RANGE CYCLE HEAT/SHOT + SLaser 1.5 150 1 0.75 + ERSLaser 2 225 1 1.5 + MLaser 2.5 350 2 2 + ERMLaser 3.5 500 2 3.5 + LLaser 5 600 4 6 + ERLLaser 6 750 4 8.5 + PPC 12 900 5 11 + ERPPC 16 950 5 16 + Reach shrinks with damage to the carrying zone: listed x (1 - zone + damage). An undamaged weapon reaches exactly the listed range. + +BALLISTIC (one panel, decided at the trigger; recoil kick = dmg/16) + WEAPON DMG RANGE CYCLE NOTES + AFC25 7 900 2 feed timer = cycle (see sec. 4) + AFC50 13 750 4 + AFC100 25 400 8 hardest hit, shortest reach + GAUSS 20 900 8 16 rounds, yellow pip, near cold + Cannons and racks run effectively cold next to the energy bank. + +MISSILE RACKS (DMG = whole-salvo total; per-round in parentheses) + RACK TUBES DMG CYCLE + SRM2 2 10 (5.0) 2 + SRM4 4 35 (8.75) 3 + SRM4 4 20 (5.0) 3 + SRM4 2 10 (5.0) 2 + SRM6 6 50 (8.3) 5 + SRM6 6 35 (5.8) 5 + SRM6 4 20 (5.0) 3 + LRM5 5 10 (2.0) 2.5 + NRK5 5 10 (2.0) 2.5 + LRM10 10 35 (3.5) 4 + LRM10 10 20 (2.0) 4 + LRM15 15 50 (3.3) 6 + LRM15 15 35 (2.3) 6 + LRM20 20 65 (3.25) 9 + Same rack name, different numbers = different chassis fits, all + authentic. We are re-verifying the per-chassis map before naming + which mech carries which variant. SRM racks display range 800; + LRM/NRK racks display 6000 -- display only; real reach is flight + time. Cluster roll on impact: of n launched, between about n/4 and + n count as hits. + +FLIGHT PROFILES (authored on the round, not the rack) + LRM round: turn 60 deg/s burn 10 s loft YES + Streak round: turn 360 deg/s burn 3 s loft no + Narc round: turn 360 deg/s burn 10 s loft YES + All rounds splash radius 30 on impact. After burnout a round coasts + up to 10 seconds before fizzling. + +============================================================================= + HOW TO REPLY (again, because it matters): Discord weapons thread, one + reply per section, section name first, then MATCHES / CONTRADICTS / + CAN'T RECALL and your detail. "Matches" alone is real data. The GAUSS + and PPC-HIT questions are the two we cannot answer without you. +=============================================================================