The extended comparisons found three errors in the reconstruction: a turning animation could leave its stop transition running at the wrong speed, Arachnitron self-destruction used the wrong blast and attacker rules, and disabled weapons kept parts of their normal cockpit gauges. All three are corrected from the original instructions. A separate omission in the headless replay adapter made it continue cockpit target validation after the death camera opened; the live window already handled that transition correctly.
Added battles
| Capture | Launch and outcome | Snapshots | Exact full images |
|---|---|---|---|
campaign-5-razor-carried |
C1_05 rescue in the Razor carried from C1_04; success at 6,697 | 6,698 | 3 |
training-6-ogre-hard-night |
Ogre escort at difficulty 3, at night, with the original AI squadmate; player death at 3,421 | 3,422 | 3 |
campaign-c1_08-datalink |
Outlaw approaches its data-link objective but is disabled at 3,969 | 3,970 | 3 |
campaign-6-outlaw-return |
Actual C1_05 result, original crew reassignment to the owned Outlaw, then Q and an incomplete return at 6,000 | 6,001 | 3 |
campaign-c5_10-full |
Final lunar mission through combat and player death at 6,369 | 6,370 | 2 |
These are separate original Wine processes, using ordinary recorded device
packets, a fixed simulation delta of 81 and a controlled presentation clock.
They execute the original movement, AI, terrain, collision, weapons, damage and
drawing code. None of these five captures needs the building-component bounds
guard used in some earlier cases. Every retained state and final RESULTS.DAT
byte agrees with C++; their actual results and flags also pass back through the
original shell, with exact debrief saves and RNG states.
C1_05 and C1_06 extend one actual history to six consecutive battles. The next
original C1_07 launch, with two squad members, is retained in
analysis/missions/captured/campaign-after-six-played; its battle is not yet
part of the comparison corpus. C1_08 and
C5_10 instead start from original shell histories with supplied earlier outcomes.
The C1_08 link was not completed and C5_10 ended in death, so their campaign
victory paths remain useful further comparisons. A requested finale image at
7,000 was never reached because the original had already ended at 6,369; the
frame exporter records that reason instead of treating it as a missing image.
Process fixture reports: rescue, nighttime escort, data-link attempt, incomplete return, finale. The debrief report retains result, flag and save hashes. The hangar report contains two original crew assignments and two weapon fits, with complete saves on both sides.
Interrupted pivot stops
C1_06 first diverged in a stationary AI HERC's animation rate on tick 4,083. The original restored +100; C++ retained +43. Root heading then differed on tick 4,084 and that changed later aiming and combat.
The original code at 0x4172a0..0x4172d6 checks whether a stop animation is already
requested. If it is, it skips only the duplicate request. It still restores the
exit rate to +100 or -100. C++ had placed both operations inside the test. A HERC
that briefly resumed turning while its earlier stop remained pending could
therefore keep the slower pivot rate on its next stop.
The same review found that the original writes zero back to its turn-input stack
argument at 0x416d2e during pivot acceleration. The extracted C++ helper had
received that value by copy. Passing the reference preserves the suppression
for the rest of the control update.
tools/export_cpp_pivot_stops.py now captures 13,400 original steps across all
twenty walking chassis, alternating short turns, stops and renewed movement.
It compares the control state, animation thread and root transforms. The fixture
fails against the earlier implementation and passes with the correction. The
full C1_06 run then matches all 6,001 snapshots, its result and three images.
See native pivot-stop evidence.
Arachnitron detonation
At C5_10 tick 2,243 an Arachnitron enters Mech_RamMove's detonation path. Its
original body disappears below the map at Z=-100,000; the old reconstruction kept
it at Z=23,838. Debris and simulation RNG diverged during the same update.
Mech_RamMove starts at 0x41e488. The detonation branch at 0x41e506 makes a
radius-3,000, damage-2,000 area blast that explicitly excludes the rammer. It then
walks all 29 component slots. Every remaining active slot receives 32,000 damage,
with the rammer itself as attacker. The C++ adapter had included it in the blast
and then applied anonymous component damage, consuming different random draws
and altering the destruction sequence.
The Arachnitron's profile also sends its destroyed body into limbo. That health transition already set the correct hidden position, but movement retained the old position and wrote it back during synchronization. The state-change handler now publishes the limbo position to movement immediately. The resulting battle matches every captured field through death on tick 6,369, including the effect pools and simulation RNG.
Offline weapon gauges
C1_08's last retained cockpit image, tick 3,800, initially differed by 1,106 pixels, all within the disabled weapon rows. The earlier images were already exact.
The native ChainedWeaponSelectGadget paint path starts at 0x4426e8; its disabled
branch at 0x442772 selects PWEAPONS frame 6 and the grey font. It expands the
label rectangle to the right edge of the gauge and centres OFFLINE across it.
The ammunition and charge widgets are disabled. WeaponSlider checks that state
at 0x442b7b before drawing. C++ had kept the normal ready lamp and meter layout.
The correction reproduces those branches. All three complete images now agree,
including every palette entry, with no ignored pixels. The
initial difference report
and its images retain the
pre-fix evidence; the
current frame fixture
is checked by original_campaign_datalink_frames.
Headless death view
Once the detonation matched, the final mission's only remaining discrepancy was its selected target at tick 6,144, after the player had died. The window had already switched to the locked outside camera. The headless driver omitted that change and continued checking whether the target qualified for a cockpit display. It cleared a target that the original outside view retained.
The headless adapter now applies the window's post-tick visibility gate before the display-state update. No gameplay rule changed for this correction. The complete final-mission fixture and exact 80-byte result then agree.
Evidence and current totals
The addresses above belong to the reference Win95 English v1.1 DBSIM.EXE, SHA-256
8561aa47e5bb1bf1f837044b08e5d807e8de492784331708a7ddeabf6d44c4ad.
The instruction extract
retains the relevant bytes and disassembly.
The process corpus now contains 45 cases: 40 controlled v1.1 cases, one v1.0 prefix and four demo cases. It compares 165,525 snapshots, 192,104,802 named fields and 1,357,011,355 integer values. Separate full-image comparisons cover 223 frames, 68,505,600 pixels and all RGB6 palette entries. Nineteen actual battle outcomes have matching original debriefs. Prefixes and repeated missions are included in those case counts. The two earlier message-queue image departures remain separately documented.
Next useful additions are another continuation of the actual campaign history, a completed campaign data link, alternative late-mission outcomes, and more loadout/difficulty combinations. The coverage table distinguishes those from the scenarios already exercised.
All 177 local CTest checks pass on C++ commit 78ff259. The
verification report
retains the per-test results, log hashes and source revision.