Autopilot · write-up
Level 4 temporary shield and first-boss handover
This follows the two failures documented in LEVEL4_FULL_VALIDATION_20260927.MD. Gameplay changes are in C. Python changes name the pickup, mirror the native ABI and test/inspect the same C implementation.
Pickup $005C: verified temporary shield
ReVa is connected to /mydumpat0. Its common pickup code was checked against
the Level 4 dump xenon_tools/level_capture/level-04.stram.bin; the Level 4
boss investigation uses that Level 4 dump, not another level's overlay.
- Animation-table row 16 at
$003F96has status$005Cand animation$002D6C. - Pickup contact at
$004FF8indexes the callback table at$005040using object word+$30. Row 16 selects$0052CA. $0052CAadds 170 to the timer at$000CC8, creating a following shield effect with update procedure$0040D6when the timer was zero.$0040D6decrements the timer once per game update and retires the effect when it reaches zero.- Projectile collision at
$0041D4skips shield damage while$CC8is nonzero. Ship/body collision at$0067BCalso checks this timer before applying damage. This does not make solid terrain passable.
The catalog now names this pickup TEMPORARY SHIELD, distinct from the
shop's Protection equipment. C uses XENON_PICKUP_TEMPORARY_SHIELD_CODE;
Python retains the old unidentified-code alias solely for old replay code.
Original evidence:
E:/xenon_runs/level4-full-20260927-r67.validation/level4-full-20260927-r67.x2events.
Pickup #560602 appears at frame 63865 and expires at 63928. Its collection
could protect against the projectile at 63933. A single 170-update shield
cannot cover the later hit at 64409; those two hits are too far apart.
The mission already selected the pickup. Its old route chased the orbiting item's current position around terrain, reaching an unusable waypoint near X=64 before the item dropped. It was not simply assigned a low value. The revised mission predicts the final eight-pixel downward drop and descends before aligning underneath it. The waiting destination uses the actual backward camera limit, rather than a world waypoint which moves upstream as the camera advances. It preserves hazard avoidance and firing.
A screen station just beyond the bottom clamp requests a camera hold. In the original ship/camera rules, holding DOWN continuously at the backward limit shrinks that limit as default scrolling resumes. The continuation therefore releases DOWN for one update at the limit, then presses DOWN to restore the same camera position. This uses the captured backscroll allowance; it does not invent extra backscroll or modify the emulator's rules. Ordinary screen bands keep their existing behavior.
When the item comes close, the mission permits a short contact detour. It tests the next four pickup positions, a maximum 32px Manhattan displacement, arrival time, and a clear physical segment. Its goal is inside the pickup's collection rectangle, with a one-pixel waypoint tolerance, rather than its sprite center. The normal evaluator still checks walls and hazards. This last adjustment avoids stopping a few pixels short of collection. Long orbit chases are removed.
Failed connectors no longer invent unchecked straight-line detour waypoints; the physical graph supplies narrow passages when reserve dilation disconnects the travel graph.
Shield collection changes the damage rules, so candidate evaluation stops at that verified collection and requests a fresh observation, as it does for Zapper. Hazards and walls are still checked before collection. Continuing to evaluate the old unprotected scene after collection can incorrectly reject the useful detour. This moving interception uses a 12-update local horizon and at most four pixels of extra clearance, rather than requiring a distant stationary hold with the ordinary 15-pixel reserve. Actual body/projectile contact and wall checks remain mandatory. Retired pickups no longer retain a phantom route for another 64 updates.
The decision's direct_goal mode accepts a safe intermediate waypoint even
when nearby pickups cannot be collected within this short forecast. Previously
the lazy nearby-pickup count prevented that acceptance and sent the search
through opportunistic detours instead. Shield interceptions also reconsider
the route each observation instead of retaining a safe stationary escape
suffix until the pickup expires. Other missions keep their existing policy.
Use the shield's protection window to progress
The pilot previously did not capture $CC8, so it continued treating enemies
and projectiles as dangerous after collecting the shield. Hatari now supplies
the actual countdown to C player preparation. C excludes the possible expiry
update and limits the local forecast to the remaining protected updates.
During that window it checks walls, but skips hostile contact checks and the
extra enemy clearance reserve. Combat, firing and pickup collection continue.
Homing movement and shell release timing remain correct if a candidate extends
beyond protection. Ordinary hazard checks resume when protection runs out.
The driver replans toward the current mission instead of retaining a defensive escape suffix. It accepts safe progress directly while protected. This removes unnecessary collision queries as well as the hesitation visible after collection; solid walls still require navigation around them.
New recordings carry the timer in control trailer $5841; replay inspection
shows temporaryShield=N frames. Older recordings report no timer and retain
conservative avoidance when recomputed rather than inventing immunity.
First boss: captured camera limits did not describe the next update
At 67213 in r67 all five satellite heads were gone. The canonical world and mission correctly targeted main head #568323; the stall was not caused by retaining dead satellite targets. Main health remained 175 until the run ended.
The original main-head update at $050782 performs:
050782 cmpi.w #$9B0,$CEA.w
050788 bge.b $50790
05078A move.w #$9B0,$CEA.w
$CEA is the backward-scroll limit, and $9B0 is 2480. Every live main-head
update restores at least that limit. The subsequent camera pass shrinks the
captured limit to the normal current-scroll-plus-16 window. Planning only
from that post-camera capture incorrectly treats arena backtracking as spent.
For example, the old frame-67343 mission clamps the lower firing destination
to Y=2468 and routes back across the top at Y=2268 instead of reaching Y=2608.
Player preparation now derives a backward-limit floor from the live main head's kind and update procedure. Movement forecasting restores it between ship movement and camera application on every forecast step, matching the original update order. Mission routing uses the same effective arena limit. The rule disappears when that main head is destroyed. Captured initial limits remain captured facts; generic backtracking and other levels are unchanged.
The main attack also retains the route's orthogonal axis order and uses the available Side Shot on the nearer exterior. The old unconditional left-side station caused a needless crossing from the right. The random-restart envelope can delay descent, but the right-side attack can damage the main head during that descent and continues from the lower station once reached.
ABI 95 includes backward_limit_floor in the prepared player and maneuver
request, direct_goal in the decision mission, and the shield timer in player
telemetry and candidate evaluation; the ctypes mirrors are updated.
Hatari and the replay DLL must both be rebuilt
with xenon_tools/hatari_dev.ps1 before comparing live and replay decisions.
Validation
Tests cover the captured-versus-restored camera limit, removal of the rule
after destruction, shield-drop interception, orthogonal wall routing and
nearer-side weapon selection. Live tests use validate_campaign.py native-run,
visible Hatari, both AVI streams, Level 4 tracing and 150-frame checkpoints.
An additional comparison against r72's actual next ship/camera transitions
checks 164 sampled updates, including 61 restored-bound cases, with zero
mismatches in screen X/Y, camera scroll or the post-camera backward limit.
The ABI 95 replay DLL also replays r88's captures through collection and expiry;
174 updates confirm that C player preparation uses the recorded shield timer.
E:/xenon_runs/level4-shield-scroll-20260927-r69.validation/level4-shield-scroll-20260927-r69.x2events: initial interception probe, 63810–64419; still missed the shield. This exposed selection of an orbit point instead of the final downward drop. It is not evidence that shield collection is fixed.E:/xenon_runs/level4-main-side-20260927-r72.validation/level4-main-side-20260927-r72.x2events: 67192–68345, restores r67's pre-handover checkpoint at 67190. Main health falls from 175 to 145, reaches the lower-right station, and takes no shield damage. The recording was finalized before the kill; it is continued below.E:/xenon_runs/level4-main-finish-20260927-r73.validation/level4-main-finish-20260927-r73.x2events: 68346–69936, continuation from r72's finalized snapshot. Main head is defeated after its health reaches one at 69818; the first shop opens at 69936. Shields remain 39 and lives remain one throughout r72 and r73. Both AVIs finalize without cleanup errors in each run.E:/xenon_runs/level4-shield-camera-hold-20260927-r85.validation/level4-shield-camera-hold-20260927-r85.x2events: 63809–64610. The camera hold reaches the lower lane but misses the pickup by a few pixels. This led to the short contact detour, rather than another long orbit pursuit.E:/xenon_runs/level4-shield-small-detour-20260927-r86.validation/level4-shield-small-detour-20260927-r86.x2events: 63809–64611. Temporary shield #560545 is collected at 63935. Its captured update changes to$107Cat 63936, and the RAM checkpoint at 63964 has$CC8=141, independently confirming activation. There is no damage during the collection. A later directional projectile #561780 hits at 64274, reducing shields 39→35, after this 170-update protection has expired. No life is lost; both AVIs finalize normally.E:/xenon_runs/level4-shield-earlier-20260927-r87.validation/level4-shield-earlier-20260927-r87.x2events: 63046–65049, starts from r67's earlier checkpoint at 63045. Shield #560354 is collected at 63845; the RAM checkpoint at 63951 confirms$CC8=64. This predates protection-aware evaluation and takes four shield damage at 64219, after protection expires. No life is lost.E:/xenon_runs/level4-shield-protected-progress-20260927-r88.validation/level4-shield-protected-progress-20260927-r88.x2events: 63047–65249, repeats the earlier checkpoint with protection-aware evaluation. Shield #560354 is collected at 63845; recorded$CC8=170at 63846 decreases to one at 64015. The camera advances from 4009 to 3840 during protection, instead of lingering in the pickup waiting lane. Shields remain 39 and lives remain one throughout the run. A generic damage-hook event at 64170 has no corresponding shield loss; it is not evidence of an actual damaging hit. Both AVIs finalize normally.
The protected run checks the pickup approach and the following corridor. It does not replace the separate first-boss handover validations above or prove the remainder of Level 4 damage-free.