Need help getting started? Try the player guide. These notes include older work; the game overview explains what’s ready now.
Native port findings
Sprite shadows (2026-10-21): Graphics now offers independent size-scaled player/enemy/item billboard sprites, Off by default, in all three renderers. Each shadow is drawn immediately behind its subject with wall silhouette clipping; the former floor-projected sampling pass has been removed. Settings v19 preserves the16-byte record and reads v1..18. Visual-effect rows are88/96/104/112; Back remains144. See sprite-shadows.md.
Graphics now holds Surface decals, Water reflections and Godrays below Mipmapping. Extras retains eight gameplay/presentation rows. Saved values, defaults and v18 settings layout are unchanged; all three effects remain available in GBA, Software and Vulkan.
Settings now has one Mouse sensitivity slider above FOV, with 10..300% range and100% preserving the previous64 heading-units/count speed. The shared horizontal/vertical value applies immediately and persists across levels. Settings v18 retains16 bytes and the CRC, using a compact header/payload while reading v1..17 unchanged; v1..17 mouse values migrate to100%, and v18 uses its saved horizontal value. See mouse-sensitivity.md.
Extras now has an independent Godrays toggle below Water reflections, default Off for fresh settings. Settings v17 preserves the16-byte CRC layout, reads v1..16, and migrates the previous coupled Surface decals choice to Godrays. All three renderers and reflections honor the separate choice; see surface-decals.md.
Graphics now offers original-asset mipmapping for Software and Vulkan, locked On for GBA. World textures, sprites and reflected scenes use the ROM's existing mip images. Settings v16 preserves the16-byte format and reads versions1..15; fresh settings enable mips while migrated native preferences retain their previous appearance. See mipmaps.md for selection and validation details.
Vulkan is now an optional Windows hardware scene backend, selectable in Graphics
when available. Walls, floor/ceiling polygons, actors and mirrored scenes use GPU
rasterization; HUD, decals/water composition and presentation retain their CPU
paths. Software/GBA remain available and settings versions1..14 remain readable.
See vulkan-renderer.md for architecture and focused evidence.
The initial severe Vulkan stall is corrected: dedicated cached readback, bounded
parallel effects, amortized buffer growth and visible-row reflection transfers.
scripts/bench-vulkan.ps1 measures isolated render time; reflections remain the
heaviest case. Resolution, artwork, simulation and audio timing are unchanged.
Technical audit follow-up: save-read failure handling, locked audio status, a shared decal atlas, separate scene/HUD link targets, centralized runtime settings, and focused incremental tests are implemented. The latest render-loop pass combines GPU sample processing, skips overwritten clears and reuses identical sky rows, with exact before/after outputs and measured lower render times. See technical-refactors.md for scope, measurements, and validation; frontend separation remains incremental.
Current milestone: all twelve campaign levels are enabled through play-native.cmd.
Extras now offers a saved Original/Classic HUD choice, defaulting to Original.
Classic reconstructs the retained green interface with live health, armor, ammo,
score, saved/live high score, time, unread NETRICSA entries and boss health in both renderers. It adds a transient weapon
selector, health/ammo palette flashes and static white localized notices.
New dossiers blink the retained analyzing sprite in HUD green without backing near the upper
center for2s, then teleport the green/white inbox inward, hold2s and teleport
back. Duplicate entries do not retrigger it.
Classic's other anchors now follow the Serious Engine layout with2px edge
insets, spaced armor/health, separate finite/infinite weapon positions and a
higher selector. The former top-center timer panel now shows max(saved high
score,current score), inset2px vertically; the timer sits immediately below.
Weapons and crosshair keep their existing behavior. See classic-hud.md.
The shared original sprite compositor now accepts mixed priorities, including
transparent-sample priority promotion, instead of rejecting the frame. Both
renderers benefit; see display.md for the bounded hardware-model
evidence and native/Windows checks.
The Main-menu Scores screen now includes original ranking/name entry and saved
records, with keyboard typing, original cycling and record highlighting. Pause
Quit and campaign-ending handoffs offer qualifying scores; see scores.md.
Death now consumes a life and automatically retries from the level-entry snapshot.
Retries skip NETRICSA and the map, starting directly at the normal black-to-level
fade with the ready weapon, HUD and movement available.
The final life runs the original Game Over message/music before the black fade
and Main return. A stale pause bit cannot stall the death controller.
See run-exit.md.
The automap now opens with M in both renderers, gated by the saved Automap
On/Off option in Extras (default Off; explicit saved choices retained). Mouse wheel or held
plus/minus zooms; live geometry, markers, contacts, palette and scanlines run in
native C. Tab retains NETRICSA. See automap.md.
Jump now defaults to Off in Extras. Existing explicit saved choices are preserved.
Native NETRICSA now toggles during gameplay with Tab; N opens/closes and Esc returns.
It also precedes every pre-level map view. In-game NETRICSA overlays a frozen
full-resolution game frame; only pre-level NETRICSA uses the animated background.
In-game fades take250ms; pre-level NETRICSA retains its original fade speed.
The in-game blend removes HUD sprites except the weapon
while darkening and tinting the frozen level green; closing reverses the blend.
Original weapon/enemy illustrations, localized descriptions, two scrolling panels,
strategic/tactical records and live/campaign-session statistics are connected.
Enemy dossiers unlock only after a kill. A campaign-session journal tracks
weapon/enemy discoveries and individual read status across levels and retries;
Classic's top-right panel displays the combined unread count.
Every level's starting equipment is familiar: viewable, automatically read,
without a new-message count or notification. Actual in-level discoveries still
alert, and carried unread messages retain their status across level changes.
NETRICSA freezes gameplay. Pre-level briefings use the original music cue;
in-game opening/closing preserves the current music's uninterrupted playback.
See netricsa.md.
On2026-10-17 the user explicitly requested manual campaign validation rather
than gating levels on automated playthroughs. The final map, Caesar's Palace,
now participates in normal advancement, passwords and saved level selection.
Existing saves remain compatible; beat map10 to unlock map11, or use
play-native.cmd --level 11 for a direct standalone start.
The original campaign story controller19458/193D8/1965C and its native screen
now connect Egypt/Rome/ending panels, artwork, text, music and fades to the
frontend. The controller passes50,462 ROM comparisons; text adds1,018 original
row comparisons, with87,854 native screen assertions and three Windows paths.
The final completion tally leads into the ending and returns to Main. Esc/P now
opens the native pause menu. The original time/ammo tally, bonus score carry and
final Sam text/music hold are connected; high-score/name entry remains. See
completion.md and campaign-story.md.
Original localized HUD notices now connect pickup, boss and death callbacks
to both renderers, including cache readiness, layout and shared lifecycle timers.
The controller passes135,104 ROM comparisons, native integration passes13,650
checks, and normal-input level1 still completes in5,110frames. See
hud-notices.md. The timed completion tally's active notice
service is available; its outer screen/digits/audio/record integration remains.
Rome maps now retain the original golden ankh, including the full20x34 and
distant10x17 images decoded from the ROM. The former laurel override is no
longer applied or linked into the frontend. Its artwork is retained as
historical material.
Advancement now recovers original player construction and weapon restoration:
100 health, zero protection, earned weapons/ammo and score. R retains the exact
level-entry snapshot. See campaign-entry.md for 8,192
original restore comparisons and 512 construction/restore sequences on 16 maps.
Original completion capture 1231C now runs natively too: another 4,096 ROM
comparisons and 512 capture/restore compositions cover gear and per-weapon
statistics rows. The original completion-statistics accumulator and checkpoint
helpers are now native and byte-matched too. Their read-only native adapter
exposes all live counters; campaign-session totals now feed the completion frontend; original high-score lists
and name entry remain unfinished. See statistics.md.
The timed time/ammo bonus controller and final record pipeline are now recovered
too: 11,466 original-loop frame comparisons and 410,217 native composition checks
pass. The pause/completion frontend now connects original notices, digits,
voice dismissal and campaign-session totals. Active E914/E9D4
message sprites are now recovered and used during gameplay. See
completion.md. The later frontend integration connects the timed tally and bonus-adjusted carry to
the playable executable. The subsequent targeted cannon fix now detaches player cannonballs
at launch, like rockets and Prion shots. Cannonballs retain original no-gravity
flight and now continue rolling horizontally on floor contact, without adding
airborne gravity. Rockets still explode and Prion shots stop at ceilings.
Six launch/trajectory cases per weapon and12ceiling contacts validate these
paths; current counts/hashes are in weapon-fixes-validation.json. The default
projectile integration and enemy cannon regression also remain covered.
The rebuilt launcher/startup/restart checks pass. Full campaign replays were
not repeated for this correction. See weapon-fixes.md.
Prion-converted enemies now continually select the nearest living combatant,
including Sam, other converted enemies and bosses, without player preference.
Facing, ranged aim and enemy melee follow that selection. The focused test passes
1,602 checks on GCC sanitizers and Windows across all ten convertible types;
special weapons retain 32,318 checks and default entity runtime 85,982. The rebuilt
Windows launcher/startup/restart checks pass. See
projectile-conversion.md.
Campaign figures below are historical replays, before this targeting change.
The corrected normal-input chain completes all eleven in 140,712 frames with
1,544,000 score / 45 HP. It includes the latest collision, Prion2x and Time Strike
changes. It supersedes the older 136,552-frame full-vitality-carry checkpoint.
A retained converted-enemy target pointer exposed
an overly strict projectile-adapter guard; cleared/reused stable slots now follow
original1097C behavior, with16 native Gunrilla regressions and two directed ROM
comparisons. Read
native-game.md for the current composition, validation and limits.
Earlier sections retain the recovery history and individual subsystem boundaries.
The eleventh-level probes found a Time Strike render failure: an animation change
while frozen retained a frame from a longer sequence. The native view adapter
now supplies a valid frame in its render snapshot, without advancing animation
or changing gameplay. Both renderers and views pass the32318-check special-weapon
suite on GCC sanitizers and MSVC. Praetorian Fort now completes through normal
input with earned equipment and original next-level vitality. A separate Normal
standalone test now completes the final map: D8 defeat, original music changes
and the VM exit in 17,270 frames with 63 HP. GCC sanitizers and MSVC agree on
every standalone field. The final earned-inventory probe dies before the boss,
so that map remains unavailable. See native-game.md
and special-weapons.md.
Weapon7 Prion shots now launch independently on the sight line immediately,
including level aim before any pitch input; the old sideways offset is removed.
See weapon-fixes.md.
Gunrilla cannonballs now clear their own shooter at launch while retaining
normal impacts against walls, players and other enemies. See
projectile-runtime.md for the scoped collision fix and tests.
The playable PC and reference renderers now restore original0750C/0787C bar
colors, rather than using the static sprite palette for every row. See
hud-colors.md for original-ROM pixel comparisons.
Startup/restart now restore the original pre-level map view and its music;
simulation, controls and HUD start during the level reveal after the map's black
hold, with the level soundtrack.
See map-view.md. Original feature parity is the completion target;
the full campaign, remaining menus and other documented gaps remain unfinished.
Normal startup now goes straight to Title, then Main/Single Player/difficulty.
Select Level now appears between New Game and Password, with saved completion
unlocks and original localized campaign names (no multiplayer maps). Language
persists too. Clear Data in Options uses a Yes/No warning, default No, to reset
both. See profile.md for storage, loadouts and validation.
Options cycles English/German/French in place alongside music and credits;
there is no startup language list. Passwords load the original
weapons/ammunition and difficulty on supported maps. See menu.md for
coverage and original-ROM proof.
The original fixed BG1 grid now overlays the scrolling menu background from
the first title/main-menu visit, as requested.
Fresh diagnostic level launches now use the ROM's original level-start weapon
and ammo records, like password starts. Existing progress takes precedence:
advancement retains carried weapons/ammo, and R restores the captured entry.
Mouse hover/click now selects menu labels with correct letterbox coordinates;
passwords accept direct keyboard text and editing. The menu soundtrack continues
across Press Start. Shared pointer/text helpers prepare future NETRICSA and score
screens; those screens remain unfinished.
Both boss controllers are now connected to the native dispatcher, animation,
combat, projectiles, script queues and HUD health binding. The sixth map's D7
fight and scripted completion are verified; later boss-map progression remains
unvalidated. Weapons 8/9 and original background/hurt palette effects now bind
to native gameplay and both renderers; see special-weapons.md.
See enemy-boss.md.
Type-64 effects now use recovered wall/sector clipping and sector-only list
updates; see sector-clip.md. The validated playable campaign
historically covered eleven maps. Admission now includes all twelve by user request.
The seventh/eighth are in the second original resource
family; their real exits complete through native scripts without grants or shortcuts.
Established input behavior
| ROM address | Behavior | Native implementation |
|---|---|---|
0x08003028 |
Read active-low KEYINPUT; held/newly pressed edges; reset chord; record/playback selection | ssa_input_poll |
0x08003150 |
Pack buttons into one byte and append while count <= 0xE0E | ssa_input_record |
0x08003298 |
Expand packed buttons; advance repeat count and RLE stream; 0xFF ends playback | ssa_input_playback |
These three behavioral ports passed 14,848 differential cases against the supplied ROM's original instructions. The test includes all 1,024 physical button masks, simultaneous opposite directions, all 256 packed values, recording bounds, repeat-count bounds, record/playback priority, state flag gating and reset calls. It does not establish correct full-game integration, rendering or mouse controls.
The input state starts at 0x030042F0:
| Offset | Observed use |
|---|---|
+0x00 |
Raw held (low halfword), pressed edges (high halfword) |
+0x04 |
Processed held/pressed after recording/playback selection |
+0x08 |
Saved global value during record/playback setup; broader purpose unresolved |
+0x0C |
Recording-buffer pointer |
+0x10 |
Playback-stream pointer |
+0x14 |
Game-state value, not recovered here |
+0x1E |
Recording position |
+0x20 |
Remaining repeat count |
+0x21 |
Current packed playback buttons |
+0x22 |
Reset-related byte cleared when reset chord is absent |
+0x23 |
Bit 1 records; bit 2 plays back; recording has priority |
0x03004010 holds a pointer to another object. Bit 0 of its halfword at
offset 4 suspends recording/playback. Its broader game-state meaning is not
established. The native API calls this input_suspended.
The original recorder resolves simultaneous left/right to left and up/down to up. Select and Start are not encoded in recordings. Playback emits the current buttons before consuming the next run. Raw hardware polling retains the upper six bits of the inverted halfword; masking them early changes reset detection. Native pointers deliberately have host width; the native structure is not a binary-compatible GBA RAM structure.
Matching status and tool fixes
Live matching is 78/526 functions and 2,816/87,648 catalogued bytes (3.21%),
after 549 compiler attempts (live status checked 18 October 2026). Original statistics helpers 1CF4, 1D9C and
1E48 add 592 exactly matched bytes. Both export and independent rebuild
preserve the original ROM byte for byte.
The manual recorder candidate is 97.5% similar, with the remaining differences at the initial global-pointer/limit/load scheduling. It is not counted among the exact matches. Its best source and notes are stored in decomp.wtf.
The matched catalogue contains 2,816 bytes of verified C out of 87,648 imported function bytes. This denominator excludes undiscovered code. The 8 MiB image size is mostly data and is not a useful code-completion denominator.
Luvdis needed bounded-stack fixes for speculative paths, conservative handling
of partial BL instructions it cannot model, and buffered output for WSL.
scripts/test_luvdis_stack.py verifies large frames, negative stack positions,
ordinary returns and unsupported partial calls. These changes do not modify
the ROM. The initial 525-function catalogue was retained after an aggressive
additional sweep proposed thousands of unverified starts.
The GBA exporter emitted unresolved Thumb-call labels as untyped absolute linker
symbols. GNU ld inserted interworking veneers, overflowing the fixed ROM layout.
The local patch emits typed absolute Thumb function symbols in a separate object.
The exporter also now discovers unresolved canonical address symbols from C
objects, including uncatalogued calls and IWRAM data references. Thumb-call
relocations determine function mode; ordinary ARM calls retain ARM mode. This
fix is recorded in patches/decomp-wtf-c-externals.patch and applied by bootstrap
after the existing Thumb-symbol patch. tests/test_export_c_externals.py checks
both patches against the pinned upstream and links real ELF objects to verify
symbol types, data addresses and absence of added interworking veneers.
The full rebuilt image is checked against the original. Unmatched code remains assembly
or original data; the rebuild is not evidence of a complete decompilation.
Earlier recovery plan and subsystem checkpoints
These are older development notes. See What you can play and Playable build details for what you can play today.
Next work required for the requested playable port
The input-to-player path and pre-collision control/vector phase have now been
recovered. See analysis/movement.md for addresses, original quirks, native API
scope and 106,577 differential cases. This includes heading math and movement
velocities. The static collision and move-commit work described below is now
implemented; the world integration described below adds the timestep and sliding.
The PC event adapter and Win32 backend are now implemented; physical-device
validation and the complete game frontend remain. A diagnostic native viewer
already runs movement, jump, H camera, world geometry and original actors.
Vertical position/gravity and camera height are now also ported; see
analysis/physics.md. Those complete routines pass 31,567 ROM comparisons.
The user-requested jump extension is separate native code with 36 behavior
scenarios. All 16 map resources now load natively with original wall setup;
see analysis/map-assets.md. BSP lookup, static map queries and clearance/move
commits pass 62,118 ROM comparisons. Another 16 start-position checks and 32
real-map jump scenarios cover original spawn points and player dimensions.
See analysis/geometry.md for the static query scope. Native entity collision,
host spatial lists, wall sliding and horizontal timestep integration are now
implemented, with 71,808 additional ROM comparisons. See analysis/world.md
and analysis/sliding.md. Pickup dispatch and synchronous world removal are now
also recovered; scripted effects, combat and OS controls remain.
- Expand the function catalogue from actual call targets and validated code ranges. Review ARM startup, hand-written math/render routines and code copied into IWRAM; do not count speculative asset bytes as functions.
- Continue into subsequent enemy AI, scripted effects, other gameplay contacts
and projectile simulation. Map-object construction
08001984, inventory helpers and type-0xE1 dispatch0801B99Care now native. The latter still exposes script/audio/HUD/network/nearest/destruction boundaries through callbacks. Seespawning.md,inventory.md,pickups.mdand updatedworld.md. Queued acquisition and cycle selection are also recovered and verified; seeweapon-selection.md. Requested/current animation handoff and original weapon control now live inweapon_controller.candweapon_runtime.c. Player initialization05E4C, complete movement064B8, frame wrapper05CCCand entity timer12CFCare now native.player_runtime.cjoins these with native jump and H-camera behavior. Death06154, respawn05FEC, spawn selection01B18and hazards05680are now recovered and connected throughplayer_gameplay.c. Their 40,068 ROM comparisons and 10,016 native integration frames are documented inplayer-lifecycle.md,respawn-selection.md,player-hazards.mdandplayer-gameplay.md. Moving sectors, switches and the level-script interpreter are now native: another 44,433 ROM comparisons include all 116 real script entries with controlled spawn/effect dependencies.level_runtime.cconnects line/sector triggers, mover hazards and script mover commands. Entity updates precede movers, which precede the script VM, as in0800244C. Seelevel-runtime.md. Scripted creation now uses native pool/world insertion inscript_spawn.c; all twelve enemy state-zero initializers are recovered, including boss setup. The pool and activation paths pass 36,697 and 14,576 ROM comparisons. Native script-spawn integration runs all 116 original entries; explicit test defeat notifications unblock groups without pretending to simulate combat. Seescript-spawn.md,entity-pool.mdandenemy-activation.md. Shared navigation, directional walking, hazards and death/corpse handling now compose with the type-CD controller inenemy_cd_runtime.c. Another 121,260 ROM comparisons and 59,319 native integration assertions cover this work; seeenemy-cd.md. Its 62-byte outer dispatcher is also byte-identical C. Original visibility B18C, nearest selection 036C4 and wall rays A240/A041 now compose throughenemy_queries.c, with 263,969 additional ROM comparisons and 53,384 native integration assertions. Seeenemy-queries.md. Other enemy controllers remain. Damage 037F4, explosion 035A8 and reward 125E0 now compose throughcombat_runtime.c, with 155,517 ROM comparisons and 26,435 integration assertions. CD contact damage and chain explosions reach real player/enemy health and death handling. Seecombat-runtime.md. Weapon animation, all ten firing controllers, auto-aim and hitscan now pass303,556 further original ROM comparisons; seeweapon-animation.md,weapon-controller.md,weapon-aim.mdandweapon-hit.md.weapon_runtime.cbinds hitscan damage and selection to native gameplay. Projectile construction, flight, five controllers, wall reflection and attached conversion effects now pass136,192 ROM comparisons.projectile_runtime.cconnects weapons6/7/10 to the shared native pool and combat. Type69 converts enemies to target other enemies and drains health; the previous freeze/thaw interpretation was incorrect. The CD runtime now shares the original drain fields with projectile impact. Projectile68/6A splitting/spread and presentation remain. Seeprojectile-conversion.mdandprojectile-runtime.md. Aimed constructor109F0 is another48-byte exact match. Original entity scheduling04E04/083E4 now passes72,420 ROM comparisons;entity_runtime.cconnects players, CD enemies, projectiles and owned pickup timers in that order of active slots. Integration passes85,982 assertions on all16maps, including jump/H. Other enemy handlers and the complete outer game loop remain. Original initial loadouts1240C pass12,979 ROM comparisons; native startup passes84,077 assertions over608starts and192shots from the original selected weapons. Seeentity-runtime.mdandweapon-start.md. - Continue active text notices, palette/blending effects and remaining sprite controllers. Normal weapon/HUD/OAM composition and original240×160 display sampling now work natively, following D2D0/01828 actors, wall occlusion, solid/portal walls and floor/ceiling/sky. Complete game presentation remains. Replace GBA VRAM, DMA, interrupt and timing operations with native platform interfaces.
- Finish platform/mode/level startup integration, asset loading, audio and save handling. Add native
keyboard bindings, relative mouse yaw, independent strafe and movement.
Determine whether vertical look is compatible with this renderer before
promising free-look behavior.
The0244C frame and F85C sprite dispatchers now pass10,500 and70,344 ROM
comparisons. Actor00908 animation and multiplayer pickup respawn pass218,240
and73,734 comparisons.
game_runtime.ccomposes these with native entities, movers/scripts and weapons, passing997,410 integration assertions with genuine two-player shared lifecycle/input, live local hazard flags and shared CD sound state. Input distribution, mode control and rendering remain external stages. Seegame-runtime.md,frame.md,sprite-dispatch.md,actor-animation.mdandpickup-respawn.md. Actor setter05394 adds a60-byte exact match. - Extend the existing Windows native viewer into the actual full game and verify menus, combat, progression, sound, save/load and original frame timing.
PC event sampling and frame integration now provide WASD, mouse yaw/fire, Space,
H and E, with314,726 sanitizer assertions on all16maps. The Win32 event backend
passes3,215 MSVC assertions with posted window messages/raw payloads; physical
device delivery remains untested. All90 portable libraries plus the Win32 backend
build as91 native Windows x64 libraries, plus the native viewer.
The viewer is incomplete; no complete game executable exists yet.
The local05898 distributor adds183,988 ROM comparisons, with genuine network
distribution explicitly unsupported. See pc-input.md and win32-input.md.
All311 original sprites and gameplay palettes now decode; original transfer/OAM
and palette routines validate1,261pieces/6,730tiles. E320 adds a56-byte exact
match. DBDC is sprite visibility/cache preparation, and FCE4 constructs OAM;
the legacy RENDER_WORLD enum does not describe a recovered world renderer.
World texture archives now decode666images/2,567,040bytes, with wholeAFF4/AF18,
65,539name comparisons and55,440 originalcolumn-copy blocks proving layout.
Map wall bindings preserve live switch changes and pass1,059wholeB0C4calls;
B0C4 matches54bytes exactly. Original ARM texturedcolumns pass67,678wholecalls,
including7,992 usingall666loadedimages. Flatcolorfills andskycopy add6,189.
The actual chain is02B88 ->B6B0 ->017CC ->BE60 ->ARM002F4; AB10/A98C handle
flatcolor/skyplanes. Those geometry stages and the original actor passes now
compose natively; HUD and final game integration remain. See world-scene.md and
texture-assets.md, map-texture-bindings.md, world-raster.md
and raster-fill.md. Sector+A/B arecolor/skyselectors,NOTtextureindices.
Original021E4 pause/menu orchestration is native with13,092wholeROMcomparisons,
60,101reentrychecks and41failureprefixes. UI command8EB0 andspritecreationE914
remainmandatoryevents. GameRuntime CONTROL still delegates toexternal; frontend
mustbindcanonicalflags/sharedinput_state andimplementevents. See mode-control.md.
The H-toggle third-person camera extension is now implemented independently in
src/view.c; see analysis/view.md. It computes a chase pose from recovered
player/eye state, retracts against static geometry and preserves gameplay aim
and movement. Native PC/Win32 event routing now handles H presses/repeats;
the native viewer displays this chase pose and Sam's original animated body.
H clears flag80 only in the rendering source snapshot, with gameplay flags
preserved. Complete third-person game integration remains.
World geometry continuation:218,912visibility ROMcalls;14,322completeBE60solid/
portal calls;23,955plane routines. Connected B6B0/017CC/BE60/AB10 matches128
wholegeometry frames/all16maps/1,843,200pixels, withactorD2D0/01828excluded.
2,048PC/game/jump/Hframes add481,049sanitizerassertions and225guards while
drawingactualgeometry. View routing02B88 adds84,032wholecalls/274,785native
cameraassertions. B220 matches42bytes,A87024bytes;09238 adds32bytes andFB5C68.
The catalogue nowcontains74exact/2152bytes=2.46%.
The74-Cexport and independent rebuild are byte-identical.
See world-visibility.md,
wall-renderer.md, plane-renderer.md, render-view.md and world-scene.md.
Windowsviewer usesactualsingleplayerspawn/motion/collision/camera/jump directly,
withoutdummyGameRuntime or gameplaycallbacks. Nativeclear/world events render
120x120worldindices,then240x160displaycomposition usingoriginalpalettes.
Inputrawmouseforegoundonly,
clickcapture,Esc/focus/menu/cancelrelease. 3,840hiddenWin32/GDIframes/all16maps
and4CLI/ROMrejections pass; physical-device/visible-window interactionuntested.
Original animated objects and the H body now render; combat,pickup execution,
scripts,movers andaudio remain outside theviewer. Original normalHUD andidle
startingweapon nowrender throughcache/OAM/240×160display; nofirecontrollerbound.
Launchwith
run-native-viewer.cmd [--level N]; see native-viewer.md.
Actor continuation:142resources/5407imagereferences/2607uniqueimages copy and
decode natively. Whole09238/09258/ARM0638 sampling passes13787 original draw
comparisons; ASan adds37860assertions. NativeD490/D884 projection andD2D0/D338
collection pass17664 isolatedcalls/256collections with9110emittedrecords.
NativeF98/1238/01828 queue/depth/occlusion passes67840ROMcalls plus36564sanitizer
assertions. Full originalB6B0 without actor hooks matches3686400pixels over
256views/all16maps, including128animatedframes,317actorcommands/2584walls.
Only BIOSdivide/CpuSet/DMA are modeled at that boundary. See actor-assets.md,
actor-projection.md, actor-queue.md and native-actor-scene-validation.json.
MapActors owns the385 original mapobjects, in01984allocation/world order, with 00908animation and no invented activation/AI state. All16maps/2048animation frames/49280originalrecords compare; owner lifecycle passes5404sanitizer assertions and preserves separately owned playerbodies onfree. Windowsviewer draws18326actorcommands,2762120changedactorpixels and1600visibleSamframes, using original65/66animation andD338overlay. The portable tests and Windows viewer exercise rendering independently of unfinished fullgame orchestration.
Normal sprite presentation now composes natively. The84-slot pool and101F4 constructor plus normalHUDcontrollers pass77424 whole-routine comparisons. FullFCE4/E648/FC3C/FC58 OAM passes6036calls/45603entries/10054affineobjects, with13183sanitizerassertions. Fullcache/visibility/allocator/transfer/reset adds 30596comparisons/7769920uploadedbytes/20624sanitizerassertions. The recovered mode1 display usesPA128/PD192 to sample the world at(x/2,floor3y/4) for240×160, withactualseparatepalettes andphysicalOBJ32Kmirror. Originalregister/map/tile setup passes448calls;635independentpixelframes coverall311realimages and128 affinecases,plus418281sanitizerassertions. Unsupportedblend/window/mosaic, mode4automap andpriority/budgetoverflow remain explicit errors.
The diagnosticHUDscene runs real1240Csetting0 before74HUDobjects,then12160 idleweaponraise,scalarHUDcontrollers,E460,DBDC,FCE4,E358andnativecomposition. Hhidesfirstpersonweaponwithoutchanginggameplayaim/body. Healthcomesfromspawned entity,armorfrominventory; score/time remaininitialized. Firing/combat arestill unbound rather than mocked. ActiveDnoticesexplicitlyunsupported. Windowsviewer passes3840frames/all16maps,3856HUDdraws/2112raisedfirstpersonweapondraws, 21807376changedpresentationpixels. Sourceandtestreports document boundaries.
ExactFB5C sprite-mark adds68bytes/34instructions,secondmanualcompile: live
catalogue74/526,2152/87648bytes(2.46%),517attempts. FC3C83.9%(2attempts) and
074F0 83.2%(5attempts) areNOTexact. The74-Cexportrebuild isbyte-identical.
See sprite-cache.md, sprite-oam.md, sprite-pool.md, display.md,
hud-scene.md and currentvalidationJSON reports.
Historical checkpoint: first playable level — 15 October 2026
These are older development notes. See What you can play and Playable build details for what you can play today.
Playable level-one checkpoint, 2026-10-15
native_game.c and platform/win32/game.c now compose real simulation and
rendering. The new play-native.cmd frontend exposes level0 only. The original
viewer is retained separately. Normal difficulty, original loadout, live map
objects, CD/CE/CF AI, real damage/firing, pickup inventory, wave/group gates,
movers, exit detection and native PC restart all run. Space and H remain active.
Audio is muted; original active text notices use simple host text.
The first-level bot uses only normal PC event APIs and read-only observations; its route planner changes only a private map copy. GCC ASan/UBSan/leak scanning and MSVC x64 both finish in5258 frames:28000score,8pickups,19spawned,100health, 13pistol/23shotgun shots. All16-map ownership proof adds4817checks. The existing game-runtime suite passes997410assertions/8220frames after shared pool changes. There are99Windowslibraries and three executables including the completion check.
Next work is remaining campaign/boss and special-weapon support, original UI, cross-level inventory carry, remaining palette/display effects and audio output. Do not claim the complete game is finished or expose unimplemented campaign paths as supported gameplay. The byte-matching catalogue remains separate from behavioral native coverage. See native-game.md and current validation reports.
Historical checkpoints: weapon corrections and campaign progression — 16 October 2026
These are older development notes. See What you can play and Playable build details for what you can play today.
Native weapon corrections, 2026-10-16
Local minigun/chainsaw/machinegun loop ownership now stops stale firing audio
without cutting music or other sources. The PC game opts into launch-independent
player rockets; the original recovery runtime retains its attachment quirk.
The changed normal-input route exposed an offscreen portal row, now safely
clipped with original sampling preserved. See weapon-fixes.md and current
weapon-fixes-validation.json, windows-weapon-fixes-validation.json and
campaign-validation.json. That checkpoint covered five campaign maps; current
current campaign evidence is summarized above. These fixes add no matching catalogue entries.
The earlier110,468-frame consecutive run completed nine maps with earned carry. The sixth includes real D7 damage/death/projectiles/HUD/music and VM finish; the seventh completes in17,484frames. The eighth completes in15,023frames, ending at1,290,000score/78HP. The frontend admits indices0..8. The eighth adds both recessed switches, actual conversion frames and12,018,400 real-mixer stereo frames. The ninth completes in13,227frames with106spawns/14pickups, ending at 1,446,000score/53HP. It exercises original weapon9 acquisition and falling E3 effects,20conversion shots/12,991converted actor frames, both renderers and 10,581,600native stereo frames without decoder errors. The input bot waits18 frames clear of an original closing-door hazard, reverses wall-blocked strafes, and uses jumping and its earned special weapons. Only the admission count and normal-input test planner changed; no game collision, hazard or inventory bypass. The bot's cardinal escape steps, ranged spacing and supply strafing are normal PC input; game collision, enemy health, damage and script rules are unchanged. This proof uses the current original minigun cadence, firing-animation weapon handoff and immediate E-button policy, superseding older timing checkpoints. Boss/post-boss audio loops now use gameplay music2/19/20; focused126730assertions pass. Later D8 natural progression, interchapter presentation and original feature parity remain unfinished. See enemy-boss.md and current campaign reports.
Sprite floor clipping (2026-10-21)
Software/Vulkan now use the recovered GBA wall-silhouette rules for actors, including death/explosion artwork crossing its floor. Shared clipping operates before pitch and reflection transforms; nearer solid walls and portal bounds still hide actors. GBA remains unchanged. See sprite-clipping.md for implementation and focused regression results.
Floor/ceiling edge decals (2026-10-21)
Surface decals now includes randomly placed, connected grime strips at dry floor and ceiling boundaries. An8KiB stored binary atlas uses the existing surface palette and2-unit texels, with matching ports and empty/end variants. All renderers share the live boundary sampler and existing shoreline index. See surface-decals.md for ownership and validation.