Prepare repository for public release

- README: attract-mode stills + demo GIF as the hero row, status/warning
  callouts, metrics table, "Contents" index, doc-index table; simplified
  the two-agent workflow diagram (LR -> TD, fewer edges) for GitHub web
- Table-of-contents indexes added to internals.md, porting-notes.md,
  agentic-development.md, AUDIO-PLAN.md
- CI: add Windows/MSYS2 build job, minimal token (contents: read),
  persist-credentials: false, concurrency group; run on main + master.
  validate job regenerates the US ROM-asset symbol file only and configures
  ntsc-final (PAL/JP need a region ROM; no ROM is used in CI)
- .github: SECURITY.md, issue forms + chooser config, PR template,
  labels.yml, dependabot (Actions, monthly)
- Do not track the proprietary SGI IRIX IDO toolchain or SGIImageViewer.exe;
  document in SetupGuide.md / building.md how to obtain IDO for N64 ROM
  builds (the PC port does not need it)
- Stop tracking two committed *.pyc files; drop stale screenshots and a
  redundant .gitignore line; misc doc cross-reference fixes

Claude-Session: https://claude.ai/code/session_01GULf6knbsqfsnW39tMr9WT
This commit is contained in:
James Dansereau committed 2026-09-01 22:42:52 -04:00
1 parent 5baa53eb61
commit 4ca11e4386
32 files changed
+573 -154

No files matched your search

+2
View File
@@ -1,6 +1,8 @@
* text=auto eol=lf * text=auto eol=lf
*.png binary *.png binary
*.jpg binary *.jpg binary
*.gif binary
*.mp4 binary
*.z64 binary *.z64 binary
*.exe binary *.exe binary
*.bin binary *.bin binary
+71
View File
@@ -0,0 +1,71 @@
name: Bug report (build or run)
description: A build failure, crash, hang, or rendering/audio/input defect in the PC port
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for filing a report. First, please check:
- The port is **Phase 2 of 4** — rendering is incomplete and many
cosmetic defects are already tracked in
[`docs/dev/GRAPHICS-BACKLOG.md`](https://github.com/jkdansereau/goldeneye-pc-port/blob/main/docs/dev/GRAPHICS-BACKLOG.md).
Search open issues and that file before filing.
- Only the **Windows / MSYS2 MINGW64** build is tested. Linux and
macOS are best-effort — build breaks there are expected.
- Do **not** attach a ROM, extracted assets, or any game data.
- type: input
id: commit
attributes:
label: Commit
description: Output of `git rev-parse --short HEAD`
placeholder: 311fd012
validations:
required: true
- type: dropdown
id: region
attributes:
label: Region / ROMID
options: [ntsc-final, pal-final, jpn-final]
validations:
required: true
- type: input
id: os
attributes:
label: OS / environment
description: e.g. "Windows 10, MSYS2 MINGW64" or "Ubuntu 22.04, native gcc"
validations:
required: true
- type: dropdown
id: stage
attributes:
label: Which stage fails?
options:
- Asset extraction
- CMake configure
- Compile / link
- Runtime — crash or hang
- Runtime — wrong rendering / audio / input
validations:
required: true
- type: textarea
id: what
attributes:
label: What happened vs. what you expected
validations:
required: true
- type: textarea
id: repro
attributes:
label: Steps to reproduce
description: Exact commands, flags (e.g. `-level_09`), and what you did in-game.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs
description: |
Paste the terminal error, and `ge007.crash.log` if the port crashed.
For a rendering defect, attach a screenshot.
render: text
+14
View File
@@ -0,0 +1,14 @@
blank_issues_enabled: true
contact_links:
- name: Build & setup guide
url: https://github.com/jkdansereau/goldeneye-pc-port/blob/main/docs/building.md
about: Read this first for build/extraction problems — most are covered here.
- name: Known rendering defects
url: https://github.com/jkdansereau/goldeneye-pc-port/blob/main/docs/dev/GRAPHICS-BACKLOG.md
about: Cosmetic / rendering issues already known and tracked. Check before filing.
- name: Security vulnerability
url: https://github.com/jkdansereau/goldeneye-pc-port/security/advisories/new
about: Report memory-safety / build-pipeline vulnerabilities privately, not as a public issue.
- name: Rights-holder concern
url: https://github.com/jkdansereau/goldeneye-pc-port/blob/main/NOTICE
about: If you represent a rights holder, see NOTICE and open an issue titled accordingly.
+41
View File
@@ -0,0 +1,41 @@
# Security Policy
This project is a non-commercial, fan-made research port. It has no server
component and ships no binaries. The realistic security surface is:
- the PC port executable parsing your own ROM and asset files at load time
(a malformed ROM/asset could in principle crash it or worse), and
- the build/extraction scripts and CI workflow.
## Reporting a vulnerability
Please **do not** open a public issue for a security problem.
Use GitHub's private vulnerability reporting:
**Security → Report a vulnerability** on this repository
(<https://github.com/jkdansereau/goldeneye-pc-port/security/advisories/new>).
If that is unavailable, email the maintainer at the address on their GitHub
profile with `SECURITY` in the subject.
Please include:
- affected version / commit hash (from `git rev-parse HEAD`),
- OS and how you built (region, `IDO_RECOMP`, MSYS2 vs WSL, …),
- a minimal reproduction, and
- the crash log (`ge007.crash.log`) or a stack trace if you have one.
## Scope
In scope: memory-safety bugs in the `port/` layer and PC-port tooling,
issues in the CI workflow or build scripts, and dependency problems we can
act on.
Out of scope: bugs inherited unchanged from the upstream
[GoldenEye 007 decompilation](https://github.com/n64decomp/007) that are not
made worse by the port (report those upstream), missing-asset or wrong-ROM
errors, and anything requiring a ROM or assets we do not distribute.
## Supported versions
Only the tip of the default branch is supported. There are no releases yet.
+8
View File
@@ -0,0 +1,8 @@
version: 2
updates:
# Keep the GitHub Actions used by .github/workflows/ up to date. Opens a PR
# when a new version of an action is released; review and merge like any other.
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
+58
View File
@@ -0,0 +1,58 @@
# Source of truth for this repo's issue/PR labels.
# GitHub does not read this file automatically. Apply it with the gh commands
# in the comment block at the bottom, or wire up a label-sync action later.
#
# `bug` and `documentation` are GitHub defaults and are kept as-is.
- name: bug
color: d73a4a
description: Something is broken
- name: rendering
color: 5319e7
description: Graphics / fast3d / RSP output defect (see docs/dev/GRAPHICS-BACKLOG.md)
- name: audio
color: 1d76db
description: Sound / music / libaudio (Phase 3)
- name: input
color: 0e8a16
description: Keyboard / mouse / controller
- name: build
color: fbca04
description: CMake / MSYS2 / toolchain / CI
- name: asset-extraction
color: c2e0c6
description: ROM asset extraction pipeline (scripts/, tools/extractor)
- name: upstream
color: bfd4f2
description: Originates in the n64decomp/007 decompilation, not the port — may belong upstream
- name: abi-64bit
color: fef2c0
description: 32-to-64-bit pointer-width / struct-layout issue (the #ifdef PORT exception)
- name: needs-repro
color: e99695
description: Cannot reproduce yet; waiting on more detail
- name: wontfix
color: ffffff
description: Out of scope or working as intended
# Apply with the GitHub CLI (run once, after the repo exists):
#
# gh label create rendering -c 5319e7 -d "Graphics / fast3d / RSP output defect"
# gh label create audio -c 1d76db -d "Sound / music / libaudio (Phase 3)"
# gh label create input -c 0e8a16 -d "Keyboard / mouse / controller"
# gh label create build -c fbca04 -d "CMake / MSYS2 / toolchain / CI"
# gh label create asset-extraction -c c2e0c6 -d "ROM asset extraction pipeline"
# gh label create upstream -c bfd4f2 -d "Originates in the decompilation, not the port"
# gh label create abi-64bit -c fef2c0 -d "32-to-64-bit pointer-width / struct-layout issue"
# gh label create needs-repro -c e99695 -d "Cannot reproduce yet; waiting on more detail"
#
# `bug` and `wontfix` already exist as GitHub defaults.
+37
View File
@@ -0,0 +1,37 @@
<!--
Read CONTRIBUTING.md first. This is a faithfulness-focused port; the ground
rules there are non-negotiable.
-->
## What this changes
<!-- One or two sentences. Link the issue it closes: "Closes #123". -->
## Why
<!-- The reasoning, not just the diff. What was wrong / missing? -->
## Scope check
- [ ] No changes under `src/` or `include/` — **or** the only changes are the
narrow `#ifdef PORT` ABI exception (CONTRIBUTING.md rule 2), and each is
documented in `docs/porting-notes.md` / `docs/dev/findings.md`.
- [ ] `Makefile`, `tools/`, `rsp/`, `ld/` untouched (N64 build).
- [ ] If `CMakeLists.txt` `REGION_DEFS` changed, it still matches the N64
`Makefile` per-region macro set exactly.
## Verification
<!-- What you actually ran. Delete lines that don't apply. -->
- [ ] `./build-pc.sh ntsc-final` — clean configure + link
- [ ] Crash-free run of at least one level (`-level_09`)
- [ ] Single-frame `GE_PCDUMP` diff against the committed golden — no
unexpected change
- [ ] pal-final / jpn-final also configured
Platform tested: <!-- e.g. Windows 10 / MSYS2 MINGW64 -->
## Notes for the reviewer
<!-- Anything uncertain, follow-ups, or areas that need a closer look. -->
+80 -19
View File
@@ -2,26 +2,43 @@ name: CI
on: on:
push: push:
branches: [ master ] branches: [ main, master ]
paths-ignore: [ '**.md', 'docs/**', 'LICENSE', 'NOTICE' ] paths-ignore: [ '**.md', 'docs/**', 'LICENSE', 'NOTICE' ]
pull_request: pull_request:
paths-ignore: [ '**.md', 'docs/**', 'LICENSE', 'NOTICE' ]
workflow_dispatch: workflow_dispatch:
# The full port build needs assets extracted from a copyrighted ROM, which CI # Minimal token: CI only reads the repo and uploads build artifacts, neither of
# does not have. This job validates everything that does NOT depend on those # which needs write access. Fork PRs run untrusted build scripts on the runner,
# assets: the PC-port tooling, the generated ROM-asset symbol files, and a # so keep the granted scope as small as possible and never expose secrets here.
# CMake configure of all three regions (which checks REGION_DEFS, the source permissions:
# list, and that SDL2 / zlib / OpenGL are discoverable). contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
# Two jobs:
# #
# This is a configure-only smoke test. It does NOT compile or run the port, and # validate — ubuntu, configure-only. Byte-compiles the tooling,
# it running on ubuntu is NOT a statement that the port builds or works on # regenerates the US ROM-asset symbol file, and CMake-
# Linux — it has only ever been built and tested on Windows (MSYS2). # configures ntsc-final (REGION_DEFS, the source list, and
# that SDL2 / zlib / OpenGL are discoverable). No ROM is used.
# Does NOT compile; running on ubuntu is NOT a claim the port
# works on Linux.
#
# windows-build — windows/MSYS2, the real supported platform. Compiles and
# links the full executable. Neither the ROM nor extracted
# assets are needed to BUILD (they are runtime-only), so CI
# builds but never runs the port.
jobs: jobs:
validate: validate:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -31,17 +48,61 @@ jobs:
- name: Byte-compile Python tooling - name: Byte-compile Python tooling
run: python3 -m compileall -q scripts tools_pc run: python3 -m compileall -q scripts tools_pc
- name: Regenerate ROM-asset symbol files # US only. gen_romassets.py resolves every symbol for the US region from
# the committed CSVs with no ROM present; PAL/JP each need a handful of
# region-specific prop/font offsets that only come from that region's ROM
# (see docs/building.md — PAL/JP builders generate romassets_e/j.s
# locally). No ROM is used or required here.
- name: Regenerate ROM-asset symbol file (US)
run: | run: |
python3 scripts/gen_romassets.py u python3 scripts/gen_romassets.py u
python3 scripts/gen_romassets.py e
python3 scripts/gen_romassets.py j
git diff --stat -- port/src/romassets_u.s git diff --stat -- port/src/romassets_u.s
- name: CMake configure (all regions) - name: CMake configure (ntsc-final)
run: | run: cmake -S . -B build-ntsc -DROMID=ntsc-final
for r in ntsc-final pal-final jpn-final; do
echo "::group::configure $r" # Real Windows (MSYS2 MINGW64) build — the only platform the port is
cmake -S . -B "build-$r" -DROMID="$r" # developed and tested on. This compiles and LINKS the full executable.
echo "::endgroup::" #
done # No ROM and no extracted assets are needed to build: the compiled asset set
# is a handful of committed pure-data .c files plus the generated
# address-constant romassets_<region>.s. The ROM (.z64) and the ROM-derived
# blobs are runtime-only dependencies — CI cannot run the game, only build it.
windows-build:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-toolchain
mingw-w64-x86_64-cmake
mingw-w64-x86_64-SDL2
mingw-w64-x86_64-zlib
mingw-w64-x86_64-python
- name: Regenerate ROM-asset symbol file (US)
run: python scripts/gen_romassets.py u
- name: Build (ntsc-final)
run: ./build-pc.sh ntsc-final
- name: Upload executable
uses: actions/upload-artifact@v4
with:
name: ge007-ntsc-final
path: build-pc/ge007*
if-no-files-found: error
retention-days: 14
# CI builds the executable but does not run it — running the port needs a
# ROM, which CI does not provide. Runtime checks (the -level_09 soak, a
# golden-frame diff) would run on a self-hosted runner instead. Not planned.
+6 -1
View File
@@ -76,6 +76,12 @@ ge007.ini
!build/test.c !build/test.c
!notes/StyleGuide.md !notes/StyleGuide.md
#tools #tools
# Original SGI IRIX 5.3 IDO toolchain (proprietary SGI binaries) and the SGI
# image viewer are NOT distributed with this repo. They are only needed to
# build the N64 ROM or to regenerate tools/ido5.3_recomp; the PC port does not
# use them. See docs/SetupGuide.md "Recompile IDO" for how to obtain them.
tools/irix/
tools/SGIImageViewer.exe
tools/extractor/*.o tools/extractor/*.o
tools/extractor/extractor tools/extractor/extractor
tools/aaa_rip/main.o tools/aaa_rip/main.o
@@ -117,7 +123,6 @@ assets/obseg/em/data/under.seg
scripts/local/ scripts/local/
scripts/make/local/ scripts/make/local/
scripts/__pycache__/generate_prop_model_c.cpython-310.pyc
# PC port debug/session artifacts # PC port debug/session artifacts
_run.log _run.log
+4 -4
View File
@@ -4,8 +4,8 @@
- `n64decomp/007`: WIP decompilation of GoldenEye 007 (N64), byte-matches US/EU/JP ROMs. - `n64decomp/007`: WIP decompilation of GoldenEye 007 (N64), byte-matches US/EU/JP ROMs.
- Active work: **PC port** modelled on the Perfect Dark PC port (same Rare "Indy" engine family). - Active work: **PC port** modelled on the Perfect Dark PC port (same Rare "Indy" engine family).
- **Reference docs:** `docs/internals.md` — architecture, GE-specific RSP deltas, phased plan (§1–§10). `docs/dev/findings.md` — the `Dxx` finding log (§F + §H, indexed at the top of §F); read the entry you need, don't linear-read. `docs/porting-notes.md` — the recurring N64→PC bug classes, one screen. - **Reference docs:** `docs/internals.md` — architecture, GE-specific RSP deltas, phased plan (§1–§10). `docs/dev/findings.md` — the `Dxx` finding log (§F + §H, indexed at the top of §F); read the entry you need, don't linear-read. `docs/porting-notes.md` — the recurring N64→PC bug classes (dense; skim the headers, read what's relevant).
- **Current status:** the README "Status" section. Current task + environment: `docs/HANDOFF.md` (a rolling local working file). - **Current status:** the README "Status" section, and `docs/dev/LEVEL-STATUS.md` for the per-level sweep. Current task + environment: `docs/HANDOFF.md` (a rolling local working file — may be absent in a fresh clone; fall back to the README "Status" section).
- **Dispatching subagents?** `docs/dev-process.md` — task budgets/deadlines, file partitioning, pre-flight, the standard brief template. Every investigation subagent reads `docs/porting-notes.md` first and appends to it. - **Dispatching subagents?** `docs/dev-process.md` — task budgets/deadlines, file partitioning, pre-flight, the standard brief template. Every investigation subagent reads `docs/porting-notes.md` first and appends to it.
## Non-negotiables ## Non-negotiables
@@ -55,7 +55,7 @@ Run `/linkcheck` for this sweep. Record new findings in `docs/dev/findings.md`
start) is functional; file-backed EEPROM saves work. Cosmetic defects are start) is functional; file-backed EEPROM saves work. Cosmetic defects are
parked in `docs/dev/GRAPHICS-BACKLOG.md`. parked in `docs/dev/GRAPHICS-BACKLOG.md`.
- **Phase 3 (audio + input):** input layer done (`port/src/input.c`); polish - **Phase 3 (audio + input):** input layer done (`port/src/input.c`); polish
bugs open (D118*, D169). Audio not started — libaudio → SDL, copy-and-adapt bugs open (D118* mouse-look residuals; interactive feel-checks owed). Audio
from the PD port's `mixer.c`. not started — libaudio → SDL, copy-and-adapt from the PD port's `mixer.c`.
- **Phase 4 (saves + polish):** file-backed EEPROM done; widescreen, config, - **Phase 4 (saves + polish):** file-backed EEPROM done; widescreen, config,
rebinding UI outstanding. rebinding UI outstanding.
+10 -8
View File
@@ -12,15 +12,16 @@ Context is scarce. Load by tier; do not blind-read whole files.
- **Tier 0 — always (auto-loaded):** `CLAUDE.md`, `AGENTS.md`. Nothing - **Tier 0 — always (auto-loaded):** `CLAUDE.md`, `AGENTS.md`. Nothing
else auto-loads. else auto-loads.
- **Tier 1 — every session start, read fully (both are short):** - **Tier 1 — every session start:**
`docs/HANDOFF.md` (current state + next task + environment — a rolling `docs/HANDOFF.md` (current state + next task + environment — a rolling
local working file; may be absent in a fresh clone, in which case read local working file; may be absent in a fresh clone, in which case read
the README "Status" section instead), the README "Status" section instead) — read fully;
`docs/porting-notes.md` (recurring bug classes). `docs/porting-notes.md` (recurring bug classes) — skim the section
headers, read the classes relevant to the task.
- **Tier 2 — on demand only, do NOT read start-to-finish:** - **Tier 2 — on demand only, do NOT read start-to-finish:**
- `docs/internals.md` — architecture / RSP deltas / phased plan (§1–§10 - `docs/internals.md` — architecture / RSP deltas / phased plan (§1–§10).
of the old research doc). Read the section you need. Read the section you need.
- `docs/dev/findings.md` — the `Dxx` finding log (§11 + §F + §H). - `docs/dev/findings.md` — the `Dxx` finding log (§F + §H).
**Jump to a specific `Dxx` via the index at the top of §F.** Never **Jump to a specific `Dxx` via the index at the top of §F.** Never
linear-read. linear-read.
- `docs/dev/HANDOFF-ARCHIVE.md` — prior-session narrative (M-2…). Only - `docs/dev/HANDOFF-ARCHIVE.md` — prior-session narrative (M-2…). Only
@@ -33,8 +34,9 @@ Context is scarce. Load by tier; do not blind-read whole files.
Having a concrete "next step" from the handoff is NOT license to skip this. Having a concrete "next step" from the handoff is NOT license to skip this.
1. Read the Tier 1 docs: `docs/HANDOFF.md` (immediate task, standing 1. Read the Tier 1 docs: `docs/HANDOFF.md` (immediate task, standing
procedure, environment gotchas) and `docs/porting-notes.md` procedure, environment gotchas — or the README "Status" section if it is
(recurring bug classes — you will re-derive catalogued bugs if you don't). absent) and `docs/porting-notes.md` (recurring bug classes — you will
re-derive catalogued bugs if you don't).
2. Skim the README "Status" section for where the project stands. 2. Skim the README "Status" section for where the project stands.
3. If you may dispatch a subagent this session, read `docs/dev-process.md` 3. If you may dispatch a subagent this session, read `docs/dev-process.md`
NOW — not at dispatch time. NOW — not at dispatch time.
+3 -3
View File
@@ -11,7 +11,7 @@ keep the port faithful to the original game.
belong to the N64 build and are never touched for PC work. If PC code seems belong to the N64 build and are never touched for PC work. If PC code seems
to need a behavioural change in the game, the fix belongs in `port/`. to need a behavioural change in the game, the fix belongs in `port/`.
2. **Narrow ABI exception.** The 32->64-bit transition forces a small class of 2. **Narrow ABI exception.** The 32→64-bit transition forces a small class of
mechanical, semantics-preserving edits to ROM-serialized structs (storing an mechanical, semantics-preserving edits to ROM-serialized structs (storing an
embedded 32-bit pointer as `u32` and casting at the use site). These are embedded 32-bit pointer as `u32` and casting at the use site). These are
allowed, must be guarded with `#ifdef PORT`, must change no behaviour, and allowed, must be guarded with `#ifdef PORT`, must change no behaviour, and
@@ -35,6 +35,6 @@ keep the port faithful to the original game.
## Where to look ## Where to look
- `docs/internals.md` — how the port is structured. - `docs/internals.md` — how the port is structured.
- `docs/porting-notes.md` — the recurring bug classes; check here before - `docs/porting-notes.md` — the recurring bug classes. Check here before
debugging a crash, you are likely looking at a known pattern. debugging a crash; you are likely looking at a known pattern.
- `docs/dev/` — the full finding log and per-level status. - `docs/dev/` — the full finding log and per-level status.
+92 -64
View File
@@ -1,5 +1,10 @@
# GoldenEye 007 — PC port # GoldenEye 007 — PC port
![status](https://img.shields.io/badge/status-Phase_2_of_4_(rendering)-orange)
![tested on](https://img.shields.io/badge/tested_on-Windows_x86--64-blue)
![license](https://img.shields.io/badge/license-MIT-green)
![built with](https://img.shields.io/badge/built_with-coding_agents-8A2BE2)
A work-in-progress native port of **GoldenEye 007** (Rare, 1997) to modern A work-in-progress native port of **GoldenEye 007** (Rare, 1997) to modern
desktop platforms, built on top of the desktop platforms, built on top of the
[GoldenEye decompilation](https://github.com/n64decomp/007). [GoldenEye decompilation](https://github.com/n64decomp/007).
@@ -11,26 +16,33 @@ sources are compiled for the host; the N64's Reality Signal Processor is
emulated in software; every other hardware surface (video, audio, input, emulated in software; every other hardware surface (video, audio, input,
timers, save storage) is shimmed in a dedicated `port/` layer. timers, save storage) is shimmed in a dedicated `port/` layer.
> [!IMPORTANT]
> **You must supply your own GoldenEye 007 ROM.** This repository contains no > **You must supply your own GoldenEye 007 ROM.** This repository contains no
> Nintendo code or assets, and no ROM. Nothing here is distributable as a > Nintendo code or assets, and no ROM. Nothing here is distributable as a
> playable game — see [Requirements](#requirements) and [Legal](#legal). > playable game — see [Requirements](#requirements) and [Legal](#legal).
<p align="center"> <p align="center">
<img src="docs/img/archives-1.png" width="49%" alt="Archives level rendering in the port"> <img src="docs/img/attract-bunker1.png" width="32%" alt="Bunker 1 intro camera">
<img src="docs/img/bunker1-1.png" width="49%" alt="Bunker 1 rendering in the port"> <img src="docs/media/goldeneye-demo.gif" width="32%" alt="~15 s of the port running: mission dossier, Facility, Silo, Jungle, Archives">
<br> <img src="docs/img/attract-dam.png" width="32%" alt="Dam intro camera">
<img src="docs/img/archives-2.png" width="32%" alt="Guards in the Archives level"> <br><em>In-engine, running in the port — Bunker&nbsp;1 and Dam attract views, and a
<img src="docs/img/bunker1-2.png" width="32%" alt="Bunker 1 with HUD"> ~15&nbsp;s clip (no audio yet, Phase&nbsp;3): mission dossier &rarr; Facility &rarr; Silo &rarr;
<img src="docs/img/bunker1-3.png" width="32%" alt="Bunker 1 storage room"> Jungle &rarr; Archives.</em>
<br><em>In-engine captures &mdash; Archives and Bunker&nbsp;1 running in the port.</em>
</p> </p>
> **Not playable yet.** This is a work-in-progress research port. The intro and ## Contents
> menus render and all 21 solo levels load, but it is **not** a complete or
> reliably playable game: there is **no audio**, the front-end 3D models and - [Background](#background)
> some text are broken, input has known rough edges, and you should expect - [Status](#status)
> crashes and glitches once you are past the level intro. Treat it as a - [Requirements](#requirements)
> technical demo of the porting work, not a way to play GoldenEye. - [Building](#building) · [Windows (MSYS2)](#windows-msys2) · [Linux](#linux)
- [Running](#running) · [Default controls](#default-controls)
- [How it works](#how-it-works)
- [Project layout](#project-layout)
- [Documentation](#documentation)
- [Credits](#credits)
- [Legal](#legal)
- [License](#license)
## Background ## Background
@@ -55,33 +67,42 @@ It used two agents:
The two **handed work back and forth** through shared written artifacts: The two **handed work back and forth** through shared written artifacts:
```mermaid ```mermaid
flowchart LR flowchart TD
H["human<br/>direction · integration<br/>build + playtest"] H["human<br/>direction · integration · playtest"]
C["Claude<br/>(Claude Code)"] C["Claude<br/>(Claude Code)"]
Q["Qwen 3.8<br/>(pi, local RTX 5090)"] Q["Qwen 3.8<br/>(pi, local RTX 5090)"]
D[("shared artifacts<br/>finding log · bug-class notes · handoff doc")] D[("shared artifacts<br/>findings · notes · handoff doc")]
H -->|"scoped task + budget"| C H -->|"scoped task + budget"| C
H -->|"scoped task + budget"| Q H -->|"scoped task + budget"| Q
C <-->|read / append| D C -->|"patch + write-up"| D
Q <-->|read / append| D Q -->|"patch + write-up"| D
C -.->|"hit usage limit ->"| Q C <-.->|handoff| Q
Q -.->|"needs deeper reasoning ->"| C D --> H
C -->|"patch + write-up"| H
Q -->|"patch + write-up"| H
``` ```
The handoff document was originally a session-to-session note; it became the The handoff document was originally a session-to-session note; it became the
**interface between the two models** — when Claude hit a usage limit **interface between the two models** — when Claude hit a usage limit
mid-problem, the local model picked the task up from that state and continued. mid-problem, the local model picked the task up from that state and continued.
**By the numbers:** ~2 weeks, one person part-time · 217 commits · 160 **By the numbers:**
root-caused bugs logged · ~30 handoff sessions · `#ifdef PORT` ABI edits in 63
game-source files · ~17k lines of port layer + ~6k lines of Python asset | Metric | Value |
tooling. By day 4 the full ~230-unit codebase compiled and linked; by day 8 |---|---|
the intro rendered; by **day 13 all 21 solo missions ran crash-free**; by | Timeline | ~2 weeks, one person part-time |
day 14 the front end was playable end to end. Estimated effort split | Commits | ~223 |
(milestone-weighted): **~60% Claude / ~40% local model** — the local model | Root-caused bugs logged | 162 (`D1`–`D169`; some later merged or withdrawn) |
built the entire foundation (build, boot, RSP wiring, converters). | Handoff sessions | ~33 |
| ABI edits to game code | 63 files, all `#ifdef PORT` |
| Port layer / tooling | ~17k lines C/C++ · ~6k lines Python |
| Effort split (milestone-weighted) | ~60% Claude · ~40% local model |
The local model built the entire foundation — build, boot chain, RSP wiring,
asset converters — then both agents ran the debugging phase together:
- **Day 4** — the full ~230-unit codebase compiles and links
- **Day 8** — the whole intro renders
- **Day 13** — all 21 solo missions run crash-free
- **Day 14** — front end playable end to end
Full write-up, timeline chart, and an honest "what worked / what didn't": Full write-up, timeline chart, and an honest "what worked / what didn't":
[`docs/dev/agentic-development.md`](docs/dev/agentic-development.md). The [`docs/dev/agentic-development.md`](docs/dev/agentic-development.md). The
@@ -89,13 +110,21 @@ workflow itself: [`docs/dev-process.md`](docs/dev-process.md).
## Status ## Status
> [!WARNING]
> **Not playable yet.** This is a work-in-progress research port. The intro and
> menus render and all 21 solo levels load, but it is **not** a complete or
> reliably playable game: there is **no audio**, the front-end 3D models and
> some text are broken, input has known rough edges, and you should expect
> crashes and glitches once you are past the level intro. Treat it as a
> technical demo of the porting work, not a way to play GoldenEye.
**Phase 2 of 4 (rendering).** The port boots, renders, and is playable through **Phase 2 of 4 (rendering).** The port boots, renders, and is playable through
the front end into the early game. It is not finished and it is not stable. the front end into the early game. It is not finished and it is not stable.
**Working** **Working**
- Boot -> Rare/Nintendo logos -> gun-barrel -> cast intro, fully rendered. - Boot → Rare/Nintendo logos → gun-barrel → cast intro, fully rendered.
- Front end: main menu -> mission select -> difficulty -> briefing -> mission start. - Front end: main menu → mission select → difficulty → briefing → mission start.
- **All 21 solo missions load, render, and survive an unattended play window - **All 21 solo missions load, render, and survive an unattended play window
without crashing** (see [`docs/dev/LEVEL-STATUS.md`](docs/dev/LEVEL-STATUS.md)). without crashing** (see [`docs/dev/LEVEL-STATUS.md`](docs/dev/LEVEL-STATUS.md)).
- Software RSP (fast3d): textured world geometry, skeletal characters, HUD, - Software RSP (fast3d): textured world geometry, skeletal characters, HUD,
@@ -107,8 +136,9 @@ the front end into the early game. It is not finished and it is not stable.
**Not yet working** **Not yet working**
- **Audio** — not implemented (Phase 3). The game runs silent. - **Audio** — not implemented (Phase 3). The game runs silent.
- Front-end 3D models (spinning Nintendo logo, gun-barrel Bond, cast) are - Some front-end 3D models — the spinning Nintendo logo, and the MISSION
mispositioned or absent. COMPLETE / mode-select models — are mispositioned or absent. (The
gun-barrel Bond intro renders correctly.)
- Assorted cosmetic defects (some text layout, a few incomplete asset - Assorted cosmetic defects (some text layout, a few incomplete asset
conversions) are tracked in conversions) are tracked in
[`docs/dev/GRAPHICS-BACKLOG.md`](docs/dev/GRAPHICS-BACKLOG.md) and parked [`docs/dev/GRAPHICS-BACKLOG.md`](docs/dev/GRAPHICS-BACKLOG.md) and parked
@@ -173,7 +203,8 @@ cd goldeneye-pc-port
./build-pc.sh ntsc-final ./build-pc.sh ntsc-final
``` ```
The executable is written to `build-pc/ge007.x86_64` (Windows: `.exe`). The executable is written to `build-pc/ge007.x86_64` (on Windows,
`build-pc/ge007.x86_64.exe`).
## Running ## Running
@@ -187,16 +218,16 @@ Configuration is written to `ge007.ini` on first run.
### Default controls ### Default controls
| Action | Keyboard / mouse | Controller | | Action | Keyboard / mouse | Controller |
|-------------------|-------------------------|-----------------------| |---------------------|--------------------------|---------------|
| Move / strafe | `W` `A` `S` `D` / arrows | Left stick | | Move / strafe | `W` `A` `S` `D` / arrows | Left stick |
| Aim / look | Mouse | Right stick | | Aim / look | Mouse | Right stick |
| Fire (Z) | Left mouse / `LCtrl` | Right trigger | | Fire (Z) | Left mouse / `LCtrl` | Right trigger |
| Aim mode (R) | Right mouse / `LShift` | Left trigger | | Aim mode (R) | Right mouse / `LShift` | Left trigger |
| Use / accept (A) | `Space` / `E` | A / X | | Use / accept (A) | `Space` / `E` / `X` | A / X |
| Reload / cancel (B)| `R` / `F` | B / Y / RB | | Reload / cancel (B) | `R` / `F` | B / Y / RB |
| L trigger | `Q` | LB | | L trigger | `Q` | LB |
| Start | `Enter` / `Tab` | Start | | Start | `Enter` / `Tab` | Start |
Mouse sensitivity, Y-inversion and the aim/turn split are tunable in the Mouse sensitivity, Y-inversion and the aim/turn split are tunable in the
`[Input]` section of `ge007.ini`. `[Input]` section of `ge007.ini`.
@@ -217,7 +248,7 @@ touch N64 hardware is redirected into `port/`:
- **`port/src/{video,audio,input,fs,romdata,config}.c`** — the SDL2 / OpenGL / - **`port/src/{video,audio,input,fs,romdata,config}.c`** — the SDL2 / OpenGL /
filesystem backends. filesystem backends.
The 32->64-bit transition forces a small, catalogued class of mechanical The 32→64-bit transition forces a small, catalogued class of mechanical
ABI-only edits to ROM-serialized structs (pointer-width reconciliation); these ABI-only edits to ROM-serialized structs (pointer-width reconciliation); these
change no behaviour and are documented individually. change no behaviour and are documented individually.
@@ -244,21 +275,15 @@ docs/ see below
## Documentation ## Documentation
- [`docs/building.md`](docs/building.md) — full build + asset-extraction guide. | Doc | What's in it |
- [`docs/internals.md`](docs/internals.md) — architecture, the RSP-emulation |---|---|
approach, GE-vs-PD engine differences, the phased plan. | [`docs/building.md`](docs/building.md) | Full build + asset-extraction guide. |
- [`docs/porting-notes.md`](docs/porting-notes.md) — the recurring N64->PC bug | [`docs/internals.md`](docs/internals.md) | Architecture, the RSP-emulation approach, GE-vs-PD engine differences, the phased plan. |
classes hit during the port, with fixes. | [`docs/porting-notes.md`](docs/porting-notes.md) | The recurring N64→PC bug classes hit during the port, with fixes. |
- [`docs/dev/agentic-development.md`](docs/dev/agentic-development.md) — the | [`docs/dev/agentic-development.md`](docs/dev/agentic-development.md) | The research angle: the two-agent setup, timeline, handoff workflow, and an assessment of what did and didn't work. |
research angle: the two-agent setup, timeline, handoff workflow, and a | [`docs/dev-process.md`](docs/dev-process.md) | The investigation workflow in detail — budgets, file partitioning, the finding-log discipline. |
candid assessment of what did and didn't work. | [`docs/dev/`](docs/dev/) | The raw engineering record: the full finding log, per-level status, graphics backlog, playtest matrices. |
- [`docs/dev-process.md`](docs/dev-process.md) — the investigation workflow in | [`docs/SetupGuide.md`](docs/SetupGuide.md), [`docs/StructureGuide.md`](docs/StructureGuide.md), [`docs/StyleGuide.md`](docs/StyleGuide.md) | Inherited from the decompilation. |
detail (budgets, file partitioning, the finding-log discipline).
- [`docs/dev/`](docs/dev/) — the raw engineering record: the full finding log,
per-level status, graphics backlog, playtest matrices.
- [`docs/SetupGuide.md`](docs/SetupGuide.md),
[`docs/StructureGuide.md`](docs/StructureGuide.md),
[`docs/StyleGuide.md`](docs/StyleGuide.md) — inherited from the decompilation.
## Credits ## Credits
@@ -267,7 +292,7 @@ This port is a thin layer on a large amount of other people's work.
**Prior work it is built on** **Prior work it is built on**
- The [GoldenEye 007 decompilation](https://github.com/n64decomp/007) — years of - The [GoldenEye 007 decompilation](https://github.com/n64decomp/007) — years of
effort by kholdfuzion, Larry Ficken, and the project's contributors; plus effort by Larry Ficken ("kholdfuzion") and the project's contributors; plus
zoinkity's GoldenEye documentation, which the decomp started from. This port zoinkity's GoldenEye documentation, which the decomp started from. This port
is a fork of that repository. is a fork of that repository.
- The [Perfect Dark PC port](https://github.com/fgsfdsfgs/perfect_dark) - The [Perfect Dark PC port](https://github.com/fgsfdsfgs/perfect_dark)
@@ -298,8 +323,11 @@ This port is a thin layer on a large amount of other people's work.
**Tools and models used to develop the port** **Tools and models used to develop the port**
- [Qwen 3.8](https://github.com/QwenLM/Qwen) (Alibaba Qwen team); - Qwen 3.8 (Alibaba Qwen team), run locally as the
[Unsloth](https://unsloth.ai) (the GGUF quantisation and Unsloth Desktop). [`unsloth/Qwen3.8-27B-GGUF`](https://huggingface.co/unsloth/Qwen3.8-27B-GGUF)
`UD-Q4_K_XL` quant;
[Unsloth](https://unsloth.ai) (the GGUF quantisation and Unsloth Desktop,
used as the local model server).
- [pi](https://pi.dev/) — the local coding-agent harness. - [pi](https://pi.dev/) — the local coding-agent harness.
- [Claude / Claude Code](https://claude.com/claude-code) (Anthropic). - [Claude / Claude Code](https://claude.com/claude-code) (Anthropic).
+2 -2
View File
@@ -5,14 +5,14 @@
# Usage: # Usage:
# ./build-pc.sh [ntsc-final|pal-final|jpn-final] # ./build-pc.sh [ntsc-final|pal-final|jpn-final]
# #
# Dependencies (see docs/internals.md): # Dependencies (see docs/building.md):
# - CMake >= 3.16 # - CMake >= 3.16
# - SDL2 dev # - SDL2 dev
# - zlib dev # - zlib dev
# - OpenGL dev (opengl32 on Windows, GL on Linux, OpenGL.framework on macOS) # - OpenGL dev (opengl32 on Windows, GL on Linux, OpenGL.framework on macOS)
# #
# Example (Linux): # Example (Linux):
# sudo apt install cmake libsdl2-dev zlib1g-dev libgl4-mesa-dev # sudo apt install cmake libsdl2-dev zlib1g-dev libgl1-mesa-dev
# Example (macOS): # Example (macOS):
# brew install cmake sdl2 zlib # brew install cmake sdl2 zlib
# Example (Windows/MSYS2): # Example (Windows/MSYS2):
+16 -2
View File
@@ -88,9 +88,23 @@ This project can compile the ROM's C code in one of two ways, controlled by the
[qemu-irix](https://github.com/n64decomp/qemu-irix/releases) user-mode emulator instead. Slower, but useful as a [qemu-irix](https://github.com/n64decomp/qemu-irix/releases) user-mode emulator instead. Slower, but useful as a
lower-risk reference if you ever suspect the recompiled toolchain is misbehaving. lower-risk reference if you ever suspect the recompiled toolchain is misbehaving.
> **The IRIX IDO binaries are not distributed with this repository.** They are
> proprietary SGI software and only ever ran on IRIX/MIPS. Neither `tools/irix/`
> nor `tools/SGIImageViewer.exe` is committed here; the **PC port does not need
> them at all** (asset extraction uses `tools/extractor`, and the port itself
> builds with CMake + your host compiler). You only need the IDO toolchain to
> build the actual **N64 ROM** or to regenerate `tools/ido5.3_recomp`. To get it:
> obtain the IDO 5.3 tree from an IRIX 5.3 installation, from
> [`decompals/ido-static-recomp`](https://github.com/decompals/ido-static-recomp)
> (which documents where its input binaries come from), or from the N64
> decompilation community, and place it at `tools/irix/root/` (with `cc` etc.
> under `tools/irix/root/usr/bin/`). `tools/SGIImageViewer.exe` is an optional
> convenience only.
The recompiled toolchain isn't checked into git — it's generated locally the first time it's needed, from the The recompiled toolchain isn't checked into git — it's generated locally the first time it's needed, from the
original IDO binaries in `tools/irix/root`. A plain `make` from the repo root builds it automatically if it's original IDO binaries in `tools/irix/root` (see the note above on obtaining those). A plain `make` from the repo
missing (wired up via `tools/Makefile`), so most people never need to run this step by hand. To build it explicitly root builds it automatically if it's missing (wired up via `tools/Makefile`), so most people never need to run
this step by hand. To build it explicitly
(e.g. to watch its own build output, or force a rebuild after changing it): (e.g. to watch its own build output, or force a rebuild after changing it):
```bash ```bash
+7 -4
View File
@@ -35,10 +35,13 @@ versions and hashes.
### Asset extraction (decompilation toolchain) ### Asset extraction (decompilation toolchain)
The extraction scripts need `binutils-mips-linux-gnu` (or an equivalent MIPS The extraction scripts need `binutils-mips-linux-gnu` (or an equivalent MIPS
binutils), `make`, `git`, `python3`, and `qemu-irix` for the IRIX IDO binutils), `make`, `git`, and `python3`. They build a small host-compiled
compiler. On Windows this is easiest under WSL or a Linux VM. Full details and `tools/extractor` and slice blobs straight out of the ROM — **no IDO / IRIX
alternatives (Docker, the recompiled IDO toolchain) are in toolchain is involved in extraction or in the PC build.** (The IDO toolchain is
[`SetupGuide.md`](SetupGuide.md). only needed to build the N64 ROM itself, and its proprietary SGI binaries are
not distributed here — see [`SetupGuide.md`](SetupGuide.md) "Recompile IDO".)
On Windows this is easiest under WSL or a Linux VM. Full details and
alternatives (Docker) are in [`SetupGuide.md`](SetupGuide.md).
--- ---
+3 -3
View File
@@ -40,14 +40,14 @@ more room.
Lewis's agents recorded generalisable IDO quirks in a learnings file; later Lewis's agents recorded generalisable IDO quirks in a learnings file; later
agents read it and did better. Our equivalent is agents read it and did better. Our equivalent is
[`porting-notes.md`](porting-notes.md) — the recurring N64->PC bug classes, [`porting-notes.md`](porting-notes.md) — the recurring N64→PC bug classes,
one screen, each entry an index into the full [`dev/findings.md`](dev/findings.md) each entry a terse index into the full [`dev/findings.md`](dev/findings.md)
log. Every investigation brief links it, and every investigation ends by log. Every investigation brief links it, and every investigation ends by
appending any new generalisable quirk. appending any new generalisable quirk.
The classes it currently tracks: The classes it currently tracks:
- pointer-width struct growth (32->64) in ROM-serialized or pun-allocated - pointer-width struct growth (32→64) in ROM-serialized or pun-allocated
structs — the dominant class; structs — the dominant class;
- 16-byte host `Gfx`/`Vtx` vs 8-byte N64 — reservation and copy sizing; - 16-byte host `Gfx`/`Vtx` vs 8-byte N64 — reservation and copy sizing;
- big-endian rodata read on a little-endian host: `f32` word-pairs, header - big-endian rodata read on a little-endian host: `f32` word-pairs, header
+18
View File
@@ -7,6 +7,24 @@ for closing **D77** (no audible music/sound on PC). Companion docs: `docs/HANDOF
--- ---
## Contents
1. [Goal and scope](#1-goal-and-scope)
2. [Current state](#2-current-state-verified-by-reading-not-assumption)
3. [The GE pipeline in one paragraph](#3-the-ge-pipeline-in-one-paragraph)
4. [How the PD port does it](#4-how-the-pd-port-does-it-ground-truth-comparison)
5. [Architecture options](#5-architecture-options-evaluate-all-recommendation-marked) — options A/B/C + sub-decisions A1–A3
6. [DMEM layout](#6-dmem-layout-ido-from-srclibultraaudiosynthinternalsh5771)
7. [Shims and ABI fixes required](#7-shims-and-abi-fixes-required) — incl. [7.1 `K0_TO_PHYS` bug](#71-bug-found-k0_to_phys-is-unshimmed-and-corrupts-pointers-on-pc)
8. [Phase 0 — recon](#8-phase-0--recon-do-first-informs-everything)
9. [Open questions](#9-open-questions-decide-before-phase-1)
10. [Phases and milestones](#10-phases-and-milestones)
11. [Verification ritual (audio-specific)](#11-verification-ritual-audio-specific-on-top-of-the-standard-one-in-agentsmd)
12. [Risks / unknowns](#12-risks--unknowns)
13. [Key references](#13-key-references)
---
## 1. Goal and scope ## 1. Goal and scope
Make GoldenEye's audio audible on the PC port with 1:1 fidelity to the N64 pipeline: Make GoldenEye's audio audible on the PC port with 1:1 fidelity to the N64 pipeline:
+3
View File
@@ -16,6 +16,9 @@ once the game is playable start-to-finish without crashes.
| ~~**D116 (HUD)**~~ | ~~proportional-font strings + ammo counter mirrored~~ | **CLOSED — NOT A BUG (M-33, §F D168).** Same capture-orientation artifact as D114. | | ~~**D116 (HUD)**~~ | ~~proportional-font strings + ammo counter mirrored~~ | **CLOSED — NOT A BUG (M-33, §F D168).** Same capture-orientation artifact as D114. |
| **D148** | Level-end cinematics don't play. Dam: hitting the exit trigger should show Bond rappelling down the dam (the bungee jump); instead it cuts straight to the mission-complete report. | Scripted cutscene / cinematic-camera + Bond rappel anim. Found M-27 during the first full Dam→Facility playthrough. Progression is unaffected — the report and next briefing load fine. **M-31 (§F D160):** static-traced the Dam end ailists (`ai_24`→`ai_17`, `camera_switch`→`CutsceneRecord` type-46 lookup). Diagnostic `GE_D160=1` shipped (`c95713f5`) — user runs Dam to the exit with it set; the trace pins whether the cutscene AI runs, and whether the propDef-index walk (D122/D132 family) hands `camera_switch` a bogus cutscene record. Leading hypothesis: propDef `sizepropdef` stride desync (medium confidence), not D75 anim-model. | | **D148** | Level-end cinematics don't play. Dam: hitting the exit trigger should show Bond rappelling down the dam (the bungee jump); instead it cuts straight to the mission-complete report. | Scripted cutscene / cinematic-camera + Bond rappel anim. Found M-27 during the first full Dam→Facility playthrough. Progression is unaffected — the report and next briefing load fine. **M-31 (§F D160):** static-traced the Dam end ailists (`ai_24`→`ai_17`, `camera_switch`→`CutsceneRecord` type-46 lookup). Diagnostic `GE_D160=1` shipped (`c95713f5`) — user runs Dam to the exit with it set; the trace pins whether the cutscene AI runs, and whether the propDef-index walk (D122/D132 family) hands `camera_switch` a bogus cutscene record. Leading hypothesis: propDef `sizepropdef` stride desync (medium confidence), not D75 anim-model. |
| **D149** | Front-end MISSION COMPLETE / mode-select 3D models (dossier, wallets) render as garbled full-screen geometry or not at all — one of the compiled sub-DLs (seg5+0x9ee4) is malformed, D146 now skips it instead of aborting. | D75 family. §F D146. | | **D149** | Front-end MISSION COMPLETE / mode-select 3D models (dossier, wallets) render as garbled full-screen geometry or not at all — one of the compiled sub-DLs (seg5+0x9ee4) is malformed, D146 now skips it instead of aborting. | D75 family. §F D146. |
| **D170** | Named-NPC "flee" scripted behaviour looks wrong on PC: on Silo, Ourumov breaks into a full run the instant he alerts ("Ourumov: Kill him!") rather than the N64 walk/retreat; developer reports Trevelyan behaves the same way on Cradle. | **Observed, not investigated** (M-34, from a Silo playtest capture; user bug report — no fix wanted yet). Could be a genuine ailist / `chrTick` divergence, OR the D155/D156 wall-clock `deltaFrames` locomotion-anim speed-up (a catch-up spike playing the walk cycle at 2–3×). **Verify first:** capture the same beat against N64 reference footage before assuming it diverges — Ourumov may be scripted to flee. If it's real, suspect the frametiming clamp (§F D155/D156) or the Cradle-family AI path (§F D123). |
| **D171** | Silo missile-shaft: a large translucent grey triangle sweeps across the lower frame while panning down the shaft (~3 s of the capture). Looks like a stray poly / near-plane clip fan, same family as D106 (portal near-plane min>max). | **Observed, not investigated** (M-34, Silo capture). Cosmetic, intermittent, tied to camera angle in the open vertical shaft. |
| **D172** | Bullet-impact / blood particle spray renders magenta or cyan instead of dark red (visible on guards hit at close range on Silo). | **Observed, not investigated** (M-34, Silo capture). A channel-order / CC-mode error in the particle-sprite path (magenta = R+B, cyan = G+B) — not the D64/D120 blood-decal family (those are crash/hang + missing decals, not colour). Likely a texture-format or env-colour decode in `blood_animation.c` / the fast3d sprite path. |
## Resolved (for reference) ## Resolved (for reference)
+4 -3
View File
@@ -1,8 +1,9 @@
# HANDOFF ARCHIVE — session-by-session narrative # HANDOFF ARCHIVE — session-by-session narrative
> **Reference only.** Current state, next task, and environment live in > **Reference only.** Current state lives in the [README](../../README.md)
> `docs/HANDOFF.md`; per-finding detail in `docs/internals.md` §F/§H > "Status" section and `docs/dev/LEVEL-STATUS.md`; per-finding detail is in
> (indexed at the top of §F). This file is the frozen accumulation of > [`findings.md`](findings.md) §F/§H (indexed at the top of §F). This file
> is the frozen accumulation of
> prior sessions' handoff briefs (through session M-11), kept so the > prior sessions' handoff briefs (through session M-11), kept so the
> reasoning behind a fix is recoverable. Everything below is as-written > reasoning behind a fix is recoverable. Everything below is as-written
> at the time and may be superseded. > at the time and may be superseded.
+53 -37
View File
@@ -1,4 +1,19 @@
# Agentic development: goal, method, timeline, assessment # Agentic development: a two-agent experiment
*A GoldenEye 007 N64→desktop port, taken from "builds a ROM" to "playable front
end" in about two weeks — driven mostly by two coding agents, a local
open-weight model and a hosted frontier model, handing work back and forth
through shared written notes under one person's direction. This is the goal,
the method, the timeline, and an honest read on what did and didn't work.*
## Contents
- [Why this project exists](#why-this-project-exists)
- [The setup](#the-setup)
- [Timeline](#timeline)
- [By the numbers](#by-the-numbers) — [Commit velocity](#commit-velocity) · [Who did what](#who-did-what)
- [The handoff workflow](#the-handoff-workflow)
- [Assessment](#assessment)
## Why this project exists ## Why this project exists
@@ -26,10 +41,10 @@ and forth** through shared written artifacts, directed by one human.
| | | | | |
|---|---| |---|---|
| Local agent | `unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL` on a single **NVIDIA RTX 5090**, driven mainly through the **[pi](https://pi.dev/)** coding agent. Unsloth Desktop (a newer local agentic-coding harness) was also trialed but not used significantly. | | Local agent | `unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL` on a single **NVIDIA RTX 5090**, driven mainly through the **[pi](https://pi.dev/)** coding agent. Unsloth Desktop (Unsloth's local model runtime, which can drive agents such as Claude Code) was also trialed but not used significantly. |
| Hosted agent | **Claude**, via **Claude Code**, on a Claude Pro subscription — mostly **Sonnet 5**, with **Opus 5** used as an escalation tier for the hardest problems and whenever there was subscription budget to spend on it | | Hosted agent | **Claude**, via **Claude Code**, on a Claude Pro subscription — mostly **Sonnet 5**, with **Opus 5** used as an escalation tier for the hardest problems and whenever there was subscription budget to spend on it |
| Human | one person: direction, work partitioning, integration, and every build / playtest / frame-capture the agents could not run | | Human | one person: direction, work partitioning, integration, and every build / playtest / frame-capture the agents could not run |
| Base | fork of the [GoldenEye 007 decompilation](https://github.com/n64decomp/007) (years of prior work by Larry Ficken / "KholdFuzion" and contributors) | | Base | fork of the [GoldenEye 007 decompilation](https://github.com/n64decomp/007) (years of prior work by Larry Ficken ("kholdfuzion") and contributors) |
| Reused | the [Perfect Dark PC port](https://github.com/fgsfdsfgs/perfect_dark)'s `fast3d` software RSP — same Rare engine family | | Reused | the [Perfect Dark PC port](https://github.com/fgsfdsfgs/perfect_dark)'s `fast3d` software RSP — same Rare engine family |
The port is the GoldenEye-specific porting work **on top of** those two The port is the GoldenEye-specific porting work **on top of** those two
@@ -56,13 +71,13 @@ gantt
OS shims, threads, fast3d integration :2026-08-21, 2d OS shims, threads, fast3d integration :2026-08-21, 2d
First rendered frames :m4, 2026-08-22, 1d First rendered frames :m4, 2026-08-22, 1d
Offline asset-conversion pipeline :2026-08-22, 2d Offline asset-conversion pipeline :2026-08-22, 2d
Entire intro renders (logos->cast) :m5, 2026-08-24, 1d Entire intro renders (logos to cast) :m5, 2026-08-24, 1d
section Both agents - handoff workflow section Both agents - handoff workflow
Claude joins :milestone, 2026-08-27, 0d Claude joins :milestone, 2026-08-27, 0d
Stage load; Bunker 1 renders + firefight :2026-08-27, 2d Stage load; Bunker 1 renders + firefight :2026-08-27, 2d
21 solo levels: load + render + no-crash :m6, 2026-08-29, 1d 21 solo levels load + render + no-crash :m6, 2026-08-29, 1d
SDL input layer (kbd/mouse/gamepad) :2026-08-29, 1d SDL input layer (kbd/mouse/gamepad) :2026-08-29, 1d
Front-end flow menu->briefing->start :m7, 2026-08-30, 1d Front-end flow (menu to briefing to start) :m7, 2026-08-30, 1d
File-backed EEPROM saves :2026-08-31, 1d File-backed EEPROM saves :2026-08-31, 1d
``` ```
@@ -75,26 +90,22 @@ gantt
- **Day 11** (27 Aug): second agent joins. - **Day 11** (27 Aug): second agent joins.
- **Day 13** (29 Aug): **all 21 solo missions load, render, and survive an - **Day 13** (29 Aug): **all 21 solo missions load, render, and survive an
unattended play window without crashing.** unattended play window without crashing.**
- **Day 14** (30–31 Aug): front end playable end to end (menu -> mission - **Day 14** (30–31 Aug): front end playable end to end (menu → mission
select -> difficulty -> briefing -> start); file-backed saves. select → difficulty → briefing → start); file-backed saves.
So roughly **two weeks**, one person part-time, to take a decompilation from So roughly **two weeks**, one person part-time, to take a decompilation from
"builds an N64 ROM" to "boots on desktop, renders every solo level, playable "builds an N64 ROM" to "boots on desktop, renders every solo level, playable
through the front end into the early game" — with audio and a set of cosmetic through the front end into the early game" — with audio and a set of cosmetic
issues still outstanding. issues still outstanding.
We are not aware of a prior Nintendo 64 native PC port developed primarily
through coding agents, or of one reaching this state on this timeline. That is
a statement about how little precedent there is, not a claim of a record.
## By the numbers ## By the numbers
| | | | | |
|---|---| |---|---|
| Calendar time | 16 days (16 Aug – 1 Sep 2026), one person part-time | | Calendar time | 16 days (16 Aug – 1 Sep 2026), one person part-time |
| Commits on the port | 217 | | Commits on the port | ~223 |
| Root-caused bugs logged | 160 (`D1`–`D167` in [`findings.md`](findings.md)) | | Root-caused bugs logged | 162 (`D1`–`D169` in [`findings.md`](findings.md); some later merged or withdrawn) |
| Handoff sessions | ~30 (`M-2` … `M-32`) | | Handoff sessions | ~33 (`M-2` … `M-33`) |
| Game-source files given `#ifdef PORT` ABI edits | 63 files, 241 blocks | | Game-source files given `#ifdef PORT` ABI edits | 63 files, 241 blocks |
| New port-layer / tooling files | 128 | | New port-layer / tooling files | 128 |
| Port layer | ~17,000 lines C/C++ (`port/`) | | Port layer | ~17,000 lines C/C++ (`port/`) |
@@ -108,20 +119,24 @@ xychart-beta
title "Commits per day" title "Commits per day"
x-axis ["8/16", "8/17", "8/20", "8/21", "8/22", "8/23", "8/24", "8/27", "8/28", "8/29", "8/30", "8/31", "9/1"] x-axis ["8/16", "8/17", "8/20", "8/21", "8/22", "8/23", "8/24", "8/27", "8/28", "8/29", "8/30", "8/31", "9/1"]
y-axis "commits" 0 --> 60 y-axis "commits" 0 --> 60
bar [1, 2, 2, 6, 9, 2, 4, 7, 57, 39, 39, 46, 3] bar [1, 2, 2, 6, 9, 2, 4, 7, 57, 39, 39, 46, 9]
``` ```
The 8/25–8/26 gap is between phases; the jump on 8/28 is the second agent Days with no commits are omitted. The 8/25–8/26 gap is between phases; the
joining, plus the parallel multi-agent "bursts" used near the end. step up from 8/28 onward is the collaborative phase in full swing, including
the parallel multi-agent "bursts" used near the end.
### Who did what ### Who did what
```mermaid ```mermaid
pie showData title "Commits by phase" pie showData title "Commits by agent (raw count)"
"Phase A - local model, solo (16-24 Aug)" : 26 "Claude" : 161
"Phase B - collaborative (27 Aug-1 Sep)" : 191 "Local model (Qwen 3.8 / pi)" : 62
``` ```
(Phase A — the first 26 commits, to 24 Aug — was entirely the local model,
solo; from 27 Aug on the two agents worked in parallel.)
| Milestone / workstream | Primary agent | Weight | | Milestone / workstream | Primary agent | Weight |
|---|---|---| |---|---|---|
| PC build system, region macros, full compile + link of ~230 units | local model | large | | PC build system, region macros, full compile + link of ~230 units | local model | large |
@@ -130,7 +145,7 @@ pie showData title "Commits by phase"
| Offline asset-conversion architecture + first converters (`tools_pc/`) | local model | large | | Offline asset-conversion architecture + first converters (`tools_pc/`) | local model | large |
| Intro rendering (logos → gun-barrel → cast) | local model | medium | | Intro rendering (logos → gun-barrel → cast) | local model | medium |
| Stage load unblocked (`D69`–`D87`) | Claude | medium | | Stage load unblocked (`D69`–`D87`) | Claude | medium |
| 21-level crash sweep — ~12 crash classes root-caused (`D88`–`D167`) | Claude | large | | 21-level crash sweep — ~12 crash classes root-caused (`D88`–`D169`) | Claude | large |
| SDL input layer (keyboard / mouse / gamepad, mouse-look) | Claude | medium | | SDL input layer (keyboard / mouse / gamepad, mouse-look) | Claude | medium |
| Front-end flow (menu → briefing → start), EEPROM saves | Claude | medium | | Front-end flow (menu → briefing → start), EEPROM saves | Claude | medium |
| Parallel struct-layout / converter static audits | local model | medium | | Parallel struct-layout / converter static audits | local model | medium |
@@ -138,14 +153,15 @@ pie showData title "Commits by phase"
| The hardest structural bugs (matrix handedness, format specs) | Claude | — | | The hardest structural bugs (matrix handedness, format specs) | Claude | — |
| Every build, playtest, frame capture, integration, and direction | human | — | | Every build, playtest, frame capture, integration, and direction | human | — |
**Estimated effort split.** By raw commit count it is ~28% local model / **Estimated effort split.** The raw commit count above (~28% local / ~72%
~72% Claude (Phase A entirely local, ~15–20% of Phase B local). Weighting by Claude) undercounts the local model: Phase A landed the build system and boot
milestone difficulty rather than commit count — the foundation the local model chain in relatively few, large commits, and the local model kept contributing
built is a heavier third of the project than its commit count suggests — the ~15–20% of Phase B in parallel. Weighting by milestone difficulty rather than
developer's estimate is roughly: raw commits — the foundation is a heavier third of the project than its commit
share suggests — the developer's estimate is roughly:
```mermaid ```mermaid
pie showData title "Estimated agent effort (milestone-weighted)" pie showData title "Agent effort, milestone-weighted"
"Claude" : 60 "Claude" : 60
"Local model (Qwen 3.8 / pi)" : 40 "Local model (Qwen 3.8 / pi)" : 40
``` ```
@@ -163,8 +179,8 @@ This is the part worth paying attention to.
```mermaid ```mermaid
flowchart LR flowchart LR
H[Human: direction, integration,<br/>build + playtest verification] H["Human: direction, integration,<br/>build + playtest verification"]
C[Claude / Claude Code<br/>frontier, hosted] C["Claude / Claude Code<br/>frontier, hosted"]
Q["Qwen 3.8 via pi<br/>open-weight, local RTX 5090"] Q["Qwen 3.8 via pi<br/>open-weight, local RTX 5090"]
D[(Shared artifacts:<br/>HANDOFF.md · findings.md · porting-notes.md)] D[(Shared artifacts:<br/>HANDOFF.md · findings.md · porting-notes.md)]
@@ -172,10 +188,10 @@ flowchart LR
H -->|scopes task, budget, files| Q H -->|scopes task, budget, files| Q
C <-->|reads / appends| D C <-->|reads / appends| D
Q <-->|reads / appends| D Q <-->|reads / appends| D
C -.->|usage limit reached ->| Q C -.->|usage limit reached| Q
Q -.->|hard structural bug ->| C Q -.->|hard structural bug| C
C -->|patch + writeup| H C -->|patch + write-up| H
Q -->|patch + writeup| H Q -->|patch + write-up| H
``` ```
Both agents worked against the **same three written artifacts**, which is what Both agents worked against the **same three written artifacts**, which is what
@@ -187,12 +203,12 @@ let them substitute for each other:
usage limit mid-problem, the local model picked the task up from the usage limit mid-problem, the local model picked the task up from the
HANDOFF state and continued; when the local model hit a bug that needed HANDOFF state and continued; when the local model hit a bug that needed
deeper structural reasoning, it wrote up where it was and Claude took over. deeper structural reasoning, it wrote up where it was and Claude took over.
2. **`findings.md`** — the chronological finding log. 160 numbered entries, 2. **`findings.md`** — the chronological finding log. 162 numbered entries,
each a root cause with `file:line` evidence and the fix. New agents (either each a root cause with `file:line` evidence and the fix. New agents (either
model) are pointed at the relevant entries before they start. model) are pointed at the relevant entries before they start.
3. **`porting-notes.md`** — the append-only "recurring bug classes" file. The 3. **`porting-notes.md`** — the append-only "recurring bug classes" file. The
single highest-leverage artifact: it stopped both models from single highest-leverage artifact: it stopped both models from
re-deriving the same class of N64->PC bug over and over. re-deriving the same class of N64→PC bug over and over.
Around these, the working rules (full detail in Around these, the working rules (full detail in
[`../dev-process.md`](../dev-process.md)): [`../dev-process.md`](../dev-process.md)):
@@ -200,7 +216,7 @@ Around these, the working rules (full detail in
- **file-partitioned tasks** — each agent's task scoped to a disjoint set of - **file-partitioned tasks** — each agent's task scoped to a disjoint set of
files so patches never collided; files so patches never collided;
- **visible budgets** — every investigation task carried an explicit - **visible budgets** — every investigation task carried an explicit
"N build->run cycles" limit and a defined fallback (revert probes, write up "N build→run cycles" limit and a defined fallback (revert probes, write up
with a confidence rating); with a confidence rating);
- **the human owns verification** — building, running the game, capturing a - **the human owns verification** — building, running the game, capturing a
frame, and judging it against N64 reference footage was never delegated. frame, and judging it against N64 reference footage was never delegated.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

+21
View File
@@ -17,6 +17,27 @@ platforms.
--- ---
## Contents
1. [Executive summary](#1-executive-summary)
2. [What the PD port actually does (the reference architecture)](#2-what-the-pd-port-actually-does-the-reference-architecture)
— [2.1 Emulate the RSP, bypass the RDP](#21-the-key-architectural-insight-emulate-the-rsp-bypass-the-rdp)
· [2.2 How the RSP is invoked](#22-how-the-rsp-is-invoked)
· [2.3 Build system](#23-build-system)
· [2.4 PD-port copy-candidate audit](#24-pd-port-copy-candidate-audit-session-2026-08-22)
3. [GoldenEye decomp: what we're porting](#3-goldeneye-decomp-what-were-porting)
— [3.1 Entry / main loop](#31-entry--main-loop)
· [3.2 The two libultra trees](#32-the-two-libultra-trees-srclibultra-and-srclibultrare)
4. [N64 hardware surfaces that must be shimmed](#4-n64-hardware-surfaces-that-must-be-shimmed)
5. [GE-specific graphics differences vs PD (the RSP work)](#5-ge-specific-graphics-differences-vs-pd-the-rsp-work)
6. [Audio](#6-audio)
7. [Input & saves](#7-input--saves)
8. [Recommended plan](#8-recommended-plan) — phases 0–4
9. [Open questions / risks](#9-open-questions--risks)
10. [References](#10-references)
---
## 1. Executive summary ## 1. Executive summary
* **Feasibility: HIGH.** GoldenEye and Perfect Dark share the same Rare * **Feasibility: HIGH.** GoldenEye and Perfect Dark share the same Rare
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

+20 -4
View File
@@ -1,13 +1,29 @@
# Porting notes — recurring N64→PC bug classes # Porting notes — recurring N64→PC bug classes
A one-screen field guide to the bug classes that keep recurring when running A field guide to the bug classes that keep recurring when running big-endian
big-endian 32-bit N64 game code, unmodified, on a little-endian 64-bit host. 32-bit N64 game code, unmodified, on a little-endian 64-bit host. Terse by
Each entry cites a `Dxx` label; the full evidence and fix for that instance design — each entry compresses a full investigation to a symptom, a fix, and a
live in [`dev/findings.md`](dev/findings.md) under the same label. grep heuristic for finding siblings. Each entry cites a `Dxx` label; the full
evidence and fix for that instance live in [`dev/findings.md`](dev/findings.md)
under the same label. Skim the section headers; read the classes relevant to
the task at hand.
If you are debugging a crash in this port, read this first — the odds are If you are debugging a crash in this port, read this first — the odds are
good that you are looking at one of these. good that you are looking at one of these.
## Contents
- [A. Pointer-width struct growth (32→64) — the dominant class](#a-pointer-width-struct-growth-3264--the-dominant-class)
- [B. 16-byte PC `Gfx` / `Vtx` vs 8-byte N64](#b-16-byte-pc-gfx--vtx-vs-8-byte-n64)
- [C. Big-endian rodata / ROM data read on little-endian PC](#c-big-endian-rodata--rom-data-read-on-little-endian-pc)
- [C2. Port-layer / SDL shims](#c2-port-layer--sdl-shims)
- [D. N64 hardware idioms fast3d does not emulate](#d-n64-hardware-idioms-fast3d-does-not-emulate)
- [D2. The HUD/model "X-mirror" — RESOLVED](#d2-the-hudmodel-x-mirror-d114d116--resolved-it-was-an-upside-down-capture)
- [D3. GCC/mingw makes an all-non-negative `enum` UNSIGNED](#d3-gccmingw-makes-an-all-non-negative-enum-unsigned)
- [D4. N64 "interrupts off" must be a real lock on PC](#d4-n64-interrupts-off-is-not-free-on-pc--it-must-be-a-real-lock)
- [D5. Loop bounds that assume linker adjacency of two globals](#d5-loop-bounds-that-assume-linker-adjacency-of-two-file-scope-globals)
- [E. Process / method notes](#e-process--method-notes)
## A. Pointer-width struct growth (32→64) — the dominant class ## A. Pointer-width struct growth (32→64) — the dominant class
A decomp struct with pointer fields, or one pun-allocated into a fixed A decomp struct with pointer fields, or one pun-allocated into a fixed