92 KiB
Roadmap and open items
This is the single tracker for high-level work on the port. If an item
is not here, it is either done or not planned. The README's Known issues
and Roadmap sections are short summaries of this file. Root-cause detail
for each Dxx lives in dev/findings.md (find it via
dev/findings-index.csv; that index is generated,
first-line-only, and can lag the entry tail, so read the entry).
Last full triage: 2026-09-29. Sources: the findings log, all GitHub issues,
PRs and releases, every local backlog/plan/roadmap note, HANDOFF.md, all
local and remote branches, and known community forks.
How to use this file
- One row per item. Link the
Dxxand/or GitHub#issue. Keep detail in the finding, not here. - Status vocabulary:
open·partial·verify(fixed, a live check is owed) ·parked(work exists on a branch or patch, not merged) ·decision(blocked on a maintainer call). - When an item closes, delete its row. The history is kept in the finding and in git. Do not strike rows through. Struck rows are what made the old backlogs unreadable.
- New work goes here first. Do not start a new backlog, roadmap or plan-of-record file. A design doc for one item is fine; link it from the row and delete it when the item lands.
- Release scoping (which items go into which version) happens in the release notes, not here.
- The release gate (what must be green before pushing / publishing a
release) is kept as a local working note —
docs/dev/notes/RELEASE-BLOCKERS-v050.md(gitignored, like the other P-pass reports). Keep it current; don't fork a second copy of it into the tracked tree. - Known issues (the player-facing subset) live in the table below. The README links to it and does not duplicate it.
Goal and definition of done
Feature complete and faithful to the N64 original. Every mode and region the cartridge ships should work and behave 1:1 with the N64, checked against an accurate emulator (1964/GEPD) or real hardware. On top of that sits a modern-remaster layer (the bar set by Nightdive's Quake/Turok remasters, the XBLA remaster and GE+/Dab's mod). It must never change game logic by default, and it must always be possible to get back to the original look and feel (see the Original N64 preset, D440).
The port is feature complete when all of these hold:
- Every solo mission (all 20 plus the credits) is completable at every difficulty, on Windows and Linux.
- No crash on any level under normal play, on either platform.
- Audio is complete and faithful: music, positional SFX, menu and weapon sounds.
- Cutscenes play correctly (camera, actor positions, timing).
- AI locomotion and pacing match the N64.
- Input feels like GoldenEye on a controller, and like a modern FPS on mouse and keyboard.
- Rendering has no visible defect versus 1964/GEPD at default settings, apart from the port's deliberate modern defaults.
- Multiplayer (2–4 player split-screen) works. It is the largest item left (§1).
- PAL and JP ROMs work (§1, pending a decision).
Exit gate: a full two-platform campaign playthrough at more than one difficulty, plus a split-screen session, on a build with the §3 verification debt cleared.
Where things stand (2026-10-01): 1–7 hold for NTSC-U, with the small
accuracy gaps in §2. 8 is merged on release/v0.4.1 (3P/4P with real pads
owed). 9 is open (Stage B). Parity rule (2026-09-30): every released
platform carries the same gate: a full 21-level sweep plus a campaign pass.
Order of work (decided 2026-09-30)
Work continues on release/v0.4.1, shipped as v0.5.0 (named 2026-10-03,
cut staged 2026-10-05, maintainer) — the docs, golden set (both platforms,
63 frames each) and tooling are complete; the P11 squash + tag + push is owed
maintainer consent (push checklist: dev/notes/PUSH-TASKS-v041.md). There are
two stages:
Stage A: now → the pre-1.0 build
- Clear the §3 verification debt.
- Split-screen (§1): keep working and testing until it is good.
All unlockedrework (§5a).- D357 settings values (§5a), plus the restart button.
- Outside PRs (§5a), in the proposed order once the maintainer approves it.
- Pillarbox with the exact original aspect for the Original N64 preset (§5a).
- Platform parity: re-base the golden baselines and extend them to both platforms (§7), then run the gate on each platform.
- Investigate and triage every §2 fidelity gap to fix or accept. Do not leave any of them as "open, unexamined".
Stage B: pre-1.0 build → 1.0
- PAL/JP (§1). It goes last on purpose, so that region-specific regressions are easy to isolate and unwind.
- macOS/ARM: merge the
macos-arm64branch (§4), with the D441 census (store-to-u32 tagging) and a high-arena test. (2026-10-08 decision: an experimental arm64 macOS build ships in v0.6.0; the merge-to-main is still the post-1.0 step here. Scope is Apple Silicon — the x86_64 path is unverified and out of release scope.) - The exit gate on every shipped platform.
- Remove the temporary scaffolding (§7).
Next (decided 2026-10-03, after the Birdman64 comparison; local note BIRDMAN64-LESSONS.md):
- D441 census: done 2026-10-03 (§2).
- Fix the listed sites as mechanical, build-checked batches on a cheap worker; the lead reviews every diff (§7). Batches 1-5 done 2026-10-03. Next: the tier-1 sweep over every level with a seeded frame compare, then further batches from it.
- Scripted-playthrough harness: moved to post-1.0 (maintainer 2026-10-04; revisit with newer models) (§7).
Known issues
What a player will notice in the current release. This table is the single list: the README links here instead of keeping its own copy. When an issue is fixed and released, delete its row. When a new player-visible issue is confirmed, add a row here (and its tracking row in the sections below).
| Issue | Impact | Workaround | Tracking |
|---|---|---|---|
| PAL and JP ROMs aren't supported in release packages | NTSC-U only | Use an NTSC-U ROM. Both regions convert, build and boot from source (D258, D487, D488; see docs/building.md); packaging (per-region exe, CI matrix, converter region check) is still open |
D258, #85, §1 |
| Changing Aspect ratio in a level (mostly Fill window to Original or a forced ratio) can briefly glitch the gun / hand model, rarely | Cosmetic, one-off | Change the ratio from the front-end PC Options, or accept it | D509 (frame hold fixed the common case; the rare remainder is logged, not investigated) |
| No Intel macOS or ARM Linux builds (the macOS download is Apple Silicon only, experimental and not notarized) | Platform | — | #88, #95, #101, #154, §4 |
| Steam Deck at 90 fps: centre firefights in Bunker 1/2 drop several fps; Jungle feels slightly less smooth than other levels | Brief FPS drops | Frame cap 60 for those levels | D583, D585 (present thread, v0.7.0), D614 |
| Cradle's turret explosions may draw wrongly | Cosmetic | None yet | Deck per-level pass (2026-10-10), not investigated |
| Windows: the picture can look hazy for a moment after alt-tabbing back; fast repeated alt-tabbing recovers slowly | Cosmetic, temporary | It settles on its own | D578, alt-tab row in §4 (v0.7.0) |
Saves from v0.4.0 and earlier can hold fake unlocks from All unlocked |
Save data | Not repaired automatically. Since v0.5.0 the option never writes the save; keep a backup of data/ge007.eep from before you used it |
D442, D387 |
| The first frame of a level takes a little longer while its textures upload | Brief FPS-counter dip | None needed | D475, D480 |
| Far objects almost fully in fog are now hidden as on the N64, except in widescreen, where the wider view can still show a faint distant building edge (e.g. Surface's dish from the start area). 4:3 matches the N64 | Cosmetic | None; higher Draw/LOD distance shows more | D503, §5c |
Windows: an occasional one-off render-thread stall can trip the "no frame rendered for N ms" watchdog (rare; observed once, during heavy GE_-debug I/O) |
Brief one-off stall / recover | Normal play (no GE_ dump probes) is unaffected; a flake, not a deterministic hang |
D593 (root-cause owed: probe I/O cost vs a genuine render-thread hang) |
1. Feature completeness vs the N64 cartridge
| Item | Status | Refs | Notes |
|---|---|---|---|
| 2–4 player split-screen multiplayer | verify | #99, D416–D423, D496 | Merged 2026-10-01. D417 Rule-2 approved. Maintainer playtest 2026-10-03: 2P and 3P with real Xbox and PS5 pads, handicaps, teams and game modes all good (D496 fixed an uninitialised weapon-text buffer). Still owed: 4P with real pads, pads-only mode, MP audio, D422 centred aim live on P2+ (AimMode = 1), D428 sway on P2+. |
| PAL and JP ROM support | partial | D258, D487, #85 | 2026-10-02: both regions convert, build and boot (D258 byte-verified against real PAL and JP ROMs); both play Dam with no crash; NTSC-U unchanged. Build: BUILD_DIR=build-pal ./build-pc.sh pal-final / build-jpn ... jpn-final with data/ge007.<region>.z64. D487, D488 fixed (PAL frame height, TV type). Open: full runtime passes per region (levels, menus, audio, saves; PAL 50 Hz feel incl. the D427/D451/D486 gates; EU-only text); packaging (per-region exe names, CI matrix, converter region gate, #6). ROMs: ge-port-reference/1964_GEPD_Edition/ROMs. #85 needs reopening or a fresh tracker when this ships. |
| Drop-in ROM converter, remaining parts | decision | #6, dev/release-dropin-rom-plan.md |
NTSC-U drop-in shipped. Left: per-region output names and re-exec guard (with PAL/JP), native C emitters to replace the PyInstaller converter. |
| Cut content (TCRF weapons/items) | decision | dev/CUT-CONTENT-BACKLOG.md |
Not part of the shipped game. Tier 0 already works via the debug/cheat menus. Tier 1 (config-toggle grants) is small and port-only. Tier 2/3 (placing props, re-enabling unused MP maps) need game data changes and are out of scope for this repo. 2026-10-09 (maintainer): the Tier-2/3 items whose data is already in the ROM — the 8 cut MP maps and the extended MP roster (backlog §D/§F) — are in 1.0 scope as a mod-fork branch (the front.c table edits touch src/game, non-negotiable #2), shipped through the mod scaffolding (§5a). Prop placement stays out. |
2. Accuracy (behaviour differs from the N64)
| Item | Status | Refs | Notes |
|---|---|---|---|
| Third-person Bond offset residual | partial; intro puppet explained (2026-10-02) | D173, D292 | Mostly fixed. On the level-start puppet the variance is tick/PRNG-dependent idle timing (D13 class, faithful, no sign-off requested); one 1-frame first-tick Y transient is untraced. If the residual is seen elsewhere (cutscene body model), the maintainer should note where. |
| AI awareness follows two non-default render settings | fixed 2026-10-06 (D565: Fog distance floor 100; AI fog cull rescaled to the game's FOV) | D565, D466, D468, D540, D222 | AI review of v0.4.0..v0.5.0 (interpreter, movement/timing, visibility/combat): no regression at shipped settings (Draw 2.0x, Fog 1.0x, FOV 60, native widescreen). Two leaks of player render settings into AI awareness remain: (1) Video.FogDistance below 100 shrinks the far clip (bgfog.c fogLoadCurrentEnvironment, clip = FarFog x min(Fog, Draw)). AI on-screen checks require the render PROPFLAG_ONSCREEN (drawdistgameplay.c portPropGameplayOnScreen), so guards beyond the shortened clip stop counting as on screen; at Draw 1.0x portD466Active() is off and sight range (fogGetScaledFarFogIntensitySquared) shrinks too. Effect: guards notice Bond / on-screen triggers fire later than the N64. Fix (shipped): Video.FogDistance is floored at 100 (video.c registration, so 50/75 in an ini clamp to 100 on load; F10 slider uiMin 100); 100-800 only extends, which D466 already keeps off gameplay. (2) FOV other than 60 (Video.FovScale != 100, or native widescreen off at a wide aspect): the gameplay fog-cull propobj.c portSub7F054C58Gameplay uses getPlayer_c_lodscalez(), which grows with the rendered FOV (D222), so at a wider FOV far fogged positions drop out of the AI on-screen verdict sooner (narrower: later). Fix: divide out the port FOV factor (as portFovYScaleFactor), keeping the game's own zoom FOV changes. Minor at defaults: the D466 verdict reuses the extended pass's room screen bbox (posIsOnScreen); at Fog 1.0x the clip is the authored far, so the two passes match. D491 (room-list portal seeds) and D431 (light-fixture hit scoring) were checked: both restore N64 data reads and only move AI toward the N64. |
| Dam ending cutscene | done (2026-10-06) | D526, D552 | Railing/grate transparency faithful (D526); first-shot swivel restored (D552, maintainer-verified). |
| Title-screen attract demo runs too fast; F10 box rescales while it plays | backlogged (after v0.5.0, maintainer 2026-10-04) | D87 (ramrom file struct); timing: D13, D248, D427, D451, D486 | Reported 2026-10-04 (live pass): attract plays visibly too fast; not investigated. Lead: it is a ramrom demo replay whose recordings carry a per-frame tick count, which the port's 60 fps / 1-tick pacing may override. Rule out PC causes, then compare with 1964. Same pass: the F10 box briefly rescaled during the demo (not reproduced; candidate fix = overlay reads fast3d's native viewport, parked locally). |
| Sniper rifle: zoom level and speed vs 1964 | verify | #136, D484, D485, D494 | Crouch: D494 (2026-10-03) makes the PC crouch key crouch/stand freely with the sniper, as GEPD does (superseding D483's freeze); maintainer-verified. Zoom level (D484, 20 -> 7 degrees) and speed (D485, tick-scaled, Rule-2) fixed 2026-10-02. Owed: 1964 A/B of zoom level and speed; close #136 after it. |
| Geometry disappears when hugging a wall (dark close-range smear) | verify (fixed 2026-10-09; golden sweep owed) | #150, D579, D543 | Root cause (2026-10-09): a v0.5.0 regression from D543, the CPU near-plane clip. It cut at the near plane (z = -w), but GL runs with GL_DEPTH_CLAMP, so geometry between the eye and the near plane is meant to be drawn (as on the N64; 1964 shows the wall). Hugging a wall put it in that band and the clip deleted it. Confirmed by one GE_NEARCLIP=0 run (no see-through). Fix: the clip now cuts at the camera plane (w = 0.01), and clip-created vertices take fog at max(z/w, -1) so the D553 near-plane haze is unchanged. Maintainer-verified at the Dam gate in 16:9 with the floor haze intact. The earlier cull/ucode/guard-band investigation was a dead end (see D579 and dev-process §8 "Regression triage first"). Owed: one 21-level golden sweep. Diagnostics stripped (last one, the src/game/bg.c probe, removed 2026-10-10). The any_w_neg no-cull caused the Cradle catwalk flicker; mixed-w triangles now get the homogeneous facing test (D584), Dam gate wall hug re-checked clean. |
| Decal shadows flicker at high FPS (Dam, Cradle catwalks) | closed 2026-10-09 | D578 | Maintainer compared Dam against 1964 (GEPD): the shadow look there is essentially the same, so it is faithful, not a port bug. The flicker seen during the D578 switch testing is not considered an open issue. Reopen if the Cradle catwalk flicker shows up on the shipped default. |
| 120 fps + VSync on G-Sync/VRR: OLED brightness flicker (present cadence); Deck 90 smoothness | PC fixed 2026-10-09; Deck 90 good on most levels (per-level pass 2026-10-10, feat/d583-deck90, local); open items in the per-level row below |
D583, D578 | PC: continuous present grid snapped to tick/N, 8-slot present ring, draw-time-based ready, present-before-draw (120.0 presents/s, 99%+ gaps 7-9.5 ms, OLED by eye OK). Deck: false turn-detection redraws removed, exact frames drawn once, turn softening applied at frame start, room scissor = union of replayed and game box, projections paired by nearest (draw peak 8-10 -> 3-5 ms, 88-90 presents/s; maintainer by eye OK); no post-swap glFinish under gamescope (present 3.3 -> 0.3 ms); set-change limit 60%. Not yet a smooth 90 in crowded fights (maintainer: "not perfect for the release yet"): set-change holds and turn-softening steps remain; cut detection replaced the matrix set-change check (crowd fights "good now"). Next: re-tune softening (Dam tunnel by-eye), per-level Deck pass, Dam truck brief flicker (Deck, 2026-10-09), Aztec M16 viewmodel flicker, rare dead-body flicker before fade-out, level-start load stutter, gamescope flip-time stats. PC 120 re-checked 2026-10-09 (120.0/s, 1% exact). Owed: VSync-without-G-Sync check, per-level Deck pass + 90 fps performance validation across levels (only Dam exercised). 2026-10-10 Deck Dam run (ac50865d): 9.5-12 ms gaps 98-99.7% per 10 s window, 0-5 dropped, draw peak 2.1-6.3 ms, late softened (redrawn) 8-56 per 10 s, maintainer by eye: good, no tunnel holes. Turn-softening re-tune closed as not needed (the redraw count no longer costs presents). 2026-10-10: per-level Deck pass done (next row); the older "Next" list above is superseded by it, except the still-unexplained Dam truck / Aztec M16 / dead-body flickers (captures owed), level-start stutter, gamescope flip-time stats and the VSync-without-G-Sync PC check. |
Deck per-level pass findings (2026-10-10, maintainer, ac50865d) |
open | D583, D578 | Overall very strong. (1) Bunker 1/2 centre firefights drop 5-10 fps: the log shows a ~70-frame run of 2-pass frames drawing 11.2-12.5 ms (~5.6 ms per pass, over the 11.1 ms 90 Hz budget); game side is idle (work ~0.14 ms), so this is draw cost, a real-optimization job (profile the pass), not pacing. 2026-10-10 measured (SLOW line counters): ~550-800 batches per pass at ~6 us each (~4-5 ms per pass); texture lookups ~1.2 per batch, few misses; a softened restart made fight frames 3 passes. Refuted: same-texture rebinds (reverted). Landed: late-soften budget gate (no restart when n+1 passes exceed 3/4 tick; nobudget = old): 3-pass frames mostly gone, but drops remain (2-pass frames to ~13 ms; maintainer: still up to ~10 fps drops). 2026-10-10 late (D583 addendum "present scheduling"): NOT draw cost: not CPU-bound (perf), not the GPU clock (1600 MHz manual: same), not the VBO upload (ring: within noise). 72% of the long present gaps are a due present stuck behind the single worker's next draw. 2026-10-10 review: present thread (D585) PARKED for v0.7.0 on local wip/d585-present-thread (opt-in, offscreen frames black): a second shared GL context + thread on every platform, macOS included, for one Deck scenario was too much risk for a point release. v0.6.0 ships with the Bunker fight drops as a known Deck issue. 2026-10-10 (D614): texture-cache thrash measured in the fight (CI8 keys hashed leftover palette entries); fixing it cut re-imports 60-70% but did not change pacing: reverted, not the cause. (2) Jungle/Egyptian read 90 fps but do not feel fully smooth: motion histogram shows 3-10 hold+jump pairs per 10 s (~0.5-1 visible hitch/s) even with 0 dropped; next step is to log which decision (room-change exact, late exact, pre-soften) precedes each hold. 2026-10-10 hold-cause log (6d7aa851), Jungle: every hold is an exact fallback (1-7 per 10 s), almost all REACH (a room the previous frame drew and this one dropped); noreach removed them with no visible holes in Jungle but did NOT change the feel (maintainer: "not significantly"; Egyptian and other levels feel better). So holds are not the Jungle issue and the pacing stats look like the good levels. Untested lead: content refreshed only at the game tick inside a 90 Hz blended view (the sky is always this frame's; objects not paired), most visible outdoors. Needs a focused look, not more switch rounds. (3) Clip-through at long range (FIXED 2026-10-10): Frigate terminal shadow through a wall, Statue Valentin through his crate; above 60 fps only. Cause: the D578 in-between depth-clip widening (gfx_interp_conservative_clip, heading-dependent depth remap). Gone on the Deck with noclip; now default OFF (interp_clip_off; GE_INTERPCLIP_ON / clipon opts back in). Owed: Dam distant-ridgeline check without it (the reason it was added; maintainer deferred it 2026-10-10). (4) Cradle catwalk shadow flicker (FIXED 2026-10-10, D584): a regression from D579 at every frame rate (bisected on the Deck); mixed-w triangles get the homogeneous facing test again. (5) Cradle turret explosions may draw wrongly (maintainer, 2026-10-10): noted only, not investigated. |
| Native widescreen: stale watch pixels at the sides of 4:3 menus (mission folder, file-select background, main menu after exiting from the watch) | fixed (2026-10-10, ac50865d; maintainer Deck check OK) | D579, D334 | Not interpolation (present with allexact). D579 (#150) stopped the per-frame canvas color clear to match N64 persistent VRAM and clears only the letterbox bars; with Native widescreen the canvas is the full 16:10 window, but 2D menus draw only their 4:3 core, so the canvas sides are never drawn or cleared and keep the watch. Fix direction: keep the no-clear where the game draws, clear the widescreen extension outside the 4:3 core (or on 2D/menu frames). Regression from D579 (this week), not in v0.5.0 releases. Fix 2026-10-10 (gfx_frame_body, D579 follow-up): outside a running stage (current_menu != RUN_STAGE) with native widescreen wider than 4:3, the canvas strips outside the centred 4:3 core are cleared to black before the DL, like the letterbox bars; in-stage frames keep the no-clear. |
| Dam: grate decals vanish behind a sliding edge, wall lighting shifts with view; guard tower window/doorway view of the outside glitches | closed 2026-10-09: faithful | D583 | Present with every present exact (allexact) and in v0.5.0; maintainer checked 1964 (GEPD): the exact same behaviour. Original-game portal/culling artefacts, not port bugs. Candidate for the opt-in fixes row below. |
| Opt-in fixes for original-game rendering bugs (QoL) | idea, post-1.0 (maintainer 2026-10-09) | D583 | Maintainer: a nice QoL feature would be optionally fixing artefacts the original game has, e.g. the Dam wall grates cut by a sliding portal edge and the guard-tower window/doorway outside view (D583 row above), and overlapping 2D transparent textures on Cradle sorting wrongly (also in the original). Must stay off by default (fidelity is the default) and live in port/ or an explicit option; game-logic changes would need Rule-2 sign-off. |
| Exclusive fullscreen picks the wrong resolution with NVIDIA "OpenGL present method = Prefer native" | open (v0.7.0, maintainer 2026-10-10) | D583 | Seen 2026-10-09 while bisecting D583; borderless is fine. Probably exclusive mode switches to the ini Width/Height instead of keeping the desktop mode. Not investigated. |
| Deck golden captures are 1280x800 when interpolation is on | open (v0.7.0, maintainer 2026-10-10) | D578, D283 | With Auto FpsCap on the Deck's 90 Hz screen, GE_PCDUMP writes 1280x800 frames against the 640x480 Deck goldens, so every frame fails to compare (and the sweep prints PASS with "stems don't match", which is not a pass). 2026-10-11: the false PASS is fixed: framediff.py exits 3 on a size mismatch and verify.sh reports it as REGRESSION ("not compared"); the capture-size fix itself is still owed. verify.sh now pins Video.DeckPresetApplied = 1 (D283 preset). Fix: dump at the window size, or re-capture the Deck goldens once. |
| Crash on save slots 1/3/4, plus a host BSOD (fltmgr.sys) | decided | #94 | Needs a repro. Two maintainer retest requests (v0.3.0, v0.4.0) got no reply. Likely D299/D301 (save-slot crash, fixed) and D344 (BSOD on exit, fixed). Decided 2026-10-01: close as stale when the release ships, pointing at D299/D301/D344; no GitHub activity before then. |
| Authored mip chains not sampled for explicit-LOD textures | post-1.0 | D323 | Distant textures use driver mips instead of Rare's hand-authored chain (heaviest on Statue/Aztec). Parked as a fidelity enhancement. Decided 2026-10-01: after 1.0, together with the LOD-fraction approximation as one "real RDP LOD" project. |
| Approximations in the software RSP | post-1.0 | gfx_pc.cpp G_CCMUX_LOD_FRACTION; D323 |
The LOD-fraction CC input is an eyeballed approximation, bundled with D323 as one "real RDP LOD" project after 1.0 (2026-09-30 triage). WrapFix settled 2026-10-02: the maintainer checked the Depot building ceilings against 1964 with the default Video.WrapFix = 0 and they look right, so the default stays off (the opt-in knob remains; RC3/D167). |
| Latent 64-bit ABI hazards | partial | D441, #107, #108; AUDIT-M6 struct player/struct hand raw offsets (porting-notes §A1) |
State (2026-10-03, D441): complete census (local scratch/d441/; many hits are intentional (s32)&ANIM_DATA_* offsets, D34); 17 files widened to uintptr_t under #ifdef PORT; 35 sign-extension sites fixed; CI ratchet tools_pc/abi_ratchet.py (baseline 389); arena windows centralised (port/include/portaddr.h); tier-1 high-arena build (GE_HIGHARENA_BASE=0x90000000) runs the menu and -level_09 pixel-identical to default. D478: nothing live on the current layout; the rest would bite only on macOS/ARM/ASLR. Sweep (2026-10-05): tier-1 all-level sweep done, 21/21 PASS, no fix batches, ratchet unchanged (389), recipe in the D441 entry. Owed: tier 2 (above 4 GiB; u32 slots widened); store-to-u32 vs arithmetic-only tag per site (portHostToN64 under macOS port_addr); mema.c widening (D453); initanitable.c heap slots; GE_DETERM wall-clock timers (D117 follow-up, blocks using determinism mode for frame gates). #108: widening the sndPlaySfx bound disables the guard everywhere; prefer a range check — done in v0.6.0 as D573 (address-window check). |
| Port-memory vertex/pool bounds hardening | post-1.0 (decided; not a v0.5.0 blocker) | D545, D549 | D545 (rockets through floor, fixed) left one residual: ~1 dropped rocket in ~60 spawns (Archives, akimbo), consistent with the room-pool hypothesis (bgBuildRoomVtxBounds allocation failing leaves no bounds) but unproven; D549 (same stack-overflow class in grenade/knife/object throws) is fixed. Both shipped. Proposed hardening: a port-memory bounds table validating vtx/pool pointers against the known arena windows. |
3. Verification debt (fixed; a live check is owed)
A single campaign pass with these on the checklist would clear most of them.
| Item | Refs | Check |
|---|---|---|
| Presets: Original N64 / Port defaults | D440 | Press both rows in F10 and in the front-end PC Options with a mouse and a pad; draw distance applies from the next level load. GE_OPTIONTREEPROBE already fails on the base commit (separate look). |
| Probe strip (2026-09-30) | D245, D302, D318 | Frigate or Dam water/sky A/B against the previous build (the s16 sky path was removed); one Facility playthrough to confirm the D318 watchdog stays silent. |
| Infra fixes | D179, D515, build-pc.sh, crash.c, CI | 2026-09-30 re-exec no-op (PATHEXT) fixed; 2026-10-04 empty-arch-tag bug (D515) fixed headless (details in AGENTS.md) — confirm on your next fresh-dir build. Owed: ./build-pc.sh from a genuine MSYS2 login shell; the next CI run (pinned actions, workflow input check). GE_CRASHTEST=6 shows resolved frames. The romdata VirtualAlloc failure path now fails boot instead of falling back to the heap copy: confirm you want that. |
| Light-fixture hit-type reads (impact sound + sparks) | D434, #119 | Shoot fixtures on Bunker and Caverns. |
| Dam/Caverns water animation | D465, #127 | Fixed 2026-10-01 (16-byte Gfx raw-index write). Maintainer: still "slightly faster" than 1964 on Dam; measured rate equals N64 within 0.1%. Optional objective check: time ten shimmer cycles on both (expect ~26 s). |
| End credits after Cradle | #129 | Did not reproduce on release/v0.4.1 2026-10-01 (maintainer finished Cradle on Agent, credits played, clean exit). Close #129 as not reproducing when the release ships. |
v0.4.1 batch (unreleased; fixes live on release/v0.4.1) |
D424–D432; #114 fire rate, #115 tank-crush audio loop, #116 tank movement, #117 sway, #118 GL recoil, #119 light fixtures | All user-verified against GEPD/1964 on 2026-09-29. Close the issues when it ships. |
| FOV-scale edge culling | D222 | Max FOV, pan across NPCs at the screen edge. Also audit the FOV/aspect terms in camIsPosInScreen and c_lodscalez for the Surface dish (D503 residual). Maintainer decision owed: expected widescreen behaviour vs fix. |
| Draw/LOD 800% | D503 | Draw/LOD distance ceiling raised 400% → 800% (2026-10-04). Owed: at 600-800, check far-field z-fighting on Dam (tunnel), Surface and Jungle; on Aztec or Streets, grep the log for the D500 vtx-pool budget line. If z-fighting shows, lower the ceiling to 600 rather than touching depth precision. |
| Water pulse, Surface 2 | D229 | Frigate is verified. Only the Surface 2 by-eye check is owed. |
| Linux save/config path when launched outside the game dir | D256 | Save-flow check on Linux. |
| Settings/F10 batch | D356, D358, D361, D363, D374, D406 | Live accept of each item in the F10 overlay. (D377–D379 residuals were waived.) |
| Controller feel | CONTROLLER-INPUT-PLAN Wave A, D204 | Per-stick deadzone/smoothing feel on a pad and on Deck; D204 tempo by ear; Input.RumbleScale=0 silences rumble. |
| Widescreen HUD at 21:9 | D334/D335 | One ultrawide HUD playthrough. |
| Older "owed" notes | D371, D372 | Bookkeeping done 2026-10-01: D150, D177, D264 ticked off against the 2026-09-28 campaign sign-off; D369 accepted in use. Still owed: D371 (GEPD key-layout preset + reload/crouch bindings: select the preset in F10 and play a level). (D372 low-end preset: no further effort; low-end work is real optimizations, see §4.) |
4. Platform
| Item | Status | Refs | Notes |
|---|---|---|---|
| macOS (Apple Silicon) / ARM64 Linux | open (target 0.9.0/1.0, maintainer 2026-10-02; scope 2026-10-08: Apple Silicon only, experimental in v0.6.0) | PRs #88, #95; #101 | Outside drafts, parked until after 1.0. Address model decided (2026-09-30): port_addr (#95), a portN64ToHost/PORT_N64PTR chokepoint with a PORT_ADDR_STRICT validator. The integration branch is macos-arm64 (renamed 2026-10-08 from macos; local + Forgejo mirror) with #88 (merged), #132 (merged) and #95 (merged 2026-10-10 — record merge 903095c9 in the v0.6.0 line + base merge f87f4bcd; the stale GitHub origin/macos mirror was deleted 2026-10-10, its lineage stays reachable via the record merge); nothing merges to main before the post-1.0 pass. Scope decision (maintainer 2026-10-08): ship Apple Silicon only — the x86_64 macOS path (#88) stays in-tree (identity at PORT_ADDR_BASE==0) but was never verified on Intel hardware and is out of release scope; arm64 macOS is planned as experimental in v0.6.0 (the first release carrying a macOS build; owed before the release: D602 diagnosis, D600/D601 live confirmations, and a release-notes experimental marker on the macos-arm64 artifact). #131 (self-hosted sweep scaffold) closed 2026-10-10 — its content shipped in the v0.6.0 CI; the fork-friendly rework is parked locally (park/ci-selfhosted-sweep-131, 2fb8e52e) for the v0.7.0 self-hosted runner item. Status 2026-10-08: D590 fixed the deterministic Windows load_bg_file SIGSEGV (the D588 bug class on the full-width bg_addr_t — plain casts, 5/5 Dam runs clean; the D589 A/B's Win side is unblocked); D589's rev32 is ROOT-CAUSED as D591: the decode-time pool is 134/134 byte-identical Mac/Win (the writer side is clean — the “pool holds the rev32” line is retired), and the reversal happens at the import — gfx_tex_source_is_c_array (port/fast3d/gfx_pc.cpp) mixes host-space and N64-raw-space in its range test, so on arm64 macOS (PORT_ADDR_BASE=16 TiB) every DRAM/cart texture source mis-classifies as a “C-compiled array” and gfx_tex_normalize_source bswaps it (a clean rev32 of the whole wide-pixel pool — the D219/M-114 pink-HUD symptom class). Fix in 9c59cbe7 (compare the host pointer directly; port-layer only, no-op at PORT_ADDR_BASE==0); Windows verified byte-identical (400/400 import r*.bin + PPM unchanged), Mac A/B now verified 2026-10-08 (clean arm64 build at 25f92e09: GE_TEXN carray=0 on all probe lines, Mac raw8 matches the Win baseline — the rev32 is gone). D589 is now RESOLVED: the "second cause" (D592) was CLOSED as a non-issue 2026-10-08. The "rock striping" that D592 tracked turned out to be a false positive of a crude vertical-high-frequency (VHF) metric flagging natural rock grain, not a GL-layer artifact: a GE_TEXSTATE GL-state probe showed the effective sampler state and the NPOT mip level counts are byte-identical Win/Mac (the Apple M3/Metal backend builds the full NPOT mip chain; the aniso extension is present on both; the NPOT rock texture gets min=trilinear, mag=linear, aniso=4 on both sides), a 0-pink scan confirmed D591 held, and the maintainer's live Mac look showed the Dam rendering clean (no visible striping, ammo counter not pink, F10 menu fine). The NPOT glGenerateMipmap guard + companion single-level sampler fix (9bed5904 / 82dbea9c) were reverted as dead weight (b80dcd08, which also strips the GE_TEXSTATE probe). The genuine cross-platform symptom (the pink HUD) was D591 (fixed, 9c59cbe7). D594 (FIXED): macOS partial input — GE_KEYLOG disproved the cross-thread-poll suspect (WASD + LMB reach both the main-thread pump and the scheduler-thread poll); the real gap was the actHeld mouse gate on current_menu == RUN_STAGE (a forced -level_NN start leaves current_menu == INVALID (-1), so the mouse was never read) plus the macOS reconcileGrab windowFocused gate. Fixed by matching PD's input model (in-stage = RUN_STAGE or INVALID; macOS grab = PD's MLOCK_ON, no focus gate) — LMB fire now works on the Mac (trackpad: LMB fire, two-finger = RMB/aim, Shift = ADS). D595 (FIXED): the arm64-only SIGSEGV that firing then exposed — initResolveAnimTable truncated the live ptr_animation_table host pointer to (s32), dropping the 16 TiB PORT_ADDR_BASE → every AI hit/stagger struck_anim resolved to bogus low memory → crash in modelSetAnimFrame on the first AI hit-reaction. Fixed by reading the base at full pointer width (§A1; identity on x86_64). Both are the last input-blockers to a playable arm64 macOS build. (maintainer visual-sanity package: scratch/d589-dam/ab3-mac/{d591_sbs_win_mac.png,d591_diffmap.png,D591-AB-SUMMARY.txt}. tools_pc/abi_ratchet.py baseline refreshed for the branch. Integration into the v0.6.0 line done (2026-10-10): #95's crouched_rifle hunk and its D420 label were dropped at integration (our #120/D445 is correct; D420 superseded wholesale); #131's fork-friendly selfhosted.yml was NOT taken into v0.6.0 (parked for the v0.7.0 self-hosted runner item). Relabel prep done (2026-10-08): no other relabelling is owed — #95's 9 genuine D-label citations (D290/D293/D294/D295/D297/D299/D406/D407/D408) mean the same things at #95's merge-base as in the current log (no drift); the D418 hits in #95 are hex addresses in getfpccsr.s, not citations. §2 ABI-hazard sweep done 2026-10-08: the macOS (Apple Silicon) full-campaign sweep — 21/21 levels end-to-end, 0 crash logs, 0 flakes (scratch/d441/macsweep.sh; record in the D441 entry) — exercised the tier-2 above-4-GiB hazards live (the D595 class) without a single firing; the structural widenings (u32 slots, mema.c D453, initanitable.c heap slots, #108 range check) stay owed. Maintainer live pass done 2026-10-08 (Launch E, MENU-LIVE-CHECKLIST.md): mouse / keyboard / pad in-level + F10 / menus all behave as on Win/Linux, no ge007.crash.log for the session; the GE_KEYLOG log shows real LMB events on both the main-thread and scheduler-poll sides — D594/D595 are live-verified (the E1 LMB-fire is the struck-animation ground truth). Windows identity gate re-enabled 2026-10-08 (D596): the stale win/ goldens (pre-D565/D569) were regenerated from e0a2d4b9 — verify.sh sweep 21/21 PASS on the branch tip; the linux//deck/ sets still need their own re-capture round on those boxes before any new cross-platform number is read. D598 (RESOLVED by D600, live playtest owed): the M3 chop on Cradle-class levels was fixed 2026-10-08 by D600 (display-locked retrace tick) — the scheduler's tick now paces to the display's refresh instead of assuming 60 Hz vsync (the CPU side was 6–17 ms per 300 frames, so the chop was display/swap pacing, not software-RSP cost); a live Cradle-class playtest confirmation is still owed. D599–D604 (all 2026-10-08; on macos-arm64, pushed to Forgejo 2026-10-08): D599 FIXED (arm64 SIGBUS on pad connect — padTabPub pointer-sized); D601 FIXED (interrupt-guarded sound-list mutation — cyclic list hung Archives stage load, live confirmation owed); D602 OPEN (end-credits SIGBUS — langGet rejects impossible slot offsets + one-shot bank diagnostic, needs a natural-flow re-trigger); D603 FIXED (2P modelSetAnimFrame SIGSEGV — playerTick re-bases the s32-held animation address; the live 2P session exercised it) and D604 FIXED + LIVE-CONFIRMED (2P respawn SIGSEGV — mp_respawn_handler stops truncating the pointer-typed start_stan; maintainer confirmed Enter/respawn in 2P with keyboard/mouse + 1 controller). D597 (FIXED 2026-10-08): GE_INPUTSCRIPT MLB/MRB sustained mouse-button tokens (slot 0) — headless scripted fire; the D595-class regression is now automatable (Mac sweep-fire no-crash run + no-env no-op run verified) and is the standing #131 runtime smoke check. |
| macOS first-launch black window (v0.7.0) | open | D581-era sweeps; logs in docs/dev/notes/mac-first-launch-hang-2026-10-13/ (local) |
2026-10-13, v0.6.0 release download on the M3: the cold first launch generated assets, reached the title stage (90) and then rendered no frame (kernel heartbeat: no frame rendered, frames=0, all game threads blocked); the next launch was clean. 1 hang in 16 launches that day (1 in 10 first launches), 0 in 7 after a reboot; neither a new binary alone nor asset generation alone reproduced it. 3 earlier sightings on 10-12. Lead: one timer mq in the heartbeat dump shows valid=83746432/0. Release notes carry a one-line "close and start again" tip. |
| Pixel gate vs the Auto frame-cap default (v0.7.0) | open | D578, tools_pc/verify.sh |
The goldens (2026-10-02) predate frame blending; with the defaults-only ini the sweep now runs Auto, which blends at 120 on a 120 Hz panel, and 2-9 levels flag at random per run (worst 9.3%). The same levels pass with VERIFY_INI_EXTRA set to a [Video] block with FpsCap = 60. Pin the sweep to 60 or re-capture goldens on the blended path; until then run the release sweep with that extra ini. |
| Platform parity gate (Linux co-equal with Windows) | open (v0.7.0, maintainer 2026-10-10) | — | Decided 2026-09-30: yes. Every released platform carries the same gate: a 21-level sweep plus a campaign pass. Needs the golden baselines on both platforms first (§7). The last known Linux crash (D190) was closed as not-a-bug. |
| Low-end GPUs (~30 fps on Celeron/HD 400) | fixed, verify on N3060 class | D339, D481, D482, #92 | D481 (2026-10-02): fast3d ran inline on the scheduler thread, delaying retrace delivery so the tick gate skipped frames; the render worker took a Lenovo X220 (HD 3000) from 44-46 to 60.0 fps. D482: Atom/Celeron-class GPUs (HD 400-605, UHD 600/605, software renderers) get DrawDistance/LodDistance 100 and MSAA 1 once, where still at defaults. D473: uncached per-batch getenv fixed. Direction: real optimizations, not a preset. Next only if N3060-class hardware still drops: one GE_PERFSTAT=1 run (gpu= vs run=), then a lighter renderer-keyed default (GPU) or fast3d per-batch cuts (CPU; local PERF-HOTSPOTS.md). |
| Statue/Cradle hitching (maintainer, 2026-09-30) | parked (not player-visible, 2026-10-02) | GE_PERFSTAT spike counters |
Diagnosed (D475, D477, D480): no sustained load — the ~33 ms frames are the frame limiter skipping a retrace after a late gfx task (boss.c, D13-class timing); CPU bursts were CI-palette re-imports (ruled out, D477) and in-play shader compiles (fixed, D480). Parked 2026-10-02: a play session with the timeline probe felt no hitching. Reopen only if a visible hitch is reported (lever: pre-warm at level load). |
| Steam Deck preset skipped when first launched from Desktop Mode | verify | D283 | Fixed on release/v0.4.1: the Deck is detected by DMI hardware id (Valve Jupiter/Galileo; STEAMOS as a second signal) and the preset applies once per ini, only while Fullscreen/Maximized are untouched. Only a Windows build and a Linux -fsyntax-only check ran. Owed: one run on a real Deck (Desktop-Mode-created ini, then Game Mode; expect fullscreen 1280x800 and the log line video: Steam Deck (DMI Valve ...)). The Known-issues row goes when this ships. |
| Windows 7 | open | #98 | Re-checked 2026-10-02: likely feasible around 1.0. The exe imports no Windows 8+ functions and the bundled SDL2 2.32.10 still supports Windows 7. The real blocker is the first-run converter ge007-convert.exe (PyInstaller, Python 3.9+): the native C converter (#6 Part B) removes it, or a separate Python 3.8 build. Work: one Windows 7 VM test, then manual per-release checks (CI cannot test it). Supersedes the earlier 'won't-fix' call. |
| Alt-tab haze + fast alt-tab recovery | open (v0.7.0, maintainer 2026-10-10) | D578 | Maintainer 2026-10-10 (v0.6.0 build, Windows 120 Hz): alt-tabbing leaves a hazy picture; fast repeated alt-tab is wonky and recovers only after a while or more alt-tabbing. Not new in v0.6.0 (was an owed check). Known issue in the v0.6.0 notes. QoL fix: clean focus-loss/regain path (context/FBO state, present queue reset). |
| Deck: max Field of view feels choppier while turning | fixed in v0.6.0 2026-10-13 (D953 LOD/fade/visibility + D954/D955); maintainer Deck-confirmed (Surface windows) | D953 | At FOV 90 (menu max) turning feels worse than at 60, at 60 and 90 fps. Frame pacing measured identical at both FOVs. Lead: FovScale pulls every model LOD switch 1.73x closer, and depth-based LOD flips off-axis objects while turning (Dam turn probe: 0 flips at 60 deg, 400 at 90 deg, 120 with the fix candidate on fix/d953-fov-lod). Pass 2 (10-13 evening): prop fog fade and fog-range visibility fixed the same way; on Surface LOD/fade/visibility do not change while turning, so they are not the feel. Maintainer: objects "update not at the right speed" (object motion is not interpolated at 90, plan D955). Next: D955 Stage 0, and one Deck GE_D193=1 run per FOV for 2-tick game steps. |
| Doors and guards flicker at 90 fps (not at 60) | fixed 2026-10-13 (D954); maintainer Deck-confirmed | D954 | In-between presents drew props (chrs, doors, effects) at the exact camera while rooms used the blended one, so props jumped against the world whenever the camera moved (Surface turn on Windows: 0.4-0.5 deg mean, up to 1.8 deg). Present in v0.6.0 at 90 fps. Fix in gfx_pc.cpp: props' plain perspective gets the room camera blend (P * R^-1 * Rb) up to the first-person gun. Owed: Deck at 90 fps, Surface doors/guards, and the gun must not move while turning. |
| Objects move at 60 Hz steps at 90 fps (props, doors, guards) | fixed 2026-10-13 (D955 + sky pass); maintainer Deck-confirmed (guards, doors); first-person weapon not blended yet | D955 | In-between presents drew objects at their tick pose (only the camera was blended). Now blended per joint, keyed by (Model*, joint) from a game-thread snapshot, rebased onto the new camera; exact on room-origin changes, failed gates, split-screen. Dam on Windows: 99.6% of object joint loads blended. Owed: Deck at 90: guards walking, gun in hand, hats, deaths, shadows, doors, Facility stall doors/sinks (the old ghost site), room boundaries. Vehicles later. |
| Windows display scaling: the game is not DPI-aware on scaled displays | fixed 2026-10-10 (D626); maintainer by-eye on a scaled display owed | D626 | Seen 2026-10-07 during the v0.5.0 4K captures: on a 3840x2160 display at 125% Windows gives the game a 3072x1728 surface and stretches it, so the picture is softer than native. gfx_sdl2.cpp sets SDL_HINT_WINDOWS_DPI_AWARENESS only when allow_hidpi is off; setting it (permonitorv2) on the HiDPI path too renders at native resolution. Workaround today: environment variable SDL_WINDOWS_DPI_AWARENESS=permonitorv2. |
5. Modern-remaster layer (port features beyond the N64)
The bar: feature parity with a Nightdive-style remaster and with GE+/Dab's mod where it's practical. Shipped so far: native widescreen and ultrawide, FOV, MSAA/anisotropic/texture-filter options (including N64 3-point), draw and LOD distance, VSync and a frame cap, show-FPS, keyboard/mouse rebinding with a GEPD-style layout, pad deadzone, sensitivity, smoothing, southpaw and triggers, rumble, crosshair and HUD customisation, HUD scale, music/FX volume, no-hit-flash, SkipIntro, All unlocked (see D387, D442), and the F10 overlay.
The modern defaults (native widescreen, overscan crop, 250% draw/LOD distance, bilinear filtering) are deliberate. They are not a fidelity defect.
Background research lives in the maintainer's local notes (gitignored):
GEPORT-REFERENCE-DEEPDIVE.md, MODERN-PORT-FEATURES-BACKLOG.md,
MODERN-OPTIONS-PLAN.md and PD-LEGACY-SURVEY.md under docs/dev/notes/.
5a. Before 1.0
Renumbered 2026-10-10 (maintainer): the planned v0.5.1 (frame rate above 60 + macOS) ships as v0.6.0, and the old v0.6.0 scope is now v0.7.0; labels below are updated, findings and commits keep the old names. Order (maintainer, 2026-10-08; mod-start added 2026-10-09): v0.6.0 = frame rate above 60 (D578) + macOS (#95, local); then custom textures and mod support (the texture work likely shares the surface/geometry findings from D578). v0.7.0 ships the items marked v0.7.0 below (#145 control styles, native N64 pad support, the v0.5.0 issue triage, the README line, mod support start — maintainer 2026-10-09: mods come sooner, in v0.7.0, not after 1.0). They are the minimum for 1.0. Everything marked v0.7.0 is open; none of it is claimed fixed or verified.
| Item | Status | Refs | Notes |
|---|---|---|---|
| Log file (next release) | done (v0.6.0) | maintainer 2026-10-06; D576 | Done 2026-10-07 (D576): ge007.log next to the ini, previous run kept as ge007.prev.log, 8 MiB cap. Was: write ge007.log next to the ini (console output is lost on a normal launch). Crosshair pointer done in v0.5.0 (D555). |
| F10 / PC Options menu: PD-style dialog refactor + watch-consolidation review | verify | D504-D512, MENU-PD-ALIGNMENT-PLAN.md (maintainer's local notes) |
Built 2026-10-04 (D504); follow-ups merged: D505/D506/D507 (wording, real-unit sliders, descriptions); D508 forced aspect ratios (16:9 / 21:9); D509 2-frame hold after an aspect change (rare gun glitch = known issue); D510 overlay + FPS counter same size front end vs level; D512 Game.HudScale scales the F10 overlay. Owed (live pass, docs/dev/notes/MENU-LIVE-CHECKLIST.md, launches A/B/C): look-and-feel vs PD; mouse, keyboard and pad in a level and on the front end; HudScale 75/100/150; 21:9; display-mode round trip across a restart; split-screen 2P with the overlay open. Gaps: background blur (post-1.0, §5c); per-seat control scheme is #139 / D513. Watch consolidation: not cheaply feasible (parked as T5). |
Defaults/presets consolidation: one Display mode switch |
verify | D504, D440, MENU-PD-ALIGNMENT-PLAN.md §5 (local notes) |
Landed 2026-10-04 (D504): the derived __DisplayMode row shows Modern / Original N64 / Custom (no ini key); F10 dropdown + left/right stepping, front end steps too; one reset row per dialog covering exactly its keys; editing a non-bundled key does not flip Display mode. Decided 2026-10-03: tri-state, flipping to Custom when the user edits a bundled key. Owed (live): display-mode round trip across a restart; read of the regrouped pages and wording (MENU-LIVE-CHECKLIST.md A1/A2/A4). |
| Control style Original shows the game's own N64 styles | verify | #139 follow-up, D516, D517 | Landed 2026-10-04 (D516, merged @ 91595597): "Controller style" row (Original only; the game's own 1.1-2.4 per seat, saved to the Bond file; front end reads "(in a mission)"); D498 presets hidden in Original. D517: hold-repeat on any Bond row dropped fps (EEPROM rewrite per detent); now staged like sliders. Live passes 2026-10-04 (maintainer): single player + split-screen 2P with different styles per seat. Owed: the 2.x second-pad pass (real second controller). |
| Pad layout preset per player (setting P2's no longer moves P1) | verify | D518, D498 follow-up | Landed 2026-10-04 (D518): Input.PadPreset kept as seat 1's key + new Input.PadPreset2/3/4; the F10/front-end preset row follows the Select-player seat. Headless GE_PADMAPTEST PASS; live passes 2026-10-04 (P2 change leaves P1 alone; split-screen: each seat ran its own preset). |
| Control scheme selectable: Ext / Original control style | verify | #139, D513, D498, D166 | Landed 2026-10-04 (D513, merged into release/v0.4.1). Input.ControlScheme (row "Control style", Ext default / Original) on the Controller page, both UIs. Original leaves the game's own style alone; D498 presets set layout and stick swap only in Original; 2.x runs faithfully; global in v1, per seat with the Select Player work. Owed: pad pass in both modes, watch-selected 1.1-1.4, split-screen 2P with different styles, 2.x with a second pad. |
| Outside PRs #107–#109, #122–#124 | decided | #122 hot-plugged pads never reopen, #123 persistent crosshair (gunfire.c), #124 compact health/armour bars (bondview2.c); #107/#108/#109 (italoarruda) |
Decided 2026-10-01: #120/#121/#122 merged locally (#122 = D450); close on push. #123: merged 2026-10-06 into v0.5.0 (D436; presets set it off, tip, Rule-2 signed off; by-eye hipfire / sniper zoom / 2P owed). #124: deferred (ignores HudScale, overlaps status text, ultrawide anchoring, split-screen untested) — tentatively on the v0.7.0 triage list (commented to the author 2026-10-10; blocker is ours: scope + golden re-baseline, so a rebase onto release/v0.6.0 would make integration cheaper). #133: duplicates D472; close as superseded on push. #109 (pad rebinding): decline as-is; supersede with our pad presets (§5a), crediting the author (Co-authored-by). #107: folded into D441; close on push. #108: range check implemented in v0.6.0 as D573 (commented + credited 2026-10-10; superseded, author to close). |
| Gamepad presets: duplicate-binding warning, Xbox stick behaviours | open (after v0.5.0; documented in the README) | D469, D498, D518, D394 | D469 (pad action table, Jinx 1.1 default, Custom per-seat bindings), D498 (Xbox 1.2 Christmas / 1.3 Frost / 1.4 Elektra) and the per-seat preset (D518) are done and maintainer-verified with pads. Not done (maintainer 2026-10-04: skip in game for v0.5.0, document only): a warning when two actions share a button; the Xbox "left stick aims the crosshair" and "D-pad copies the left stick" behaviours (D394). |
| Pad button names on a Nintendo pad | verify | D471; local note PAD-MENU-AUDIT.md |
Audit done 2026-10-01 (no controller-only trap; D472 fixed G1-G3). D471 family button names + player LEDs: PS5 DualSense verified 2026-10-03. Owed: a Nintendo (Switch) pad check; the maintainer has no such pad, so this waits for one or for a user report. |
Mute and auto-pause on focus loss; PNG screenshots to screenshots/ |
parked | D231, PR #56 (closed unmerged), docs/dev/notes/parked/0001-QoL-*.patch (local) |
Deprioritised by the maintainer on 2026-09-25. F12 today is the dev PPM dump. |
| Frame rate above 60 (90/120/144 with interpolation); v0.6.0 | verify | D578, #137 (f1zz1ec0ke), dev/UNLOCKED-FPS-PLAN.md |
Built 2026-10-07 (D578, rework of #137 by f1zz1ec0ke), branch feat/interp-fps: Video.FpsCap 90/120/144 draws matrix-blended frames between game frames on displays faster than 60 Hz; exact-frame fallback for turns (default ON); room-set change forces an exact frame; auto (match display) cap default. Latest commit 06ab98af: port-side portal-chain replay recomputes room scissors for the interpolated camera (verified 0 mismatches over 1,200 exact frames at alpha=1 on Dam; the deep tunnel chain and flicker are untested). Goal: a fresh Steam Deck install defaults to 90. Remaining before merge into the release/v0.6.0 line (all open): (1) Dam tunnel holes / pop-in re-test on a Deck with 06ab98af; (2) VSync-on re-test (74.5 presents/s seen earlier); (3) Windows 120 Hz check plus a default-60 golden regression; (4) alt-tab haze; (5) live 144 Hz and Deck OLED 90 Hz checks. Dam in-between flicker (2026-10-08, NOT FIXED, the blocker for shipping high FPS): eight Deck A/B variants (dclamp, projset, exactproj, clipfix, nodepth, nocull, fullsciss, plus the older noportal/nosciss/noclip/noreach) all still flicker, and the CPU emits the same triangle counts in blended and exact passes; the loss is per-pixel content, not missing triangles. Next: run holecap in the Dam tunnel gap (saves in-between vs exact images of a real hole) and read what the hole pixels are. Findings: D578 addenda; handoff: docs/HANDOFF.md. State 2026-10-10 (supersedes the "Remaining before merge" list and the Dam-flicker note above, both resolved by D578 2026-10-09 / D583): work lives on feat/d583-deck90 (local, unpushed, on top of feat/interp-fps). PC 120 + VSync on G-Sync fixed; Deck 90 good on most levels. Merged 2026-10-10 into land/v051-integration (off release/v0.6.0, with macos-arm64). Known issues for the release notes: Bunker fight drops on the Deck (D585 parked), Jungle feel, Cradle turret explosions (uninvestigated). Open gates: Dam ridgeline check with the clip widening off, default-60 golden regression / 21-level golden sweep, alt-tab haze, 144 Hz live check, VSync-without-G-Sync PC check. Was: decision. Older note: the menu cap was {30, 60} (the ini accepts 0 = uncapped, but the sim ticks at the VI rate); the plan's Phase 0 is resolved by D248 and its Phase 1 audit and Phase 2 slice scope are written (2026-09-30). Must stay compatible with netplay determinism. |
| PD Extended Options parity: settings that need new dev work | done (reviewed 2026-10-04; two rows deferred) | MENU-PARITY-SONNET-PLAN.md §3 (local notes); pd_port port/src/optionsmenu.c @ 32a1cb9 |
Reviewed 2026-10-04 (maintainer decisions; local notes). Done: D511 fullscreen mode, Center window, crosshair opacity and color by health (live check owed, MENU-LIVE-CHECKLIST.md A4/A5/B3). Watch Screen size/Ratio: stay on the watch, no PC rows; the game saves watch settings on watch close (D349 correction) and they don't fight Aspect ratio (README). Deferred past v0.5.0: mouse lock mode (Auto/Always/Off; aim lock itself = Input.AimMode, D337); per-seat controller device select (needs a stable pad id; MP input layer). Closed: edge deadzone = Input.AimRange (D338); crosshair sway N/A (GE has none; gun sway is D428); use key reloads, no toggle (Ext keeps D378's GEPD split, Control style Original gives the N64 behaviour); per-seat options/binds (pad binds already per seat, D469/D518; keyboard/mouse is one device); no Detail textures toggle (Video.DetailBaseTile is the D236 fix); N/A confirmed: HUD centering (D335b), glare, overexposure, GE64 muzzle flashes, MP death music, radial menu speed, language filter, crosshair speed. Other rows: analog movement/stick scale/crouch → #139, T7; tickrate/framerate limit → frame rate above 60. |
| One PC options UI: front-end "PC Options" opens the F10 overlay over the folder graphic | verify | D519, D343, D504, D510, D512 | Landed 2026-10-04 (D519): the file-select "PC Options" entry opens the F10 overlay over file select; the MENU_PC_OPTIONS screen and four old probes are gone; Bond-file rows and the watch chooser are keyed to file select. Headless checks pass. Owed: by-eye mouse, keyboard and pad pass on file select; profile chooser + Controller style with a real profile; footer text overlaps the Copy/Erase bar. |
| Emulator saves load directly in the game (no tool for import) | verify | D514, D492; port/src/eepimport.c called from geEepromLoad; D297 legacycrc.c same pattern |
Landed 2026-10-04 (D514). Copying a 1964/Project64 .eep in as data/ge007.eep works: on first launch each region that validates in emulator format and not port format is converted in place (same rules as eep_convert.py); regions invalid in both are left to the game's wipe; port saves untouched; the original is backed up to ge007.eep.emulator.bak. Export stays with eep_convert.py. Headless verify 6/6 byte-identical to the reference. Owed: by-eye mission select after importing a real 1964 save. |
DexDrive / GameFAQs .n64 saves |
idea (easy, post-1.0) | D514; sample scratch/eepinv/gamefaqs_dexdrive_2001.eep (local) |
Noted 2026-10-04. Old GameFAQs GoldenEye saves are DexDrive Controller Pak dumps (123-456-STD header, then a 32 KB pak) whose note (game code 3BADD1E5, 2 pages) holds the 512-byte cartridge EEPROM. Extracting it and zero-padding to 2048 bytes gives a valid emulator-format save (TenebrusoM sample: all 6 CRCs OK). Support = walk the note table, pull the note, pad, hand to the D514 importer (or an eep_convert.py dexdrive-to-pc subcommand). Not tested in game. |
| Title bar and window icon (no FPS counter; static "GoldenEye 007" title + GE-crosshair window icon) | done (v0.5.0 polish) | maintainer request 2026-10-17; D550; port/src/video.c, port/fast3d/gfx_sdl2.cpp, cmake/icon/ge007.rc; icon art = docs/img/icon/ge007-icon.png (tools_pc/make_icon.py) |
DONE 2026-10-17 (D550): static title bar (live FPS stays on F10), SDL_SetWindowIcon from a generated 32x32 header, exe icon via ge007.rc. Original generated mark, no game imagery. Build-verified; maintainer live window/taskbar check owed. |
Opt-in update check (Game.CheckUpdates, off by default) |
verify | D551; port/src/updatecheck.c |
Landed 2026-10-06: Game-page toggle; one HTTPS GET per launch to /releases/latest (no pre-releases); Windows loads winhttp.dll at runtime only. Live-verified (Win/Linux/Deck), security-reviewed. Follow-up PR (2026-10-06): (1) DONE 2026-10-07 (D575; offline harness tools_pc/updatecheck_test.c covers the edge-case half of (2); the live half is still owed). Was: the Linux/Deck curl path reads into a 64 KB buffer and treats curl's exit code as failure, so a /releases/latest response over 64 KB (long notes, many assets) silently gives no result even though tag_name is in the first ~1.5 KB; raise the cap and accept a full buffer (v0.4.0's response is 27 KB, so v0.5.0 is safe). (2) Validation matrix: offline harness for versionNewer/extractTag edge cases; throwaway builds with GE007_VERSION set to 0.3.0/0.4.0 against the live endpoint, Windows + Deck; a pre-release never prompts; after a publish, an older-version build shows the F10 row and opens the releases page; network-off and setting-off runs. |
| Control style: Classic/Original gamepad styles do not match the N64 (#145) | open (v0.7.0; reported on v0.5.0) | #145, D516, D498, D469, D518, D394; README gamepad section | Reported: (a) Input "Invert look" (port/src/input.c padLookInvertY, applied only on the right-stick look path, ~lines 2797/2821) does not reach the left stick when an Original style that aims with the left stick (1.2) is active. Hypothesis from code reading, not yet verified. (b) Face buttons under "Classic" do not revert to the original roles (original: South = change weapon, West = action/reload; port: South = action, West = reload, North = change weapon). (c) Menu buttons differ (original: South accepts, West goes back; port: West + South accept, East goes back). (d) The in-game watch invert row looks locked (D564 removed the game's own Look up/down row). Decision owed (maintainer): should "Original" mean strictly the N64 face-button and menu roles, with the modern roles kept as a separate preset? Port-only fix. Cross-refs the Gamepad presets row above. |
| Native N64 pads (raphnet adapter) | open (v0.7.0; unverified) | v0.5.0 video review; vendored mupen InputAutoCfg.ini |
Nothing raphnet-specific exists in the repo. The adapter should appear as an SDL joystick, but that is unverified. Work: verify with a real adapter or a user report (raw stick range ~+-80, octagonal gate, deadzone, C-buttons as buttons vs axes), then add a port-only N64-pad profile alongside the Xbox 1.2-1.4 styles. Owed: a real adapter test (maintainer or a tester). |
| v0.5.0 issue triage: #146 menu emblem, #147 gun sway part 2, #144 mission timer | open (v0.7.0 triage) | #146, #147, #144, D428 | #146: main-menu file-folder emblem texture corruption (4K, Fedora KDE); needs a repro and a 1964 comparison before any fix. #147: gun slides side to side but does not turn with the look direction (part 2 of the sway report, relates to D428); check against 1964 first. #144: optional PD-style mission timer; port-only QoL, small. Parked issues #113 (cheat toggles), #111 (bots), #110 (third-person), #105, #101, #100, #98 are unchanged and already decided/answered above. |
| README "what this is" line | open (v0.7.0, docs) | recurring viewer questions (v0.5.0 video comments) | Add a short, honest line to the README: a decomp-based native port, AI-assisted, with 1:1 fidelity as the goal. Answers the repeated vibe-coding doubts and comparisons with other GoldenEye ports. VR stays post-1.0 (reference row in Community forks). |
| Opt-in gameplay behaviour toggles (shoot-through, true rockets) | open (1.0, added 2026-10-09; not started — no F10 row, no ini key, no port code; today's build is pure vanilla) | §5b pattern; gunfire.c, chrprop.c; the 007 Plus source in the reference tree (semantic reference only — it is a modded decomp, never a copy source) |
Port-only, default off; one batched Rule-2 sign-off (same pattern as the §5b rows). Semantics (checked 2026-10-09 against the 007 Plus source in the reference tree): shoot-through = the per-weapon ObjectsShootThrough stat (gun.h:77; PROPFLAG2_SHOOTTHROUGH bondconstants.h:360; penetration-limit checks chrprop.c:2693/2822/2848) — how many cover objects a shot passes through; mods retune the per-weapon table (e.g. Moonraker 6 vs 2; the dabs weapon-stat notes agree) and the disable toggle restores the vanilla values (RAM override, All-unlocked class). True rockets — still open (2026-10-09): the on-disk Plus tree's rocket handling matches vanilla (propobj.c:4943: fixed 100.0f player-prop / 2.0f enemy damage, owner-tagged self-damage, unk8C wall-bounce), so the scene's "true" semantics are not in that tree, nor in the GEPD bundle or the footstep docs; plausible candidates = AoE radius/splash retune or door-destruction behaviour — confirm with the scene author before implementing. Implementation-risk note (maintainer 2026-10-09): these are game-adjacent weapon-stat edits — fine-tune, don't guess: implement as minimal RAM-override toggles, diff-check against the vanilla values, verify with 1964 A/B + golden frames, one small commit per toggle, human review of the diff. State 2026-10-09: nothing implemented. Work order: (1) one-off stats-table dumper (vanilla + tuned per-weapon values, both ROMs); (2) the RAM-override + F10 row (one small commit, per the risk note); (3) 1964 A/B + golden-frame verify. True rockets waits on the scene-author answer for its semantics. F10 rows; the Original N64 preset keeps both off. |
| Mod/patch support: drag-and-drop mod loading + mod management + mod template scaffolding + a shipped example mod | open (v0.7.0 start — maintainer 2026-10-09: mods come sooner, in v0.7.0, not after 1.0; full scope stays the 1.0 floor; added 2026-10-09) | D413 (capacity-only Rule-2 exception, user-approved 2026-09-28 — recorded in the mod-loader worktree's AGENTS.md), land/modloader-* worktrees, §5d; dabs CLAUDE-notes/mods.md (local reference) |
Progress so far (the Goldfinger 64 campaign, 2026-09-28 → 2026-10-08, worktree land/modloader-m1-backlog) — this is a working mod-loader layer, not a starting point; do not undersell it: the rommod layer is live — a 25.1 MB GF64 mod ROM loads over the 12.5 MB vanilla base (rommod: mod 'goldfinger64' requested — 58 raw file rows, 598 sidecar rows in the run logs; the standard pcmodels/pccg sidecar pools carry the extra content), with C2 ROM-patch decoding of the mod's patches. M1 done (97fda74f): GF64 boots, renders (walls fixed), clean-quits via the loader. C2 done (8c325fc5): the ROM-patch decoder CLI tools_pc/modpatch/ — branch-only, not yet merged to main. D413 (user-approved 2026-09-28): the capacity-only Rule-2 exception — raising compiled table/pool capacities (rommodTextureCap(), g_MaxProps, STAN_MAX_ROOMS) under #ifdef PORT with a provably-vanilla-identical gate; it is the mechanism that lets a mod exceed vanilla limits. Asset-prep + verification: the modprepare pipeline (decodes the vanilla RZ file table — 727 rows, all resolved → base_filelist.csv/base_table.json); a 70-run GF64-vs-vanilla A/B campaign (per-system: chrs/heads, levels, fog, portals, props, textures, vis/cull/nocull, mem, dyn, shots, clean-quit; vanilla-gate runs proving no-mod identity; GF64 re-verification runs against mainline findings). This row = M1→: content-tier mods (maps, textures, models) loadable by drop onto the exe / a mods/ folder, with a management list (enable/disable); custom patch support rides on the same path. Design standard (maintainer 2026-10-09): the dabs mod system — mods/<name>/{files,segs,textures} overlay dirs, single-overlay slot, live file swap (modListApplySelection / romdataResetFiles), restart path only for segs/ mods. Add (maintainer 2026-10-09): mod-template scaffolding + docs (new mod = copy template into mods/) and a first example mod we ship that does something cool. The starter/test mod is the gun-colour feature (maintainer 2026-10-09 — it does not stand alone as its own feature): per-weapon tint + a texture swap, demonstrating the scaffold end-to-end (crosshair colour is the separate shipped D511 — don't conflate). Precedent: the drop-in ROM converter already loads a Goldfinger 64 ROM — maps work, the mod's custom logic is inert; closing that gap (weapon/script data) is the stretch goal. Acceptance case: GEPD footstep-patch-style mods (bodies staying down, footstep SFX, core tweaks); their feature set maps onto the §5b opt-in toggles. v0.7.0 slice (maintainer 2026-10-09): look at mods sooner — merge M1/C2 to main, start the M1→ management + scaffolding (dabs standard) in v0.7.0, with the GF64 boot/render as the acceptance case; template + example mod and custom-patch support complete by 1.0. |
| Cut-content restoration (mod tier): extended MP roster + the 8 cut MP maps | open (1.0; added 2026-10-09, bring sooner if easy) | dev/CUT-CONTENT-BACKLOG.md §D/§F |
Everything is in the ROM data (backlog, verified): roster — front.c:601+ mp_chr_setup[] holds ~40 named entries beyond the 8 selectable (ROSIKA, KARL, TERRORIST, BIKER, …); maps — front.c:556-573 multi_stage_setups[] has 8 commented-out entries (Citadel/Frigate/Statue/Cradle/Aztec/Runway/Dam/Depot) and every one of those maps already boots standalone (-level_XX, geometry, AI setup and briefings intact). Tier 2/3: the table edits touch src/game → land on the mod-fork branch (non-negotiable #2) and ship through the mod scaffolding above; Tier-1 config-toggle grants stay port-side (backlog §2). Maintainer 2026-10-09: in the 1.0 roadmap at minimum; if the front.c table edits + setup fixes turn out small, pull in earlier (v0.7.0). Assessed 2026-10-10 (read-only, front.c): decision = not pulled in for v0.7.0. (a) Roster half is smaller than the row implies: num_chars_selectable_mp is already dynamic game logic (front.c:4240 unlock_all_mp_chars() sets 0x40 via the existing debug/cheat unlock-all; front.c:4986 sets 0x21 on Agent + Cradle-completed, else 8) — so an extended roster may need no src/game table edit at all: a Tier-1 port-only config toggle invoking the existing unlock path (live check owed: the 64-char select screen under the cheat) — the one-line "set the default to N" variant is the only src/game touch, and that stays mod-fork-only either way. (b) Maps half is the real cost: 8 entries are commented out with per-map state flags (stat/crad "works"; azt "needs setup"; dest/runway/dam/depot "xbla setup"; Citadel "old format") — uncommenting is trivial, the xbla/old-format/needs-setup fixes are not, and they touch src/game data handling → mod-fork branch. (c) v0.7.0 has no mod scaffolding yet (it lands with the 1.0 mod-fork), so there is no v0.7.0 ship path for the content itself; keep the item in 1.0 mod-fork scope and do the (a) live check opportunistically. |
| Motion/gyro aim (controller sensor) | open (1.0, added 2026-10-09) | — | Controller gyro look, opt-in, default off; sensitivity + calibration rows. Scope note (2026-10-09): gyro hardware exists only on PS4/PS5 pads (and the rare Switch Pro via adapter) — Xbox/XInput pads have no sensor, so the practical feature set is small; the API is SDL2 SDL_GameControllerGetSensor — verify first on the PS5 DualSense (maintainer has one; the D471 row already used it as a controller test) before building. Steam-Input-style gyro mapping stays a player-side workaround (the game is non-Steam, custom shortcut only — no Steamworks). |
| Localisation: JP/PAL ROM support first, then community language packs | open (1.0; reframed 2026-10-09) | §1 (PAL/JP row) | Reframed 2026-10-09 (maintainer): phase 1 = JP/PAL ROM support, already Stage B (§1). Phase 2 (later 1.0, community-driven) = a port-only text-override layer (data/languages/<code> packs overriding ROM strings) so people can add their own language packs if inclined; translation content is community-supplied (open-source-branching model). |
| Custom gun colour (ships as the example/starter mod — see the mod row above) | deferred (2026-10-09) | D511 (crosshair colour already shipped — a different thing) | Maintainer 2026-10-09: not a feature in its own right — it is the starter/test mod that demonstrates the mod scaffolding (per-weapon tint + texture swap); the hook (a tint pass in the model/fast3d stage) is designed when the mod row starts. |
5b. GE+ / Dab's-mod gameplay options (opt-in; touch game code)
| Item | Status | Refs | Notes |
|---|---|---|---|
| Disable knockback / hitstun, damage sound, endless death cam | post-1.0 | hooks at chraction.c:2233, gunfire.c:3334, bondview2.c:8354 |
Needs one batched Rule-2 sign-off. Decided 2026-10-01: after 1.0, all opt-in (default OFF), one batched Rule-2 sign-off. |
| Bodies stay where they fell | post-1.0 | — | Decided 2026-10-01: after 1.0, opt-in. |
| Port-native third-person camera | post-1.0 | #110 | The 007 Plus ROM patch itself is out of scope. Decide whether a port-native TP camera is in or out. Decided 2026-10-01: decide in/out after 1.0 with the other §5b options. |
5c. Enhanced visuals (optional; after feature-complete)
The XBLA/Nightdive-style "new look". None of it has started in this repo. An outside fork has a large Original/Enhanced/Remaster render-mode stack (see Community forks below). Adopting any of it is its own decision and needs Rule-2 review.
| Item | Status | Notes |
|---|---|---|
| Post-process chain: FXAA/SMAA, bloom, depth of field, colour grade/LUT, CRT filter, brightness/gamma, colourblind filters, SSAO | post-1.0 | Build the framebuffer pass once. Every effect defaults OFF. Decided 2026-10-01: after 1.0; our own opt-in implementation (default OFF; the Original N64 preset restores the N64 look); thepont's fork is reference only. |
| Near-full fog reveal (D503): far objects about 97% fogged show as faint silhouettes with straight room-clip edges on 32-bit output (e.g. Surface's dish) | verify | Snap landed 2026-10-04 (cutoff 247, not derived from measured vertex fog); dish residual = (C) widescreen frustum, moved to the §3 D222 row; by-eye pass across levels owed. Decided 2026-10-03 (maintainer): option (a), snap fog at or above ~97% to full fog (port-only, fast3d vertex fog). Option (b) (N64 16-bit colour/dither output) stays a candidate for the Original N64 bundle. Measurements: findings D503. |
| Render scale / supersampling, integer scaling, "authentic 320×240" mode | post-1.0 | Decided 2026-10-01: after 1.0; our own opt-in implementation (default OFF; the Original N64 preset restores the N64 look); thepont's fork is reference only. |
| Dynamic/coloured lighting, dynamic shadows, water reflections | post-1.0 | Large. Consult the PD port first. #105 is about the fork's version of reflections, not ours. Decided 2026-10-01: after 1.0; our own opt-in implementation (default OFF; the Original N64 preset restores the N64 look); thepont's fork is reference only. |
| Path-traced render mode (opt-in, RTGL1) | post-1.0 | Experimental, for fun (maintainer, 2026-10-01): deprioritised to after 1.0. Plan in the maintainer's local notes: vendor MIT RTGL1 behind port/rt/, default OFF; fast3d stays the default backend and the fidelity ground truth; Phase 0 is a toolchain spike (RTGL1 under MSYS2/MINGW64). Nothing starts before 1.0. |
| HD texture packs: loader + texnum dumper; model packs | open (1.0; loader + dumper bumped 2026-10-09, was post-1.0; model packs stay post-1.0) | #100 |
| Animation smoothing (keyframe slerp) | post-1.0 | Decided 2026-10-01: after 1.0; our own opt-in implementation (default OFF; the Original N64 preset restores the N64 look); thepont's fork is reference only. |
| F10 background blur + GUI-only texture filtering | post-1.0 | Backlogged 2026-10-04 (maintainer): visual nice-to-have after 1.0. Design done (local MENU-BLUR-GUIFILTER-DESIGN.md, ready Sonnet prompts in its §4). Blur: fast3d already decodes PD's framebuffer EXT opcodes and has the 16-tap kernel; only an emitter is missing (port/fast3d/gbiex.h); capture once on open (live capture too costly on HD 3000, D481). GUI filter: Video.GuiTextNearest point-samples texrects only. Port-only, default off. |
5d. Extras (nice to have)
In-game console · demo/replay record and playback (doubles as the
determinism harness, §7) · photo mode · benchmark mode · subtitles · HUD
opacity and a flash-intensity slider · a screen-shake slider that covers
every shake source (D181 only scales explosions) · F11 video recording ·
in-game patch notes and update check · mod loader (parked: branches
land/modloader-*, D413/D414; only the content tier M1/C3′ is viable here)
and a stage loader.
6. Multiplayer beyond the N64
| Item | Status | Refs | Notes |
|---|---|---|---|
| LAN netplay | open (1.0; bumped 2026-10-09, was post-1.0) | — | Depends on split-screen. Determinism groundwork is D117 (not achieved). Decided 2026-10-01: in scope after 1.0. Bumped to 1.0 (2026-10-09): single-screen view option alongside split-screen, spectator mode, and demo recording (doubles as the §7 determinism harness, §5d). Online (non-LAN) netplay is in scope via the client/server row below. |
| Online netplay: client/server (Zandronum-style) | open (1.0 if viable — tier 1 pre-1.0, narrow tier-2 core as the 1.0 stretch, else post-1.0 per the plan) | local note dev/notes/ONLINE-CLIENT-SERVER-PLAN.md (direction agreed 2026-10-07) |
Added 2026-10-09 (maintainer pivot; supersedes the blanket online exclusion in Not planned); maintainer 2026-10-09: wants it in 1.0 if viable — the viability gate is D117 determinism + the plan's tier-2 milestones, tier 1 (port-only) goes regardless. Target: client/server (Quake/QuakeWorld→Source lineage) with a Zandronum-style feature set; shipped as a build variant in the main repo (GE_ONLINE=ON → ge007-online client + headless ge007-server; no forks); game-logic hooks fenced under #ifdef GE_ONLINE so faithful builds stay byte-identical (golden frames prove it; a fenced Rule-2 amendment owed, maintainer call). Tiers: 1 port-only (lobby + NAT, server config, master server + browser, quick match, rcon — pre-1.0); 2 the GE_ONLINE core (authoritative server, prediction/reconciliation, mid-match join, spectators — start narrow: one level, one scenario, 4 players; 1.0 stretch, post-1.0 if the gate slips); 3 later (more players, unlagged hit checks, server demos). References: the PD port port-net branch (ENet, host-authoritative — closest analogue, study first); Zandronum/Odamex design-only (GPL — copy design, never code). The #141 security hold stands (forensic review before reusing any of it). |
| MP bots | open (1.0; bumped 2026-10-09, was post-1.0; opt-in) | #111 | Not N64 (GoldenEye's MP is human-only; Simulants are Perfect Dark). birdturtle simulants is an outside prototype. Decided 2026-10-01: in scope after 1.0 (opt-in; not N64). Bumped to 1.0 (2026-10-09): opt-in AI/scripted bots for local MP. |
| Co-op campaign | open (1.0; bumped 2026-10-09, was post-1.0; opt-in) | — | Not N64. thepont feature/coop is an outside prototype. Listed under Not planned unless this changes. Decided 2026-10-01: in scope after 1.0 (opt-in; not N64). Bumped to 1.0 (2026-10-09): opt-in split-screen co-op campaign (007 Plus-style). |
| Cheats beyond the N64 cheat menu | post-1.0 | #113 | Only in scope as an opt-in toggle. Decided 2026-10-01: in scope after 1.0, opt-in toggles only. |
7. Tooling, infrastructure, security
| Item | Status | Refs | Notes |
|---|---|---|---|
| 1964-vs-port comparison harness | partial | tools_pc/abpad/ |
One millisecond timeline drives 1964 (virtual XInput pad) and the port (GE_INPUTSCRIPT_MS); both windows captured on one clock with side-by-side sheets, verified through intro skip, file select and folder open. Not frame-identical (1964 has no seed pin or frame dump). Left: in-level timelines (e.g. the D486 turret check); the two sides use different save files. |
| Scripted-playthrough harness | post-1.0 (maintainer 2026-10-04: not a good use of current LLMs, revisit with newer models) | GE_INPUTSCRIPT, D117 |
Input script + GE_PCDUMP + crash-log check for unattended regression runs. Levers: Invincibility + Invisibility cheats, closed-loop waypoint steering, pinned seed. Spike: one Dam route x5, measure end-position spread, then go/no-go. |
| Cheap worker for mechanical, build-checked tasks | open | delegate-local MCP; memory of past Qwen issues |
Birdman64's fast worker model wrote 44% of its commits while the lead planned and reviewed. Ours: pattern-applied edits (D441 fix batches, scaffolding strips, small tools), each gated by a clean build + a specific check + the lead's diff review, in the worker's own worktree. Local Qwen for edit-only tasks (it fabricates on reading tasks), or a hosted fast model via delegate_to_provider (the maintainer's cost call). |
| Golden baselines | partial | tools_pc/verify.sh, tools_pc/golden/README.md, D117/D522/D529/D531 |
2026-10-06: all three sets (win/linux/deck) re-based for D543/D546, A/B-confirmed; history in the golden README. Windows gate GREEN (2026-10-05 re-base): 21/21 PASS honest sequential. The recipe pins the save CONTENT (D529: verify.sh installs the canonical in-tree save tools_pc/golden/ge007.eep per level) and per-level windows — 900-1500:300 on 14 levels, 1000-1400:200 on Surface 2/Streets/Depot/Cradle/Frigate, 1500-1700:100 on Dam — because the 900 stem sits inside the wall-clock-paced intro flyby (D117; dam measured 1.6–7.2 % run to run). No tol limit raised. Linux set (D525 → D530 → D531): D530's re-round ran under the box-local save (capture_p7.sh's re-pin overwrote D529's canonical install); D531 fixed the tool and re-captured all 21 levels under the canonical eep (47/63 frames moved). Cross-platform spread recomputed 2026-10-05 from the committed pairs (framediff.py win-vs-linux at the stems, tol 2): exact 0.380–5.120 % on the 20 non-Cuba levels (silo's 900 stem is the outlier: cell mean 34.3, phash 10), structural 21/21 clean, max phash 40 (cradle, at threshold); Cuba 1.357–12.663 % is the structural-tier-only level. Pixel gate green on all three, final v0.5.0 build (2026-10-06): win 21/21; linux 21/21 on the X220 (DISPLAY=:1 makes the GL probe see the real GPU; one Jungle flyby-jitter miss passed twice solo); deck 21/21 (needs XAUTHORITY for the probe over ssh). |
| Flicker scan (A/B/A frame alternation) | parked (2026-10-03: tooling, nothing blocked on it; local spec scratch/birdman64-rows-investigation.md §4) |
GE_PCDUMP, GE_INPUTSCRIPT |
Dump every frame of a scripted run at low resolution and flag frame n when it differs from n-1 but matches n-2. For any old-vs-new pixel diff outside the golden gate, run a same-commit control first. Reference: Birdman64 tools/flicker_scan.py. |
| GE_ probe catalog (macos-track diagnostics: keep vs strip) | done 2026-10-08 (strip debt closed; the GE_TEXDUMP KEEP family stays in-tree) |
dev/GE-PROBE-CATALOG.md |
The macOS track added env-gated, diagnostic-only GE_ probes (all off by default, no behavior change when unset). Keep: the GE_TEXDUMP family (GE_TEXN/GE_TEXDUMPROW/GE_TEXRAW + the GL .rgba32 upload dump — the standing cross-platform texture-triage tool, cached getenv). Stripped already (2026-10-08, b80dcd08): GE_NPOT_NOGENMIP (the D592 NPOT mip-guard, 9bed5904 + companion 82dbea9c) and GE_TEXSTATE (the D592 GL-state probe, de5a0fea) — both removed when D592 closed as a non-issue (metric false-positive; see the D592 close-out). Stripped 2026-10-08 (final probe-strip commit; on macos-arm64, pushed to Forgejo 2026-10-08): GE_TEXP (the src/game/image.c pool-cursor dump — its removal returns that region to the N64 build), GE_SIZEOF (the port/src/main.c startup ABI-width canary, redundant with the abi_ratchet.py CI) and GE_KEYLOG (the video.c+input.c D594 input diagnostic) — 75 pure deletions, behavior-neutral, Mac headless re-verified (2P + solo, 0 crash logs). Stripping is a mechanical, behavior-neutral edit. |
| Release build-provenance attestation | verify | .github/workflows/ci.yml release job; .github/SECURITY.md; README Status section |
Implemented 2026-10-04: SHA-pinned actions/attest-build-provenance attests dist/*.zip[.sha256] + dist/*.tar.gz[.sha256] in the tag-only release job (id-token: write + attestations: write on that job only). Backs SECURITY.md's "unsigned, but reproducible" stance with gh attestation verify <file> --repo jkdansereau/goldeneye-pc-port; documented in SECURITY.md and the README. Owed: the v0.5.0 tag build is the first real run; confirm the step passes and verification succeeds on a downloaded asset, then delete this row. |
| Self-hosted CI runner link failure | open (v0.7.0, maintainer 2026-10-10) | D244 | Needs a pacman -Syu on the runner (maintainer-only access). Release tag builds use GitHub runners, so it doesn't block a release. |
| Remove temporary scaffolding before a release | partial | dev/GE-ENV-PROBES.md, D302 |
Passes 2026-09-30 to 2026-10-03 removed the closed-finding probe suites (registry in GE-ENV-PROBES.md, gen_env_probes.py --check passing); TEMP probes GE_TESTSTYLE / GE_D516 removed 2026-10-04. Left: D104 (kept while D294 is in verify); the M-183/M-185 clamps were deleted 2026-10-04 (879f879a, model.c pure decomp again; the M-189 root fix stays) and the cutscene re-check was covered by the 2026-10-05 Deck campaign playthrough on rc1 (level intros, endings incl. Facility and Dam, credits). |
P12 U5 review of tools_pc/** (release-diff, B10) |
partial | D531/D532/D533 | Reviewed 2026-10-05 (the unit that owed the P7 merge). Blocker found + fixed (D531): capture_p7.sh's per-level re-pin restored the local save (see Golden baselines). Should-fixes applied as D532 (tooling-only): verify.sh's pin_ini_640x480 fails closed like pin_eep; GOLDEN_SEED hard-pinned with a warning for a stray GE_RSEED; audiodebug.ps1's dead -AB/-Old switches removed. Box pixel verify done 2026-10-06 (see Golden baselines). |
| Findings log and doc size | partial | tools_pc/docs_budget.py |
Budget checker (per-file and tier-1 token budgets; --toc FILE). findings.md is still about 2 MB (~500k tokens), so agents must keep using the index. Nothing blocks; trim only when a budget check fails. |
| Branch and PR housekeeping | open | — | 30 landed local branches pruned 2026-09-30 (tips in prune-branches-2026-09-30.txt, notes archive). On hold by the maintainer (do not prune yet): probe-only d243-verify-local, investigate/d243-cutscene-race, park/d236-probes-m139. Local main and release/v0.4.1 are deliberately not pushed. PR #62 (mouse dt-decouple) stays held until mouse feel is fundamentally better. |
| Docs site: Web 1.0 phase 2 | decision | — | Phase 1 shipped. Phase 2 (centred serif page) is plan-only. |
| Docs site: press/SEO pass (2026-10-05) | partial | docs/ site pages |
Landed on the pure site pages + layout: real <h1> masthead, color-scheme/theme-color/max-image-preview/rel=me, ink-mute >=4.5:1, focus-visible + selection, 15px body, mobile padding; date/modified_time front matter on the pure pages. Home-page additions (pull-quote, Overview fact table, press section) removed on review 2026-10-05 as duplicates. The five short topic notes (the-software-rsp, the-asset-pipeline, framerate-and-pacing, input-and-aim, saves) were dropped from the published set (files stay as working material). Open: the same front matter on the shared docs is deliberately untouched (authoritative working docs, not edited for site polish). |
| Agentic-development deep dive (doc) | queued — not yet (2026-10-05) | docs/dev/agentic-development.md |
Write-up owed for the public case study: per-agent commit/work estimates (manual attribution pass over the session log, incl. D350-style commit-date divergences), a code-quality audit of the trial models (GPT-6 (Sol) et al.), and process feedback / findings. Deferred by the maintainer; nothing here blocks. |
| Docs site: split Security & fidelity -> two pages + v0.5.0 update pass (2026-10-05) | done (local, unpushed) | docs/security.md, docs/fidelity.md (was security-and-fidelity-status.md) |
Split on review (the homepage pointer sat near Known issues and read as if there were security issues); both pages cross-linked and linked from the hub and index.md's Download section. Update pass 2026-10-05 against the release/v0.4.1 tree: no network includes/symbols/HTTP literals in compiled src/+port/; no registry or library-loading calls; converter imports no network module; bundle manifests re-checked (allowlist + ROM/oversized-blob hard-fail); region macros re-compared vs the Makefile (all three regions); library classification re-checked (CMake globs libultra+libultrare audio, gu, io/vitbl.c only). Full game-logic audit not re-run; recent src/game edits are finding-gated. |
| Docs site: final sanity sweep + anchor fixes (2026-10-05) | done (local, unpushed) | docs/porting-notes.md (3 TOC hrefs), docs/404.html (permalink) |
Audit of the 10-page published set (one h1 per page, no heading skips, in-page anchors resolve, unique titles/descriptions, og:image/canonical, JSON-LD, no local paths, served == built). Three porting-notes.md TOC hrefs had a double hyphen where kramdown emits one: corrected at source against the live ids. docs/404.html got permalink: /404.html. Preview-builder slug rule fixed to kramdown's. |
| LLM-agent dev-velocity workstream (model tiers + subagents + compaction hygiene) | decision — Tier 0/1 landed 2026-10-09; two approvals outstanding | docs/dev-process.md §8, pi/ package, forensics of pi session 01a11ec6 (#150 cull-hunt evening) |
Root cause of the #150 loss was model + discipline, not retrieval: a 4-bit-quantized 27B default model fired unvalidated render fixes at the maintainer for A/B (four consecutive failures); the 04:52Z compaction promoted an unvalidated hypothesis to "diagnosed" and post-compaction turns built on it. RAG/GitNexus evaluated and rejected (PolyForm license conflict, auto-writes AGENTS.md, wrong failure class; the repo's findings-index.csv is the domain-specific retrieval layer). Landed per the 2026-10-09 maintainer instruction: Tier 0 — ~/.pi/agent/settings.json default = the ninfer backend's model (only one of ninfer/strata runs at a time, and ninfer is the fast one; today that is the coding-launcher 4-bit qwen3.8-27b-nvfp4full — the quality launcher ninfer-quality.bat serves the groupwise-int qwen3.8-27b as the strong local tier, a 30-second launcher restart + new pi session, not a backend switch); §8 rules (model tiers; data-before-edit; context reset after a 2nd failed maintainer A/B or a contested compaction; evidence-ledger compaction prompt); MODEL line in the brief template. Tier 1 — pi install npm:pi-subagents@0.76.1 (pinned; audit in docs/dev/notes/pi-subagents-audit.md: MIT, no eval/telemetry, no install hooks, 310 js files) + tracked pi/ package: four model-pinned subagent roles on ninfer (build-runner/sweep-watcher/doc-sync on 4-bit; pairing pinned inherit so the reasoning step follows the parent session's tier) + the compaction-ledger extension (evidence-ledger prompt; optional stronger summarizer via GE_COMPACT_MODEL). Awaiting maintainer approval: (1) pi-subagents as a third-party npm dependency; (2) the tier split itself — planning on openrouter/deepseek/deepseek-v4-pro (or strata-coder-hard with the local backend switched), execution on the standing ninfer backend (default = the model it serves, today the 4-bit nvfp4full). Parked until after v0.7.0: pi-plans trial (228★/2 contributors, exploratory benchmark, self-published evidence), rpiv-ask-user-question, Langfuse tracing, pi-durable-subagents (1★, unvetted); do NOT stack billion-context on the ledger extension (compaction overlap). Workstream mapping: first real runs on the v0.6.0 critical path — D578 Dam-tunnel flicker (feat/interp-fps; the holecap probe is build-runner-shaped) and D579 T-step (a)+(c) log pairing (the pairing agent's first job); build-runner + sweep-watcher support the v0.7.0 #145/native-pad campaigns. The ledger extension loads at session start, so its verification happens in a fresh session. |
Community forks (not ours; reference only)
| Fork | What it has | Relevance |
|---|---|---|
thepont/goldeneye-pc-port feature/graphics-final-stack, fix/original-water-fidelity, feature/coop |
ORIGINAL/ENHANCED/REMASTER render mode, lighting, post-FX, bump/shadow/DoF, water reflections, vector HUD font, 2P co-op | Source of #105. Heavy src/game edits. Their D323–D326 and "D329" labels clash with ours, so relabel anything ported. |
birdturtle feature/local-mp-input, simulants |
Local MP restore; first MP bot | Cross-check for #99 and #111. |
kaziema vita |
PS Vita port | Platform reference. |
mattymattmattmatt/goldeneye-pcvr-port vr/stereo-headaim |
VR stereo + head aim | Platform reference. |
Decisions owed (maintainer)
Decided 2026-09-30 and 2026-10-01 (all moved into the rows above): PAL/JP in Stage B; All unlocked as a RAM override; D357 approved with changes; platform parity gate; feature PRs get a design review first; port_addr for #88/#95; D417 approved; the gameplay-visibility policy (§2); §5b, §5c and §6 post-1.0 and opt-in; D433 code audit; D323 post-1.0; #94 closes as stale on release.
Nothing else owed right now (outside PRs decided 2026-10-01, see §5a).
Not planned
Online matchmaking, leaderboards, anti-cheat, cross-play (client/server
netplay is in scope now — the §6 online row) · Steamworks, achievements, cloud
saves · HDR, frame
generation, stereo 3D (ray tracing only as the opt-in post-1.0 experiment
in §5c) · remake-scope assets (new models, music or voice) · new movement
mechanics (jump, roll, melee) · the 007 Plus ROM patch as such (#110) · a
per-user save folder (decided 2026-10-03: saves stay next to the game,
keeping the security doc's "never writes to %APPDATA%" promise) · a
first-launch controls card and controller toasts (decided 2026-10-03: new
UI for little gain; F10 is documented in both READMEs).