3109cfc49a672018fa7004c7f6ee1f7896ec5be6
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5d6ded73f0 |
#110: cross-pod verified BOTH ways -- the cascade replicates, and peer fire alone drives it
Two two-node benches close the last stated gap ("no two-node run has watched a
peer's view of an arm death"), the second at the user's insistence on the REAL
field composition after the first used the self-damage scalpel:
1. mp_armchain.sh (scalpel): B self-destroys dz_rarm mid-fight. A's screen
receives the whole cascade -- [zone-repl] dz_rarm lvl 0->1 AND the cascaded
dz_rgun lvl 0->1 -- plus the respawn reset coming back clean (1->0). B's
post-cascade AFC pushes turned out to be the RESPAWN RE-ARM, correct
behavior, not a gate failure. (Also confirmed: the self-damage harness
dispatches a real Entity::TakeDamageMessage -- the identical path a peer's
round takes, so the scalpel and the field share every line from the handler
down.)
2. mp_armgrind.sh (the field composition): stand-off at 180, NO self-damage
anywhere, A grinding B with real cross-pod fire for six minutes. On B:
* 25 incremental arm-zone hits from A's weapons via the cylinder tables
(dz_rgun reached 1.0 from pure accumulation -- 15 cascades on rehits)
* dz_rarm finished by B's OWN AFC bay cooking off (AmmoBinAFC100 BAY FIRE
350, half into dz_rarm) -- itself lit by A's fire crits: peer-originated
end to end
* [cascade] zone 9 -> AFC100 + AmmoBinAFC100 + Condenser6 force-failed,
fire gate refusals logged
On A: [zone-repl] dz_rarm 0->1 and dz_rgun 0->1 -- the shooter SEES the arm
and pod die. B symmetrically received A's torso deaths.
Also: DamageZone::ReadUpdateRecord gets a change-only [zone-repl] diagnostic
(BT_MP_LOG) -- the probe that made the peer side measurable; mp_armgrind.sh
opens with the stale-node taskkill the other benches already had (a leftover
node from an aborted launch joined a later lobby as a third instance).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
614849b4a6 |
#110 coverage: all 8 chassis + all 3 weapon-class gates verified through ZONE death
Answering "are you 100% positive this works for every weapon type" -- it was not a yes when asked, and the gaps were closed with measurement rather than assurance: 1. AUTHORED DATA, all eight chassis (zonesweep.sh; the [zone-armor] dump now carries the zone NAME): every arm zone AND every missile-rack zone on every chassis authors descend=1 (ava/bhk/lok/mad/own/snd/thr/vul); every gun/rack zone lists 1-4 critical subsystems; doors are inert (0/0/0); bhk uniquely adds destroySibs=1 on its arm chain. No chassis is missing the cascade authoring. 2. WEAPON-CLASS GATES, end to end through a ZONE death (not direct weapon destruction, which was #86's verification gap): ballistic AFC100 (projweap gate1) -- dz_rarm, ava1 [prior commit] energy PPC (emitter gate) -- dz_larm, ava1 [prior commit] missile NRK5_2 (projweap gate1) -- dz_rmissle, own1 [this pass] [cascade] zone 12 -> NRK5_2 + AmmoBinNRK5_2 force-failed [ammo] NRK5_2 -> NoAmmo (gate1): destroyed=1 All three fire-gate code paths are now exercised by the cascade. 3. One anomaly chased to ground rather than waved off: the Owens rack cascade also killed Avionics/HUD/Searchlight/ThermalSight -- zone 15 dz_searchlight, an authored CHILD SEGMENT of the missile rack (the sensor mast sits on the shoulder pod). Authored skeleton + authored descend flag, walked faithfully. Remaining surface NOT bench-verified, stated plainly: cross-pod -- the cascade is master-authoritative (crit plugs bind on masters only) and the resulting alarm states ride the existing weapon update records, but no two-node run has watched a peer's view of an arm death. The field re-test (Lynx/Conn Man's own audit, in MP) covers exactly that. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
06adaee523 |
#110: the zone destruction cascade is LIVE -- an arm now takes its gun pod with it
Lynx: "You can destroy an upper arm, and the gun pod is intact and can still fire." Conn Man's audit: three chassis, both arms, reproducible. And the user is right that this family was claimed fixed before: #86 gated fire on the WEAPON's own destruction and was verified by destroying the weapon directly (BT_KILL_SUBSYS) -- the field scenario was the ARM ZONE dying with the weapon subsystem healthy, which that bench never reproduced. Oracle's 693-night "I can still fire destroyed energy weapons" was almost certainly this mechanism. ROOT CAUSE -- a silent stub. Mech__DamageZone::RecurseSegmentTable @0049cad4 was transcribed faithfully... against three local shim types whose iterators unconditionally return NULL: struct SegmentIterator { DZRef *Next() { return 0; } }; struct SegTableX { SegmentRecord *operator[](int) { return 0; } }; The cascade fired on zone death (bench: 72 [cascade] lines), "descended", and touched nothing. Every line read correct; none of it did anything. THE REAL WALK (decomp re-read, FUN_0049cad4): iterate the mech's segment table (mech+0x300, vtbl+0x34 GetNth) to this zone's segment, then destroySiblingsOnDestruction (Wword 0x68): recurse every other zone on the SAME segment (seg+0xD0), setting graphic state 2 (Gone) descendOnDestruction (Wword 0x67): recurse every zone on every CHILD segment (seg+0xE8 -> child+0xD0) -- the arm takes the gun The engine ALREADY HAS both structures: EntitySegment::damageZoneTable @0xD0 / childIndexTable @0xE8 (TableOf is 0x18 -- byte-identical to the decomp offsets), populated at stream time by JMOVER.cpp:373 [T0]. The stub was never necessary. Implemented with the engine iterators via two new read accessors on EntitySegment (SEGMENT.h); the binary's asymmetry is reproduced as-is (the sibling loop checks graphic state != 1, the child loop does not; re-hits on a 1.0 zone re-run the cascade -- idempotent in effect). VERIFIED (ava1, self-damage to one zone, autofire everything): dz_rarm -> [cascade] zone 9 -> zone 17; AFC100 + AmmoBinAFC100 + Condenser6 ForceCriticalFailure'd; "[ammo] AFC100 -> NoAmmo (gate1): destroyed=1"; torso LRM5/SRM2 keep firing (correct) dz_larm -> [cascade] zone 2 -> zone 6; PPC + Condenser4 force-failed; "[emitter] 'PPC' fire REFUSED (destroyed=1)" x4998 -- the emitter gate now logs refusals BY NAME (the FIRED line never named its weapon, which is how #86's verification gap survived) regression smoke: frame time 7.13/7.20ms, 0 asserts, 0 cascades in ordinary combat (they fire only on genuine zone deaths) Authored data (now dumped under BT_DMG_LOG): descend=1 on exactly the four arm zones (ava1: 2/6/9/17), destroySibs=0 everywhere -- so legs/torso behavior is untouched by this change. KB: combat-damage.md cascade section; reconstruction-gotchas #26 (the silent-stub trap: a shim that returns EMPTY converts a reconstruction into fiction that reads correct -- shims must Fail() loudly or log their emptiness). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
da70bd58b2 |
#84: the replicant salvo now HOMES AT THE LIVE TARGET -- the stale-point double detonation is gone
Oracle (674): "missile appear to register hit explosions twice, once where
target was and again where the target is". Rajel (693): "once where the mech
was when I fired and on the expected impact".
MECHANISM, measured on two nodes (BT_PROJ_LOG "DET at" now logs EVERY contact
detonation, including damage-0 rounds, which were invisible before): the
replicant salvo mirror pushed rounds with NO entity handle at the FROZEN
fire-time aim point, and the pool's contact test is proximity to p.targetPos --
so mirror rounds "contacted" the empty air where the target USED to be and
detonated there, on every peer, every salvo (45 salvos -> 234 frozen-point
air bursts in a 200s bench). The true impact appears at the live position
(the shooter's own homing rounds on his node; the victim's damage reaction on
peers) -- two sites per salvo, exactly as reported.
THE BINARY'S MODEL (CLASSMAP, Missile flight-entity cluster): missiles are
ENTITIES with authoritative/GHOST Performance variants (Projectile
PTR_LAB_005129e8 / 005129f4) and their own WriteUpdateRecord (@4bef4c, slot 7)
-- peers ran ghost missiles updated from the wire and saw the TRUE trajectory.
One explosion, correct place, every node. The frozen-point mirror is the port
infidelity (the entity Missile itself stays blocked by the documented 2007
Entity-base mismatch; mislanch.cpp:301).
FIX: the MissileLauncher update record now carries the locked target's EntityID
(salvoTargetID; EntityID::Null = point fire). The mirror resolves it on the
receiving node via HostManager::GetEntityPointer (engine T0, an index-socket
Find -- NULL-safe on any ID), refuses non-mechs via BTIsRegisteredMech, and
pushes the mirror rounds WITH the handle -- they re-lead on the live local
replicant exactly as the master's own rounds do, and detonate at the true
position. Guards: record-length gate (a short record from an older build has
no ID field -- its tail would be garbage and must not resolve) + Null check +
registered-mech check.
VERIFIED (two nodes, 200s, missile autofire both ways):
* every record arrives len=52/52 with sane aims ([mlrec] diag)
* 22/46 salvos resolve (tgtID=3:22 -> the victim's local master) and their
mirror rounds home: the frozen-air DET population fell 234 -> 102, the
live-homing population rose to 155/207 per node
* the unresolved remainder is BENIGN and correct: EntityID::Null point fire
plus hostID=-1 LOCAL entities -- i.e. the victim's WRECK, which autofire
keeps shooting after the kill; a wreck does not move, so the frozen aim IS
its true position
Downstream expectations: Ronin's smoke-screen (#114) should drop by ~the mirror
half, and the audio census (#32) loses the duplicate Static3DPatchSource
explosion sounds on peers -- both to be read from the next field logs.
Also in this commit: [projectile] DET diagnostic (every contact detonation with
position/damage/handle/aim), [mlrec] record-arrival diagnostic (len/recID/
subsys/counter/aim, capped 200), scratchpad/night9/mp_double.sh.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
3354db4bd1 |
#32: RETRACT the retention diagnosis; count what matters (steals + true drops); name the saturating class
The reopen said "the pool fills and never returns a source". The 30s census in
the SAME field logs disproves it: free returns to ~227-230 between bursts and
reuses climbs ~20/s all session. free=0 on the failure line is true by
DEFINITION at the instant of a failed acquire -- the third instance of the
counter-sampling trap (live=256-vs-6, then hsparm greps, now this), read off the
alarm line instead of the trend line.
WHAT THE LOGS ACTUALLY SHOW
* The pool cycles; release-on-stop exists and works (the engine steal loop).
* During firefights CONCURRENT demand exceeds 240 and the priority steal loop
services each new sound by killing an old one -- continuously through
combat (failures spread across every decile of every combat session).
* Idle standing demand is ~13 sources. My "each component holds its SourceSet
to entity teardown, ~20-25 per mech" narrative was wrong.
* The raw ACQUIRE FAILED line count (6.8k-19k per log) is NOISE: the steal
loop retries after every failed attempt, so lines accumulate per EVENT and
most events still play via a steal. True drops were never counted.
CHANGES
1. Census now carries steals= and drops= (drops = the steal loop ran dry and
the sound NEVER played) plus a per-class drop histogram
("[audio] dropped by class: {class 1005 x4v: N} ...") -- all ungated, so
the next field logs are decisive instead of suggestive.
2. The ACQUIRE FAILED print is rate-limited to 1/30s and now names the
requesting class + voice count. 19k-line log spam distorted this triage.
3. BT_AUDIO_SOURCES=<n> now raises the POOL cap too (it previously raised the
AL context budget while the pool stayed at 240, making the field
experiment impossible to run).
MEASURED (9 mechs, missile autofire, 150s)
* cap 240: peak 130 sources, 0 fails -- demand tracks SHOOTER count, not mech
count; one shooter cannot saturate. A 6-shooter lobby pins 240.
* cap 48 (BT_AUDIO_SOURCES=64): saturation reproduced -- census
steals=223 drops=455, histogram names the classes.
* Dominant field requester (requested=4) = class 1005 Static3DPatchSource:
world-placed effect sounds, i.e. EXPLOSIONS. 1001 DirectPatchSource x1v
dominates drops at low cap; 1002 Dynamic3DPatchSource x3v present.
CONSEQUENCE FOR THE FIX ORDER: #84's stale-aim double detonation duplicates
exactly the saturating class on observer nodes. Fix #84 FIRST, then re-read the
field census; only if it still saturates does the budget experiment
(BT_AUDIO_SOURCES with frame time measured) become the play.
KB: the wrong night-9 entry in open-questions.md replaced with the corrected
diagnosis; gotcha candidate noted -- an alarm-line counter is not a trend.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
202ebbf84a |
KB + tracker: night-9 playtest (build 4.11.693)
CONFIRMED FIXED and closed: #95 (missile salvo damage), #97 (leak gauge 3 levels), #98 (loop-6 lamp), #99 (leak alarm audible). #95 deserves a note: a tester reported "LRMs still doing 3.3 damage", but that is the PER-MISSILE figure. 382 impacts across three 693 logs show the cluster being delivered correctly -- LRM20 3.25 x burst 5..20 (total up to 65), LRM15 3.33 x 3..15, LRM10 3.50 x 2..10 -- and those burst ranges match the binary's Random(n)+n/4 roll exactly. #32 REOPENED. The pooling change removed the alloc/free churn (the ~10% frame time is real) but every 693 field log still shows ACQUIRE FAILED (requested=4 live=240 pooled=240 free=0 ...) 19,182 fails (Sauron) / 15,333 (Rajel) / 6,818 (Ronin), high-water 225 of 240, starting ~1% into every session. `free=0` is the diagnosis: sources are never returned. This is precisely the risk flagged when the fix landed -- retention, not pool size. Players called audio "fine" the same night; the log disagrees. #84 still present, but the surviving explosion is a DIFFERENT mechanism from the bundled one that was fixed: "where the mech was when I fired" is the stale fire-time aim point already recorded as an open in rendering.md, i.e. an MP visual, not the message-manager path. Needs a two-node bench logging the OBSERVER -- the earlier two-node run verified damage delivery but never the visual. New: #108 ghost mech (peer never sees the death; shots still register, so it is a visual/replication desync, the inverse of #94), #109 panic/eject, #110 arm parent/child linkage (gun pod survives its mount -- three chassis, both arms; parentArtifactZone exists but only drives LOD), #111 death warp bubble shown to peers, #112 AFC shotgun spread (may be authentic Ultra-AFC burst), #113 LRM burn duration, #114 missile smoke as a smoke screen, #115 hot box, #116 Standard-vs- Expert heat gating, #117 per-chassis cockpit bounce. ⚠ A MEMBER OF THE ORIGINAL TEAM IS NOW TESTING -- "Ronin" (log user torak). He worked on the 1995 game and has played the pods recently. Treat his pod comparisons as primary evidence above reconstruction inference. First two contributions recorded in the KB: per-chassis cockpit bounce was deliberate, and NARC likely shipped as data without an implementation. ⚠ Conn Man ran the OLD build (.674) for all seven of his sessions, so his reports are not evidence about 693. His arm-linkage audit is still valuable -- nothing in 693 touched that path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |