Need help getting started? Try the player guide. These notes include older work; the game overview explains what’s ready now.

Native twelve-level campaign

All twelve original campaign maps are now enabled. This includes normal map10-to-map11 advancement with earned inventory, final-map passwords and Select Level after beating map10. No save migration or progress reset is needed. play-native.cmd --level 11 starts Caesar's Palace directly with its original standalone loadout. The user requested manual campaign validation on2026-10-17; automated playthrough success is no longer an admission gate. M now opens the recovered in-level automap in either renderer, gated by the saved Extras -> Automap option (default Off), with wheel or held plus/minus zoom, original walls/markers/palette and scanline animation. Pause and Tab NETRICSA return to the map. See automap.md. Original chapter/ending panels now run natively: Egypt before New Game, Rome on advancement into map6, and the ending after the final bonus tally. Finite lives now follow original death timing and automatic retries, preserving the remaining5/3/2 difficulty allowance across levels; permanent death offers saved high-score entry. See death/retry/game over. The ending offers high-score entry before Main. Esc/P now opens Continue/Quit with a Yes/No warning. Completion renders original localized notice sprites, live score and time/ammo bonus digits; held fire/Enter/Space accelerates counting. Bonus score commits once before advancement. See pause and completion and saved high scores/name entry. Preview the ending with play-native.cmd --story 12. See campaign-story.md.

Run play-native.cmd from the workspace. It opens the supplied, identity-checked orig/SSA.gba in build/native-windows/Release/ssa_native_game.exe. The executable runs native x64 C; the ROM supplies data, never CPU instructions. Original localized pickup names, boss introductions and death messages now use their sprite lettering and original reveal/expiry behavior in both renderers. Language follows the saved menu option. See HUD notices. Rome campaign ankhs use the requested golden laurel wreath, with original20x34 and10x17 dimensions, origins and gold palette indices. This is an in-memory presentation replacement shared by both renderers, with original pickup behavior. See artwork and source prompt. Normal startup now begins with title, main menu, Single Player, New Game and difficulty. Language cycles in Options instead of a startup selection list. Language and beaten-level unlocks now persist in save.dat. Single Player inserts Select Level between New Game and Password, with original localized campaign names and no multiplayer maps. Level1 is free; completing a level unlocks its successor on every difficulty. Later unported campaign maps remain unavailable. Options → Clear Data warns with Yes/No (default No) before resetting progress and language. See profile storage and level selection. Enemy crowd movement now allows tangent sliding and gradual separation of overlapping spawns. See enemy crowd movement. The focused normal-input first-level proof finishes in5,110 frames with24,000 score, eight pickups,19 spawns and100 health, with no living enemies or open groups. Prion-converted enemies now choose the nearest living combatant on every behavior pass, without preferring Sam. Facing, projectile aim and enemy melee use the selected target. All ten convertible types pass the focused 1,602-check GCC/Windows test; see Prion targeting. The campaign replay figures below predate this targeting change. The updated GCC sanitizer and Windows campaign replays complete maps0..10 consecutively with earned carry: 140,712 frames, 1,544,000 score and 45 HP. Each advancement now resets vitality through original player construction, carrying earned gear and score. This includes crowd sliding, wide player clearance, saved-menu support and the latest Prion2x/Time Strike changes. Map8 finishes 17,235 frames / 76 HP with 106 spawns; map9 finishes 10,930 frames / 46 HP with 50 spawns. Both use actual conversion, falling Time Strike objects, jump/H controls, both renderers and the native audio mixer. The frontend now admits all twelve maps for manual validation. Praetorian Fort completes in 17,231 frames / 99 spawns / 9 pickups / 45 HP with earned equipment and original next-level vitality. The level11 development probes exposed and led to a repair of Time Strike's stale animation frame in native render snapshots; see special weapons. No enemy health, collision, script, inventory or hazard rules were bypassed in those probes. Arrows/WASD navigate, Enter/Space confirms, mouse hover/click selects entries and Esc goes back. Title music continues across Press Start. Difficulty affects native combat; selected language also applies to subsequent map screens. --level 0..10 explicitly bypasses these menus for diagnostics. See menu recovery for supported pages and gaps. Options → Credits displays the original ROM-backed scrolling credits. Up/W pauses, Down/S speeds up, and confirm or Esc returns to Options; gameplay stays frozen. Single Player → Password supports direct keyboard typing with Backspace/Delete, alongside the original eight-character editor and table. Left/Right moves the cursor; Up/Down changes characters, Enter/click submits, and Esc returns. Accepted passwords select the original level, difficulty and weapon/ammo loadout, then the normal fade/map/level sequence. Restart restores that password entry inventory. Later maps remain explicitly unavailable. Level starts, restart and advancement display the original pre-level map view. Click or press Space/Enter to confirm; its fade reaches solid black before gameplay begins. The frontend presents the final black map frame, holds black for at least a quarter second, then reveals the level over at least one second. These transition frames cannot be consumed in a simulation catch-up batch. One bootstrap tick builds the first level image and the complete HUD is loaded before it appears. Movement, mouse capture, aiming and HUD updates remain active throughout the reveal. Simulation catches up at its normal clock while each fade step is presented separately. Map music stays on that screen; gameplay starts with the level soundtrack.

Normal startup and restart now run one native initialization tick before their first gameplay draw, building valid HUD/cache/OAM data. The pre-level map does not tick gameplay. Drawing gameplay before its bootstrap tick rejected the zeroed initial sprite records and made the launcher exit immediately; the hidden smoke path had already ticked before drawing and did not expose it. scripts/test-native-startup.ps1 tests the actual normal startup, raw-input registration, initial window paint and restart in both renderer modes through play-native.cmd, including launching from another working directory. The normal Windows gameplay test now includes these checks. The launcher saves stderr to a per-session build/logs/launch-*/stderr.log, displays failures and waits on error. A session directory is reserved atomically, because CMD random sequences can collide when two launches start together. On exit the launcher also updates build/logs/last-launch.log when that file is writable. A running older launcher holding that shared file cannot block a new launch. Automation may set SSA_LAUNCH_NO_PAUSE=1 and an explicit SSA_LAUNCH_LOG; tests use private logs and also verify two simultaneous default launches. Current startup evidence is in analysis/windows-native-startup-validation.json.

Mouse look activates automatically during gameplay and on focus return, without a separate click-to-capture mode or prototype text overlay. Use WASD to move, mouse movement to turn and aim vertically, left mouse to fire, Space to jump, H to toggle first/third-person view, E to use doors, and number keys 1–0 to select an owned weapon. Picked-up weapons also select through the original acquisition logic. Esc/P opens Pause and frees the cursor; R reloads Colts when Enhanced weapons is enabled. Enter advances after the first eleven exits and shows the ending after the twelfth exit; otherwise it restarts. Mouse aiming uses the original vertical auto-aim until the first vertical mouse input. Vertical input enables direct free aim, including full yaw precision, sector-plane hits and projectile slope. The PC renderer rotates the camera through up to 80 degrees up/down; the original crosshair art, placement and target animation are restored in both views. The optional original 240x160 reference renderer retains horizontal look and original auto-aim. Third-person PC view now orbits with pitch and converges onto the actual weapon contact, keeping the centered original crosshair aligned. See chase aiming. Third-person view hides all fixed-screen weapon muzzle flashes as well as the first-person weapon. The effects still animate normally; changing H back to first person restores any active flash. World impacts and projectiles remain visible. Single-player Sam uses the original white-shirt body overlay (variant3, resources121–125). Selection is confined to the render snapshot: gameplay player identity and the recovered animation/asset/projection routines retain their original behavior. Both PC and reference renderers use the same variant. Ranged attacks now have no weapon-distance cap, including shotgun side pellets. Player projectiles have no age expiry; walls, floors, ceilings and targets still stop them. Melee reach and blast radii retain their original rules. See unlimited range.

The native audio backend now plays original ROM effects and level music. M toggles mute; --mute starts silently and --no-music retains effects only. Background mixing keeps audio delivery independent of rendering. Restart clears active effects and plays the map cue on the map screen; confirming it starts the level song. See audio integration and original map view. Footsteps use the original alternating cadence while walking or strafing on the ground, in both camera modes. Jumping, standing still, disabled controls and pressing into a wall do not emit walking sounds. Independent effect voices keep the soundtrack running. Enemy, activation and impact sounds use a new PC spatial mixer: stereo direction follows Sam's yaw and volume fades with three-dimensional distance. The listener stays at Sam's eye in both views, so H and vertical mouse aim do not displace it. Each CD/CE enemy can run its own movement loop; attached enemy sounds follow their emitter, while one-shot impacts stay at their emission point. Doors have world positions too. Each door loop ends when that door stops, without cutting off other moving objects. Pickups, local weapons, footsteps and music remain centered. This spatial model is a native PC addition. Positioned sounds now fade continuously with distance, including nearby doors, using the same falloff as enemy effects. Pickups bypass distance attenuation and positional panning, using the same local playback path as player sounds. The last life selects the original game-over music at the recovered GAME OVER notice, while ordinary deaths retain level music and sound17. The real scripted exit selects the original level-clear cue once. End-screen transitions clear old effect loops. Restart restores level music. --no-music keeps these transitions effects-only. The death lifecycle and automatic finite-life handoff are now connected; see run-exit.md.

This is a twelve-level prototype, with campaign playthrough validation left to the user. The completion tally UI, score/name entry, remaining presentation effects and original menus remain unfinished. The new native audio renderer is not yet an exact reproduction of the GBA hardware mixer. Pickup/boss/death notices use original HUD sprites; the completion shortcut still uses host text. The all-map diagnostic viewer remains available separately through run-native-viewer.cmd; it does not run this gameplay composition.

Composition and ownership

Type-64 moving effects now use original D000/CE50/053D0 geometry and native sector-only membership updates. The shared constructor and scheduler no longer reject this relocation path. See sector clipping for original comparisons, bounded-loop guards and controlled integration coverage. This adds no campaign admission or new original creation-site claim.

SsaNativeGame keeps stable owners for map/ROM-backed script data, players, combat, enemies, projectiles, pickups, frame scheduling and rendering. The caller retains the ROM until teardown. Actual level/mover initialization precedes map objects, which precede players, preserving the original allocation order. ssa_script_spawn_adopt_plan moves map bodies into the shared100-slot actor pool. ssa_world_replace preserves block/sector link order while transferring storage before gameplay borrowers bind. The initial reserved prefix is a highwater mark; adopted actors in it can die, be collected, and be reused. External player bodies remain separately owned.

The original 0244C frame order runs real player updates, CD/CE/CF AI, projectile flight/damage, movers, scripts, pickup respawn, actor animation, weapon/HUD controllers, sprite animation, cache preparation and OAM construction. The reference first/third-person world and actor rendering composes with the original HUD, palettes and weapon sprites at 240×160. The Windows frontend now defaults to an additional dynamic PC renderer that follows the window size; --resolution WIDTHxHEIGHT selects a fixed size and --original-renderer selects the reference view. See pc-renderer.md. H exposes only a rendering snapshot of Sam's body and hides the first-person weapon. It changes neither hitboxes nor aim. One shared RNG state is owned by the game; impact selection currently is its only recovered consumer.

Normal difficulty uses damage.difficulty=1, continue_flag=3, input_state=1 and the actual per-type speed records at 0844BFD4. No debug loadout, invulnerability, health grant, artificial group defeat or forced animation completion is used. The PC shell handles restart and completion explicitly; it does not claim a recovered full original menu dispatcher. The production frontend exposes levels 0 through 10 (--level 0..10); the final campaign map remains unsupported. The recovered difficulty menu now also selects original easy/hard damage rules and initial continue values5/3/2. The later finite-life integration now performs automatic retries and final game-over/high-score handoff. Enter restart remains available only to the explicit startup/transition diagnostic, not ordinary play.

Level advancement and restart

Enter after a supported intermediate scripted exit starts the next map with earned weapons, ammo, the equipped usable gun and total score. Original player construction starts the new map at 100 health with no protection or pending acquisition queue. H camera mode and Q weapon history also carry forward. A direct --level diagnostic launch uses the original ROM level/difficulty starter loadout, as password entry does. This also applies to explicit --level 0; ordinary New Game retains its recovered zero-setting first-level initialization. Restart restores the current level's entry inventory and score, including after death. Enter after the last admitted map replays it from its entry state.

SsaNativeCarry is a value-only entry snapshot. Exact capture/apply serve restart; carry_next prepares the original vitality/queue reset after completion. Native weapon_progress.c recovers the original 123C4 weapon restore, with 8,192 whole-routine comparisons and 512 original construction/restore sequences across all 16 maps. It also recovers 1231C completion capture: 4,096 whole-ROM comparisons and 512 capture/restore compositions. ssa_native_game_weapon_progress reads equipped/requested guns and ownership/ammo/shot/hit rows without mutating the game. The carry path now uses that recovered capture. The separate native_statistics.c adapter snapshots all live completion counters for the new original accumulator/checkpoint backend; frontend total persistence and score screens remain unimplemented. See statistics.md. The separate native_completion.c adapter now composes the verified timed time/ammo tally and bonus-adjusted capture/accumulate/checkpoint sequence; it does not replace the Windows frontend's Enter path yet. See completion.md. See campaign-entry.md. This does not claim recovery of every outer campaign screen or transition. Capture requires an idle game; apply requires a newly initialized game before its first tick. Invalid/dead captures and invalid carry values are rejected. New maps retain their own spawn positions, actor owners, scripts and transient weapon effects. The frontend initializes each replacement game at its final heap address: SsaNativeGame contains internal pointers and cannot be relocated by copying. Renderer caches and audio voices reset at the transition. The map view runs without gameplay ticks; after confirmation and its fade, a bootstrap tick prepares the first gameplay frame before drawing.

Validation

tests/test_native_playability.c completes level 0 through normal portable PC input events. Its route planner reads a separate copy of map geometry; possible unlocked door openings are considered only in that copy. Real doors still need E and the actual mover update. A separate aim workspace chooses bot inputs. The bot never writes gameplay bodies, health, ammo, damage or script counters.

The earlier GCC/MSVC checkpoint completed in 4,977 frames: 28,000 score, 7 pickups, 19 spawned enemies, 69 remaining health, 13 pistol shots and 23 shotgun shots. The quick-click buffer retains an additional shotgun attack and changes the bot's later combat/route. The bot continues firing at close threats even when low on health, and stops optional supply detours after clearing the waves. It still uses only normal PC inputs. The actual group 3/4 deaths unlock the final gate, and touching the exit pickup queues opcode9. analysis/campaign-validation.json records the current sanitizer proof; analysis/windows-native-game-validation.json records Windows completion and hidden-window frontend smoke. Physical keyboard/mouse interaction has not been manually tested. Separate integration checks pass 600 gameplay frames with 390 airborne frames, 360 third-person frames, a pickup and incoming damage, then 120 fresh frames after teardown/restart, with leak detection enabled. The current completion/build reports bind their sources and executable hashes to these results. Older broad source audits describe earlier checkpoints.

tests/test_campaign.c runs consecutive completions using the shared input bot, with earned weapons/ammo and score plus original next-level player construction. The updated chain, including crowd/player clearance and the latest special-weapon changes, completes the following maps identically on GCC ASan/UBSan/leak detection and MSVC:

Map Frames Cumulative score Pickups Spawned enemies Health
1 5,110 24,000 8 19 100
2 10,584 112,000 12 49 100
3 10,118 234,000 17 73 95
4 13,923 408,000 22 104 100
5 12,997 622,000 26 119 97
6 15,530 844,000 13 146 84
7 11,026 1,022,000 11 112 100
8 16,028 1,194,000 17 102 48
9 17,235 1,330,000 14 106 76
10 10,930 1,386,000 6 50 46
11 17,231 1,544,000 9 99 45

The final map has a separate Normal standalone completion in campaign-standalone-validation.json and its Windows counterpart: 17,270 frames, 117 spawns, 8 pickups, 160,000 score and 63 health. The D8 boss naturally enters, takes damage, releases its group on death and reaches the original script exit; boss/post-boss music each starts once. Nine boss firing events are observed. No active type-6A boss projectile survives to the post-frame observation in this route, so this does not establish natural D8 projectile flight. Some optional group-six enemies remain alive, as permitted by the exit.

The uninterrupted development chain beyond map11 died on the final map at frame 4,961, before D8. Its actual earned entry had weapons 0x37F, 96 shotgun shells, 25 rockets and no automatic/cannon/special ammunition; no fresh starter grant was substituted. This probe is not completion evidence. The frontend now admits all twelve maps at the user's request, independently of automated playthrough results. The next campaign check is the user's manual playthrough.

The later-map bot uses normal vertical mouse input to aim at visible body parts, backs away from ledges, uses earned special weapons and steers away from nearby enemies while firing. This run uses the current original-rate minigun, clocked chainsaw, firing-animation weapon handoff and immediate E-button policy. The bot chooses its earned shotgun for close threats on earlier maps, holds a steadier automatic weapon on map7, and keeps more distance on maps6/7. When low on health it can aim/fire while moving toward a reachable supply pickup. These are ordinary W/A/S/D and mouse inputs, not health or ammunition grants. Its dedicated collision scratch checks walking routes without changing gameplay. Cached planning edges use short moves, a small clearance margin and current sector heights. Reaching the destination's grid cell retains the exact final approach needed for pickups and wall switches. These are test-bot decisions, not changes to original AI, movement or damage.

Praetorian Fort adds a 32-unit planning grid and pit-aware walking probes. Its first arena retains exact-width stair routes; after a genuine stall in the southern rooms, the bot requires one unit of extra route clearance, retains fractional steering and approaches interior points near wall corners. This avoids planning exact64-unit passages that cannot accept its current fractional position. Only the private planning map and normal keyboard/mouse events are affected. The actual player radius, wall sliding, hazards, enemy health, damage, script groups and ammunition remain unchanged. Its copied-body planner can consider a low ledge, but only ordinary Space input allows the real player to cross. Navigation jumps release the bot from the raised secret-room exit without relocating the gameplay body. Ninth-map inputs keep more distance and collect reachable armor between waves. Final-map inputs finish an actual shot before reassessing a brief visibility gap, avoiding repeated cancelled lower/raise animations. These are input-driver choices only.

The bot now uses its earned cannon ammunition when automatic guns are empty, alongside real Prion and Time Strike pickups. All 99 original enemy spawns and the final group-gated exit execute naturally. Optional group-zero enemies remain alive in the completed earned run, as permitted by the original exit. An earlier standalone Praetorian Fort checkpoint completed independently of carry. The current standalone report instead validates the final map.

Complete BFS trees cache the original predecessor/queue order for repeated goals from the same grid cell. Changes to sector heights, body dimensions, clearance or the start cell invalidate the tree; exploration still reads current visited sectors. A30000-frame cached/uncached development comparison produced identical diagnostic logs and every result field. Both runs failed at the same route, so that comparison proves cache equivalence rather than level completion. Those logs remain eleventh-corner3-earned.* and eleventh-cached-earned.* under build/native-campaign/. The successful uninterrupted chain supersedes them.

The fourth map's opening armor pickup triggers its original script and opens the locked start door. Script OPEN preserves the lock flag; the test observes actual door clearance rather than requiring an invented unlock. The real exit can be reached with two of its three switches activated. The fifth map completes without a wall switch; its pickup and sector scripts supply the required progression. Optional original content remains loaded and available.

Earlier fourth/fifth routes included 3,697 airborne, 13,692 third-person and 10,793 pitched frames, plus308 level/pitched PC draws alongside the reference renderer. Ten carry guards still reject invalid/late values. No inventory grants, teleports, forced defeats or script-state shortcuts are used in the completion run. campaign-validation.json binds all linked sources, headers and test includes. The separate second/third-level drivers remain available; their older reports record earlier checkpoints. The sixth map naturally spawns and defeats D7 through the original scripts, then completes through opcode 9. Unlike the earlier maps, it has no initial exit pickup. The seventh map is the first in the second resource family, and now completes with112 spawned enemies and its real scripted exit using only the sixth map's earned carry and its own pickups. It adds3,439 airborne, 8,724 third-person and9,000 pitched frames, with196 PC/pitched draws alongside reference rendering. It acquires weapon7 from the actual pickup and fires twice, recording390 converted-enemy controller frames. The eighth map activates both recessed switches and reaches its original VM exit in15,023 frames, recording102 enemy spawns,17 pickups,2,115 airborne frames, 7,320 third-person frames and7,557 pitched frames. Both original and PC renderers run, including168 PC level/pitched draws. The carried conversion gun fires twice, and410 controller frames now contain a converted enemy during an actual completed campaign map. The real native mixer plays all12,018,400 stereo frames with zero decoder errors. These current routes include the corrected Prion launch and Gunrilla cannonball clearance.

The ninth map completes in13,227 frames with106 original enemy spawns,14 pickups and53 health. The bot acquires weapon9 and fires20 times, recording448 actual E3 actor frames in the shared projectile scheduler. It also records12,991 converted enemy frames,2,382 airborne frames,6,627 third-person frames and4,857 pitched frames. Both renderers run, including148 PC level/pitched draws. The native mixer renders10,581,600 stereo frames with zero decoder errors. This is an earlier nine-map checkpoint; current admission is summarized above.

The test planner recovers from grid/corner stalls by making short ordinary movements at exact cardinal/diagonal headings, looking for doors and jumping. Map6 uses3 recoveries and map7 uses28. Collision and original wall sliding remain unchanged. Recessed switches use a farther80-unit input-planning approach when the original48-unit stand point is too small/low for Sam. The original use query spans64 units plus body radius, so it activates them normally from the room. Both normals are tried; no runtime collision or interaction range is changed. The eighth, ninth and tenth maps each use two navigation recoveries. The later-map bot reverses a blocked strafe, jumps more often during fights, uses carried conversion ammunition against Gunrillas, and avoids wasting shots on converted allies or repeatedly selecting weapon9 for a target already marked by its effect. These remain normal PC inputs. A closing door's original radius-sampled crushing hazard killed the first probe; the bot now waits clear and looks away until the door finishes closing. It records14 such waiting frames on map9 and11on map10. No game hazard, collision, enemy health, inventory or script behavior was changed to pass. Earlier failed/aborted probe logs are retained in build/native-campaign/; they are not completion evidence. The updated GCC sanitizer/Windows proof is the full 140,712-frame chain, rather than an isolated granted loadout or a resumed snapshot. The player's stats, actor bodies and scripts are never changed by the bot. The checker can write an earned entry snapshot with ssa_native_campaign_check.exe 9 build/native-campaign/entry.bin and run an isolated development probe using --resume 9 build/native-campaign/entry.bin. Resumed probes are explicitly labeled and are never accepted as the default consecutive campaign validation.

scripts/test-native-campaign.ps1 also exercises the actual Windows launcher, Enter advancement and R restoring entry values with both renderers and a real, muted audio device. Its explicit end-screen/death fixtures test the frontend; the independent campaign bot proves real gameplay completion. It additionally checks original map presentations with no simulation progress and the map-to-level music handoff on advancement and restart. Physical input and listening remain untested. The current run covers all ten boundaries and entry restarts through index10, with40frontend stages,21map views and1470frozen map ticks per renderer. All21reveals check immediate weapon/HUD display, movement and entry state; captured black/midpoint/full pixels verify each fade. Evidence is in campaign-validation.json and windows-native-campaign-validation.json.

The ownership test adds 4,817 checks on all 16 maps. The existing combined frame regression passes 997,410 assertions over 8,220 frames. New enemy, pickup and particle recovery proofs are documented in enemy-control.md, enemy-ranged.md, pickups.md and particle-projectiles.md. These behavioral ports do not imply additional byte-matched functions in the decomp.wtf catalogue.

Build/test commands:

powershell -ExecutionPolicy Bypass -File scripts/build-windows.ps1
powershell -ExecutionPolicy Bypass -File scripts/test-native-game.ps1 -SkipBuild
powershell -ExecutionPolicy Bypass -File scripts/test-native-campaign.ps1 -SkipBuild
.\decomp.ps1 test-second-level
.\decomp.ps1 test-third-level
.\decomp.ps1 test-campaign
.\decomp.ps1 test-native-playability
.\decomp.ps1 test-native-game
.\decomp.ps1 test-map-gameplay-ownership

Player rockets and cannonballs now fly independently from launch, and continuous local weapon audio stops when firing ends. The changed rocket combat route accounts for the updated fourth/fifth-map outcomes above; the normal-input bot is unchanged. It also exposed a portal raster boundary now clipped safely. See weapon fixes.

The Win32 map handoff now puts the weapon at its normal ready position before building the first reveal image. The weapon fades in together with the world from the first visible frame; it no longer raises only after the reveal ends. Third-person hiding and music timing remain unchanged. Gameplay and the HUD now update during the reveal, with controls available from its beginning.

The current reveal is live: capture and keyboard controls are available immediately, and input, physics, enemies, weapon animation and HUD advance on the normal simulation clock while each fade step is presented. Sprite cache transfers are completed before the first visible image, so the full HUD accompanies the ready weapon. The outgoing map and black hold still keep gameplay stopped and own the map soundtrack. The reveal lasts at least one second independently of the simulation clock. Mouse look stays active throughout the reveal.

Windows transition checks deliver W input and require actual XY movement during every map reveal in both renderers. Initial HUD residency and entry carry are checked before live gameplay can change inventory. Black/midpoint/full images are compared to paired unfaded images from their own simulation frame; the older frozen-frame comparison is no longer appropriate. These diagnostics are recorded in windows-native-campaign-validation.json.

The Windows frontend also accepts mouse-wheel weapon selection while gameplay has mouse capture. Wheel up selects the previous usable weapon and wheel down selects the next, wrapping through IDs 1–10 and skipping unowned or empty weapons. The relative selection begins at the requested weapon, so rapid scrolling works during the original lower/commit/raise animation. Partial high-resolution wheel deltas accumulate; focus/capture loss clears them. Menus, map view, pause and death do not accept wheel selection. Number keys retain their existing behavior.

scripts/test-weapon-wheel.ps1 -SkipBuild exercises the actual Win32 message handler on a hidden window and advances native ticks through a completed switch. Its 158 checks cover rapid/partial/multiple notches, both wrap directions, Q toggles, key repeat, availability, inactive input and bounded extreme step counts. It does not test physical mouse delivery. Results and hashes are recorded in windows-weapon-wheel-validation.json.

Q now selects the last actually equipped weapon, so successive presses toggle between the last two usable weapons. Requests alone do not alter history; the native lower/commit stage does. History carries between levels and in the restart entry state. An unowned or empty previous weapon is ignored. Key repeat, menus, map view, pause and inactive gameplay cannot trigger Q.

E button activation is independent of weapon stowing. The frontend's gameplay.immediate_use policy activates the original switch, texture, script and click on the first valid use tick, while the real weapon action/animation continues. The use key, contact geometry and original one-shot switch latch still apply. This is separate from the requested firing-completion gate for weapon changes. See interaction checks.

The frontend enables finish_fire_before_switch. Number keys, wheel and Q can change the pending destination during firing, but lowering waits for completion. Discrete weapons finish their entire firing/reload sequence. Continuous weapons coast to the current cycle's end without further attacks, then run the normal stop/wind-down and handoff. Sticky loop completion flags are reset when this wait begins. Pause freezes the wait. Selecting the current firing weapon again cancels the pending switch. Impact effects use the actual firing weapon during the wait. The default recovery runtime leaves this PC policy off.

tests/test_weapon_switch.py and scripts/test-weapon-switch.ps1 -SkipBuild pass 3,295 checks on GCC ASan/UBSan with leak detection and MSVC: all ten weapons in both views, 506 waiting frames, pause, released fire, empty automatic ammo, overwritten/cancelled destinations, previous-weapon availability and campaign carry. Cadence/quick-click checks remain 53,141 and the original runtime regression remains 133,923. Windows weapon-audio/rocket/Prion checks pass 127,418 assertions including six cannon launch regressions; frontend perspective/chase/4K/reference smoke remains a separate earlier checkpoint. The current eleven-map campaign proof above includes this PC handoff policy.