Autopilot · write-up
Campaign incident fixes, October 3, 2026
The baseline and complete incident list are in THREE_NATIVE_CAMPAIGNS_20261003.MD. Changes are validated independently before subsequent fixes. All live tests use the resident C pilot, the official Release Hatari/DLL builds, visible fast-forward, paired AVIs and checkpoints every 150 canonical frames.
Level 2 lower-maze diver prediction
Correction to the baseline diagnosis: $50346 is not a sine-script handler.
Disassembly of R1's checkpoints/f14111-periodic.sav.ram shows these rules:
$503B6: climb five screen pixels per tick until screen Y <= 50.$5036E: track the ship's X by four pixels per tick; start diving when the horizontal difference is less than ten pixels.$503FA: descend twelve pixels per tick; reset the dive flag at screen Y >= 160.$503A6:[0,-2,-4,-2,0,2,4,2]adds a small wobble. Its index uses the game timer at$CDCplus the original object's RAM address, with an extra shift during climbing.$EAEhere ticks animation; it does not interpret motion scripts.
The old C path was fitted linear velocity. It continued a dive after the enemy had already reset to climbing. C now captures the dive flag and simulates the movement phases. Shared inspection/mission paths assume a stationary ship; candidate collision and destruction evaluation use the simulated ship position. The existing dependent-body workspace is reused; no Python movement policy or per-frame FFI call is introduced.
The game timer differs from the recording frame counter and pauses/resets
independently. Recording trailer $5842 adds its actual value. The native replay
decoder and ctypes observation layout both carry it (ABI 102). Historical files
remain readable but lack the wobble phase; their new diver forecast omits that
wobble rather than pretending the recording counter is the game timer. Do not
use those historical forecasts to claim exact motion parity.
Validation
First integration probe R193 exposed an evaluator whitelist still rejecting the new dependent model. Recording finalized normally; the rejection was fixed and covered by a candidate/workspace regression test.
- R193:
E:\xenon_runs\level2-diver-model-20261003-r193.validation\level2-diver-model-20261003-r193.x2events. - R194:
E:\xenon_runs\level2-diver-model-20261003-r194.validation\level2-diver-model-20261003-r194.x2events. Resumed R1 frame 14111, reached the second shop at 15973. No diver damage, life loss or stalls; one four-point directional-projectile hit at 15374 during the spider fight. Baseline had three eight-point diver hits and two four-point spider hits in this section. The timer phase was subsequently corrected after comparison with the newly recorded scalar; R195 checks that final version. - R195:
E:\xenon_runs\level2-diver-model-20261003-r195.validation\level2-diver-model-20261003-r195.x2events. Resumed R1 frame 14272. Divers caused no damage, but the spider killed the player (last shield loss 15663, life loss 15680). This exposed a timing-sensitive spider regression, so the prediction change was not accepted from R194 alone. - R196:
E:\xenon_runs\level2-diver-cannon-20261003-r196.validation\level2-diver-cannon-20261003-r196.x2events. Correct Cannon births alone did not resolve it: life lost at 15711.
The motion auditor now optionally rebases screen-relative paths to the actual
later camera (--adjust-camera). A fixed camera forecast is insufficient when
a changed route backscrolls. Longer frozen-player diver paths cannot be compared
as exact forecasts of a moving player; the candidate evaluator supplies that
player dependence.
Targeted checks: native workspace (9), observation (5), session (13), protocol (20) and replay UI (33) tests pass. Replay tests require normal filesystem access because their temporary-directory fixtures are inaccessible in the sandbox.
Cannon births and spider regression
$4902 ticks the attachment animation before checking the firing pose $29CBA.
An idle attachment ($29B5A) starts $2FE2 on a fire intent; it does not emit a
projectile immediately. The four one-tick poses are windup $29C0A, fire
$29CBA, recovery $29D38, return $29DCA, then idle. The old rollout instead
emitted on every fire pulse (about 28 shots over 56 ticks instead of about 12).
C now captures each installed Cannon's pose/countdown and advances that cycle inside combat. A started cycle continues if a later fire pulse is off. Unknown poses do not invent future kills. The scene carries the initial phases, and the combat state retains them across batched advances. ABI 102 mirrors those readable structures in ctypes; the resident pilot still performs no per-frame FFI call.
work/audit_cannon_forecast.py compares one-step C births, disassembled original
rules and captured allocations. R1 frames 5017–5570: 554 comparisons, 121 births,
zero mismatches. Four- and five-tick gaps are observed. This checks birth timing
in that sample, not every weapon's future damage, geometry or animation.
The spider regression had two independent control defects:
$50DE6restores$CEAto at least$120(288) before camera application; the C forecast lacked this rule and invented loss of backscroll after 16 pixels.- A final route override erased the escape chosen for a live projectile during the below-web crossing. The front route now preserves that safety choice.
The firing station also retains world Y >= 385; camera advance must not move it back into the destructible web. These changes are limited to the live spider.
- R197 (web goal only) still lost a life; that hypothesis alone was insufficient.
- R198 (camera restoration): reached shop 15978 with two four-point projectile hits, no lost life or stall.
- R200:
E:\xenon_runs\level2-spider-safety-20261003-r200.validation\level2-spider-safety-20261003-r200.x2events. R1 checkpoint 14272 through the second shop (16117): shield 39 throughout, no lost lives or stalls; all 19 cash drops appearing after resume collected. Two already-visible maze drops at resume escaped (identities 35120 and 35147). - R201:
E:\xenon_runs\level2-model-regression-20261003-r201.validation\level2-model-regression-20261003-r201.x2events. Second pre-diver checkpoint (14111); reached shop 15958 with no diver hits, lives lost or stalls. Two four-point spider projectile hits remain; baseline had the same spider damage plus 24 diver damage. These remaining hits will receive a local tactic pass.
New camera and below-web station tests pass, alongside combat/workspace/protocol checks. Four older mission assertions still disagree with the unchanged eye and lower-maze policy (three pocket tests and the early-pickup fixture); their outcomes must not be described as a completely passing mission suite.
Screenshot: Level 3 frame 18663
The yellow curves are the shared C script trajectories. The straight white arrows are the velocity overlay, derived from recent positions, and are not the script model used to evaluate these enemies. The formation-hold goal requests screen Y 120–136 while the ship is near the ceiling, so its rectangle correctly appears below the ship. Baseline C evaluation overrides that retreat with an unsafe escape; fixing those escape choices remains necessary.
Remaining work
- Shared diver/Cannon prediction corrections implemented; second checkpoint and earlier campaign regions still require regression verification.
- Correct early Level 3 survival posture and escape selection without changing successful gates/boss tactics.
- Stage Level 2 POWERUP and Zapper collection earlier, with hazard avoidance.
- Fix remaining Level 2 corridor/spider projectile hits locally.
- Collect safe Level 3 health and remaining boss cash; preserve working fights.
- Healing/AVI recording fixes below implemented and checked independently.
Recording and incident accuracy
Odd-sized PNG chunks were written without RIFF word padding. Header/index sizes
must retain the unpadded payload length, while the file and containing LIST/RIFF
sizes include the padding byte. src/avi_record.c now writes that byte before
the next chunk. xenon_tools/audit_avi_structure.py verifies chunk boundaries,
parent sizes and OpenDML indexes without decoding every frame.
R209's historical pair had 4001 missing-padding errors. Both new R212 AVIs
have 4167 video chunks with valid padding and index lengths:
E:/xenon_runs/level3-carrier-observed-launch-20261003-r212.validation/level3-carrier-observed-launch-20261003-r212.x2events.
The synthetic AVI/index tests and campaign monitor tests pass. This repairs new
recordings; it does not rewrite historical files.
A health pickup can briefly set shield to 59 before normalizing it to the
maximum 39. The fallback memory-write recorder previously reported this
normalization as twenty damage and read object metadata at address zero.
It now compares against the capped prior shield and leaves absent object IDs
unattributed. A captured contact without a net shield decrease is retained as
contact, not included in shield-loss totals. Real net losses remain damage.
These changes affect recording/analysis only, not the C pilot's decisions.
Level 3 passage and carrier follow-up
Both LEVEL3_STRATEGY.MD and LEVEL3_CARRIER_BOSS_TACTIC.MD were reread after the user's reminder. Their route-tube and camera-window warnings apply directly to the latest pocket failure. The older Python Y154 carrier station is not current C evidence: the newer notes explicitly report hits at that station with the later loadout.
Prediction corrections include the additional scripted tail handler $4F258,
candidate-dependent $5073C/$507B2 expansion (including peak spacing 16),
and seven-member scroll-triggered waves whose script age survives backscroll.
The tail's sampled 1/8/16-frame anchors match after camera rebasing. Expanded
formation bounds do not imply that shooting one guessed member destroys the
whole uncertainty envelope.
The failed left-pocket exit had two concrete defects. A valid span query can
return 1 with zero route points; the onward check now requires points and a
route under the future camera clamp. Separately, the grid-free station
(108,3472) was not a usable stopping pose from the actual (115,3470) ship:
its nine-pixel left step hit terrain. Level 3 formation stations now require
a small free stopping neighborhood, while the transit graph stays undilated.
Route steering uses a four-pixel horizontal tolerance and clear orthogonal
legs. The early passage retains physical collision checks with a four-pixel
maneuver reserve instead of the ordinary fifteen-pixel reserve.
The documented C carrier sequence is retained as goals validated by the shared planner, with its main attack below the cores using forward weapons. Three return defects were corrected: a new launch must not send a ship already on the right across the body to the left refuge; a completed crossing must not re-enter that phase on the next frame; and the lower refuge must use reachable Y176 rather than the old Y190 joystick hint. Its hold is released only after the ship reaches the lower row and the observed body/shot conditions clear. Inspection now publishes the same proposed movement as the refuge goal.
All tests below used visible resident-C Release Hatari, a matching replay DLL, both AVIs and checkpoints every 150 frames:
| Run | Start | Result | Shield | Boss cash |
|---|---|---|---|---|
| R239 | 17268 | Passage and carrier complete, first Level 3 shop reached | 27 unchanged | 10/10 drops |
| R240 | 19040 | Carrier complete, shop reached | 27 unchanged | 10/10 drops |
| R241 | 18227 | Carrier complete, shop reached; two earlier swarm hits remain | 27 to 3 before carrier; unchanged during carrier | 10/10 drops |
Recordings:
E:/xenon_runs/level3-carrier-return-side-20261003-r239.validation/level3-carrier-return-side-20261003-r239.x2events.E:/xenon_runs/level3-carrier-return-check-20261003-r240.validation/level3-carrier-return-check-20261003-r240.x2events.E:/xenon_runs/level3-passage-return-check-20261003-r241.validation/level3-passage-return-check-20261003-r241.x2events.
R241 damage at 18892 ($E1E, identity 51458, eight shield) and 18893
($4F24E, identity 51370, sixteen shield) is a remaining passage regression
from a different entry state. Valuable health pickups also remain missed.
The carrier result is accepted for these three entry states; the complete
Level 3 passage and the full campaign are not yet accepted.
Rejected intermediate versions include simplified upper refuges (R233, fatal tail hits 20729–20730), goals without side-aware return (R235, fatal body hits 20604–20605), a shorter horizon alone (R236), restoring unchecked authored steering alone (R237), and changing the uncertainty lifetime alone (R238). One clean focused checkpoint in R234 did not generalize to the earlier run. These failures must not be presented as successful fixes.
Rejected follow-up experiments (R242–R244)
Predicting the additional single-object top entrant as a permanent pending hazard did not improve the alternate entry: R242 and R243 took a 16-shield swarm hit at 18883 and lost a life in the carrier at 19434. Searching farther back for side stations did not change that outcome. Changing the Level 3 escape search to one-frame extensions also failed: R244 took damage at 18871, 19096 and 19910, then lost a life at 19927. All three experiments were removed; they are not accepted fixes.
Recordings:
E:/xenon_runs/level3-singleton-prediction-20261003-r242.validation/level3-singleton-prediction-20261003-r242.x2events.E:/xenon_runs/level3-visible-bay-routing-20261003-r243.validation/level3-visible-bay-routing-20261003-r243.x2events.E:/xenon_runs/level3-tick-escape-20261003-r244.validation/level3-tick-escape-20261003-r244.x2events.
A pending seed currently has no combat target. Treating a top entrant as indestructible throughout the horizon could therefore reject a forward firing lane that would clear it. This is a hypothesis for the failed additional prediction, not a demonstrated cause. The retained seven-member bottom-entry forecast and the carrier's below-boss forward station remain unchanged.
Forward-attack confirmation and remaining G1 approach failure
R245 (E:/xenon_runs/level3-forward-full-20261003-r245.validation/level3-forward-full-20261003-r245.x2events)
repeated the healthy Level 3 entry. The carrier died without shield loss and
all ten cash drops retired beside the ship. After the shop, scripted swarm
$4F244 #62286 caused 16 damage at 22145. The run stopped for a stall at
23211 near world (249,2197); no life was lost. The approach and carrier
therefore pass this entry, but the rest of Level 3 does not.
At 22130 the remaining gate route was (256,2196), (172,2196),
(168,2304), (80,2304), (60,2112), (56,2000). Survival displaced the
ship while ordinary camera scrolling continued. By 22312 the connector
returned no route: the later row 2304 was behind the C model's camera reach.
The fallback remained in the right passage instead of reconnecting to G1.
This is not evidence that the destructible gate is erroneously still solid.
Two attempted corrections were rejected:
- R246 extended the extra maneuver search through the closed G1 approach.
It took no damage but still stalled at 23266 near
(215,2162).E:/xenon_runs/level3-g1-escape-20261003-r246.validation/level3-g1-escape-20261003-r246.x2events. - R247 forecast successive route bends inside each trial rather than holding
at its first waypoint. Its synthetic turn/retreat test passed, but the
live run took 16 damage from
$4F24E#62346 at 22154 and stalled at 23252.E:/xenon_runs/level3-gate-route-forecast-20261003-r247.validation/level3-gate-route-forecast-20261003-r247.x2events.
Both changes and their temporary ABI additions were removed. Looking farther along the route alone did not prevent the camera from closing its retreat. A further fix must preserve the reachable route suffix during a survival dodge and demonstrate that behavior in live gameplay; the cause of each missed crossing still requires investigation.
R248 (E:/xenon_runs/level3-forward-confirm-20261003-r248.validation/level3-forward-confirm-20261003-r248.x2events)
rebuilt the restored C code and replayed from the pre-carrier 19040 save.
Shield stayed 27, lives stayed three, both cores died, and all ten drops
retired beside the ship. The shop opened at 20560. The cash total is 750;
collection attribution remains inferred from pickup retirement next to the
ship because the capture has no explicit collection event. Both AVIs have
4903 indexed video frames and pass the RIFF padding/index audit. The 47
focused driver, Level 3 mission, maneuver, decision and session tests pass.
The restored C sources match R245's captured native source snapshot after
normalizing line endings. This confirms the below-boss forward tactic and
rejects the failed navigation experiments; it does not accept the full level.
Historical investigation: camera reach was modeled incorrectly
The user requested comparison against earlier gate runs before further fixes.
The investigation indexed 2,743 recordings across D: and both E: recording
roots. Old Python checkpoint RAM confirms all nine gates open by
D:/src/hatari/xenon_tools/run_logs/level3-aimed-state-fix-0827-49.x2events,
frame 59167. The September 25 native R4 recording cleared G1, G2 and G4, but
left G3's cap and stalled; it is not an all-gate success baseline.
Original Level 3 code restores its backward camera limit to at least 2608 before each ordinary maze update. C omitted that rule and treated the captured post-camera scroll-plus-16 limit as lasting. At R245 frame 23210, changing only the route query's maximum Y from 2212 to 2784 restores a complete native route to G1 via Y2304. R258 and the September R4 run show the same cause at G3. The original camera code and Level 3 embedded map are unchanged between those runs. Therefore the earlier claim that the game had permanently sealed the retreat is retracted; the restriction came from the incomplete C model.
R258 recording:
E:/xenon_runs/level3-g1-route-owner-20261003-r258.validation/level3-g1-route-owner-20261003-r258.x2events.
At frame 28244 the actual RAM and C observed map agree: G1/G2/G4 open, G3 cap
still closed. The stale diagnostic gate label caused this to be called a G2
stall. No gameplay changes were made during this historical investigation.
Saved September source includes uncommitted G1 route retention and movement override experiments missing today. Their absence is not a lost committed merge, and their run still took damage and stalled. Correcting the camera model has priority over restoring those overrides or adding pacing thresholds. Scope, source history, recording paths and repeatable diagnostics are in LEVEL3_GATE_REGRESSION_ANALYSIS_20261003.MD.
Level 3 C repair and full validation
Implemented the original per-update camera restoration, retained maze routes, visible swarm staging connectors, short lateral escape taps, reaction room on forward gate approaches and route ownership through retreat bends. Ordinary Level 3 advancement now searches reachable forward regions, avoiding the blocked-center projection loop after G9. Final radial worms use the existing checked escape search with real sprite hulls; other levels keep their policy.
Full-entry R277 reached Level 4 at 30214, opening every gate with no lost life or stall. Remaining projectile damage: 23211, 24162, 28262, four shield each. Early swarms and the carrier were damage-free. All 10 carrier and 20 final-encounter cash drops retired beside the ship; ordinary cash/health collection is still incomplete. Both AVIs passed structure/index audits. The 74 targeted native tests passed.
Recording:
E:/xenon_runs/level3-full-repaired-20261003-r277.validation/level3-full-repaired-20261003-r277.x2events.
Detailed incident, pickup, shop and rejected-attempt evidence is in
LEVEL3_GATE_REGRESSION_ANALYSIS_20261003.MD.