diff --git a/.gitattributes b/.gitattributes index 290ad9d0..a546dd49 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,8 @@ * text=auto eol=lf *.png binary *.jpg binary +*.gif binary +*.mp4 binary *.z64 binary *.exe binary *.bin binary diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..1c0d8950 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -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 diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..2edadabd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -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. diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000..5901c13f --- /dev/null +++ b/.github/SECURITY.md @@ -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 +(). + +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. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..e5c49c41 --- /dev/null +++ b/.github/dependabot.yml @@ -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 diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 00000000..7f260a01 --- /dev/null +++ b/.github/labels.yml @@ -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. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..193c3394 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,37 @@ + + +## What this changes + + + +## Why + + + +## 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 + + + +- [ ] `./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: + +## Notes for the reviewer + + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f73047bc..ffa2c51b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,26 +2,43 @@ name: CI on: push: - branches: [ master ] + branches: [ main, master ] paths-ignore: [ '**.md', 'docs/**', 'LICENSE', 'NOTICE' ] pull_request: + paths-ignore: [ '**.md', 'docs/**', 'LICENSE', 'NOTICE' ] workflow_dispatch: -# The full port build needs assets extracted from a copyrighted ROM, which CI -# does not have. This job validates everything that does NOT depend on those -# assets: the PC-port tooling, the generated ROM-asset symbol files, and a -# CMake configure of all three regions (which checks REGION_DEFS, the source -# list, and that SDL2 / zlib / OpenGL are discoverable). +# Minimal token: CI only reads the repo and uploads build artifacts, neither of +# which needs write access. Fork PRs run untrusted build scripts on the runner, +# so keep the granted scope as small as possible and never expose secrets here. +permissions: + 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 -# it running on ubuntu is NOT a statement that the port builds or works on -# Linux — it has only ever been built and tested on Windows (MSYS2). +# validate — ubuntu, configure-only. Byte-compiles the tooling, +# regenerates the US ROM-asset symbol file, and CMake- +# 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: validate: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Install dependencies run: | @@ -31,17 +48,61 @@ jobs: - name: Byte-compile Python tooling 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: | 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 - - name: CMake configure (all regions) - run: | - for r in ntsc-final pal-final jpn-final; do - echo "::group::configure $r" - cmake -S . -B "build-$r" -DROMID="$r" - echo "::endgroup::" - done + - name: CMake configure (ntsc-final) + run: cmake -S . -B build-ntsc -DROMID=ntsc-final + + # Real Windows (MSYS2 MINGW64) build — the only platform the port is + # developed and tested on. This compiles and LINKS the full executable. + # + # 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_.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. diff --git a/.gitignore b/.gitignore index 30fe2601..eb65ba94 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,12 @@ ge007.ini !build/test.c !notes/StyleGuide.md #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/extractor tools/aaa_rip/main.o @@ -117,7 +123,6 @@ assets/obseg/em/data/under.seg scripts/local/ scripts/make/local/ -scripts/__pycache__/generate_prop_model_c.cpython-310.pyc # PC port debug/session artifacts _run.log diff --git a/AGENTS.md b/AGENTS.md index 76fa8ee9..9729eb3d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,8 +4,8 @@ - `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). -- **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. -- **Current status:** the README "Status" section. Current task + environment: `docs/HANDOFF.md` (a rolling local working file). +- **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, 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. ## 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 parked in `docs/dev/GRAPHICS-BACKLOG.md`. - **Phase 3 (audio + input):** input layer done (`port/src/input.c`); polish - bugs open (D118*, D169). Audio not started — libaudio → SDL, copy-and-adapt - from the PD port's `mixer.c`. + bugs open (D118* mouse-look residuals; interactive feel-checks owed). Audio + not started — libaudio → SDL, copy-and-adapt from the PD port's `mixer.c`. - **Phase 4 (saves + polish):** file-backed EEPROM done; widescreen, config, rebinding UI outstanding. diff --git a/CLAUDE.md b/CLAUDE.md index 078dadb9..6888f20a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 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 local working file; may be absent in a fresh clone, in which case read - the README "Status" section instead), - `docs/porting-notes.md` (recurring bug classes). + the README "Status" section instead) — read fully; + `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:** - - `docs/internals.md` — architecture / RSP deltas / phased plan (§1–§10 - of the old research doc). Read the section you need. - - `docs/dev/findings.md` — the `Dxx` finding log (§11 + §F + §H). + - `docs/internals.md` — architecture / RSP deltas / phased plan (§1–§10). + Read the section you need. + - `docs/dev/findings.md` — the `Dxx` finding log (§F + §H). **Jump to a specific `Dxx` via the index at the top of §F.** Never linear-read. - `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. 1. Read the Tier 1 docs: `docs/HANDOFF.md` (immediate task, standing - procedure, environment gotchas) and `docs/porting-notes.md` - (recurring bug classes — you will re-derive catalogued bugs if you don't). + procedure, environment gotchas — or the README "Status" section if it is + 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. 3. If you may dispatch a subagent this session, read `docs/dev-process.md` NOW — not at dispatch time. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 537e76a4..46a76632 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 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 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 @@ -35,6 +35,6 @@ keep the port faithful to the original game. ## Where to look - `docs/internals.md` — how the port is structured. -- `docs/porting-notes.md` — the recurring bug classes; check here before - debugging a crash, you are likely looking at a known pattern. +- `docs/porting-notes.md` — the recurring bug classes. Check here before + debugging a crash; you are likely looking at a known pattern. - `docs/dev/` — the full finding log and per-level status. diff --git a/README.md b/README.md index b045262e..e10d0975 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # 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 desktop platforms, built on top of the [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, timers, save storage) is shimmed in a dedicated `port/` layer. +> [!IMPORTANT] > **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 > playable game — see [Requirements](#requirements) and [Legal](#legal).

- Archives level rendering in the port - Bunker 1 rendering in the port -
- Guards in the Archives level - Bunker 1 with HUD - Bunker 1 storage room -
In-engine captures — Archives and Bunker 1 running in the port. + Bunker 1 intro camera + ~15 s of the port running: mission dossier, Facility, Silo, Jungle, Archives + Dam intro camera +
In-engine, running in the port — Bunker 1 and Dam attract views, and a + ~15 s clip (no audio yet, Phase 3): mission dossier → Facility → Silo → + Jungle → Archives.

-> **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. +## Contents + +- [Background](#background) +- [Status](#status) +- [Requirements](#requirements) +- [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 @@ -55,33 +67,42 @@ It used two agents: The two **handed work back and forth** through shared written artifacts: ```mermaid -flowchart LR - H["human
direction · integration
build + playtest"] +flowchart TD + H["human
direction · integration · playtest"] C["Claude
(Claude Code)"] Q["Qwen 3.8
(pi, local RTX 5090)"] - D[("shared artifacts
finding log · bug-class notes · handoff doc")] + D[("shared artifacts
findings · notes · handoff doc")] H -->|"scoped task + budget"| C H -->|"scoped task + budget"| Q - C <-->|read / append| D - Q <-->|read / append| D - C -.->|"hit usage limit ->"| Q - Q -.->|"needs deeper reasoning ->"| C - C -->|"patch + write-up"| H - Q -->|"patch + write-up"| H + C -->|"patch + write-up"| D + Q -->|"patch + write-up"| D + C <-.->|handoff| Q + D --> H ``` The handoff document was originally a session-to-session note; it became the **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. -**By the numbers:** ~2 weeks, one person part-time · 217 commits · 160 -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 -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 -day 14 the front end was playable end to end. Estimated effort split -(milestone-weighted): **~60% Claude / ~40% local model** — the local model -built the entire foundation (build, boot, RSP wiring, converters). +**By the numbers:** + +| Metric | Value | +|---|---| +| Timeline | ~2 weeks, one person part-time | +| Commits | ~223 | +| Root-caused bugs logged | 162 (`D1`–`D169`; some later merged or withdrawn) | +| 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": [`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 +> [!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 the front end into the early game. It is not finished and it is not stable. **Working** -- Boot -> Rare/Nintendo logos -> gun-barrel -> cast intro, fully rendered. -- Front end: main menu -> mission select -> difficulty -> briefing -> mission start. +- Boot → Rare/Nintendo logos → gun-barrel → cast intro, fully rendered. +- Front end: main menu → mission select → difficulty → briefing → mission start. - **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)). - 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** - **Audio** — not implemented (Phase 3). The game runs silent. -- Front-end 3D models (spinning Nintendo logo, gun-barrel Bond, cast) are - mispositioned or absent. +- Some front-end 3D models — the spinning Nintendo logo, and the MISSION + 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 conversions) are tracked in [`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 ``` -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 @@ -187,16 +218,16 @@ Configuration is written to `ge007.ini` on first run. ### Default controls -| Action | Keyboard / mouse | Controller | -|-------------------|-------------------------|-----------------------| -| Move / strafe | `W` `A` `S` `D` / arrows | Left stick | -| Aim / look | Mouse | Right stick | -| Fire (Z) | Left mouse / `LCtrl` | Right trigger | -| Aim mode (R) | Right mouse / `LShift` | Left trigger | -| Use / accept (A) | `Space` / `E` | A / X | -| Reload / cancel (B)| `R` / `F` | B / Y / RB | -| L trigger | `Q` | LB | -| Start | `Enter` / `Tab` | Start | +| Action | Keyboard / mouse | Controller | +|---------------------|--------------------------|---------------| +| Move / strafe | `W` `A` `S` `D` / arrows | Left stick | +| Aim / look | Mouse | Right stick | +| Fire (Z) | Left mouse / `LCtrl` | Right trigger | +| Aim mode (R) | Right mouse / `LShift` | Left trigger | +| Use / accept (A) | `Space` / `E` / `X` | A / X | +| Reload / cancel (B) | `R` / `F` | B / Y / RB | +| L trigger | `Q` | LB | +| Start | `Enter` / `Tab` | Start | Mouse sensitivity, Y-inversion and the aim/turn split are tunable in the `[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 / 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 change no behaviour and are documented individually. @@ -244,21 +275,15 @@ docs/ see below ## Documentation -- [`docs/building.md`](docs/building.md) — full build + asset-extraction guide. -- [`docs/internals.md`](docs/internals.md) — architecture, the RSP-emulation - approach, GE-vs-PD engine differences, the phased plan. -- [`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 - research angle: the two-agent setup, timeline, handoff workflow, and a - candid assessment of what did and didn't work. -- [`docs/dev-process.md`](docs/dev-process.md) — the investigation workflow in - 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. +| Doc | What's in it | +|---|---| +| [`docs/building.md`](docs/building.md) | Full build + asset-extraction guide. | +| [`docs/internals.md`](docs/internals.md) | Architecture, the RSP-emulation approach, GE-vs-PD engine differences, the phased plan. | +| [`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 research angle: the two-agent setup, timeline, handoff workflow, and an assessment of what did and didn't work. | +| [`docs/dev-process.md`](docs/dev-process.md) | The investigation workflow in 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 @@ -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** - 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 is a fork of that repository. - 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** -- [Qwen 3.8](https://github.com/QwenLM/Qwen) (Alibaba Qwen team); - [Unsloth](https://unsloth.ai) (the GGUF quantisation and Unsloth Desktop). +- Qwen 3.8 (Alibaba Qwen team), run locally as the + [`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. - [Claude / Claude Code](https://claude.com/claude-code) (Anthropic). diff --git a/build-pc.sh b/build-pc.sh index 9110d42d..8f71030f 100644 --- a/build-pc.sh +++ b/build-pc.sh @@ -5,14 +5,14 @@ # Usage: # ./build-pc.sh [ntsc-final|pal-final|jpn-final] # -# Dependencies (see docs/internals.md): +# Dependencies (see docs/building.md): # - CMake >= 3.16 # - SDL2 dev # - zlib dev # - OpenGL dev (opengl32 on Windows, GL on Linux, OpenGL.framework on macOS) # # 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): # brew install cmake sdl2 zlib # Example (Windows/MSYS2): diff --git a/docs/SetupGuide.md b/docs/SetupGuide.md index 1688aa53..7b5177b0 100644 --- a/docs/SetupGuide.md +++ b/docs/SetupGuide.md @@ -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 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 -original IDO binaries in `tools/irix/root`. A plain `make` from the repo 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 +original IDO binaries in `tools/irix/root` (see the note above on obtaining those). A plain `make` from the repo +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): ```bash diff --git a/docs/building.md b/docs/building.md index f72da027..85a6f61e 100644 --- a/docs/building.md +++ b/docs/building.md @@ -35,10 +35,13 @@ versions and hashes. ### Asset extraction (decompilation toolchain) The extraction scripts need `binutils-mips-linux-gnu` (or an equivalent MIPS -binutils), `make`, `git`, `python3`, and `qemu-irix` for the IRIX IDO -compiler. On Windows this is easiest under WSL or a Linux VM. Full details and -alternatives (Docker, the recompiled IDO toolchain) are in -[`SetupGuide.md`](SetupGuide.md). +binutils), `make`, `git`, and `python3`. They build a small host-compiled +`tools/extractor` and slice blobs straight out of the ROM — **no IDO / IRIX +toolchain is involved in extraction or in the PC build.** (The IDO toolchain is +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). --- diff --git a/docs/dev-process.md b/docs/dev-process.md index ad368fcc..1aeefec2 100644 --- a/docs/dev-process.md +++ b/docs/dev-process.md @@ -40,14 +40,14 @@ more room. Lewis's agents recorded generalisable IDO quirks in a learnings file; later agents read it and did better. Our equivalent is -[`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) +[`porting-notes.md`](porting-notes.md) — the recurring N64→PC bug classes, +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 appending any new generalisable quirk. 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; - 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 diff --git a/docs/dev/AUDIO-PLAN.md b/docs/dev/AUDIO-PLAN.md index eeb4da6a..8f12da69 100644 --- a/docs/dev/AUDIO-PLAN.md +++ b/docs/dev/AUDIO-PLAN.md @@ -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 Make GoldenEye's audio audible on the PC port with 1:1 fidelity to the N64 pipeline: diff --git a/docs/dev/GRAPHICS-BACKLOG.md b/docs/dev/GRAPHICS-BACKLOG.md index 18e6c819..12a6a22f 100644 --- a/docs/dev/GRAPHICS-BACKLOG.md +++ b/docs/dev/GRAPHICS-BACKLOG.md @@ -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. | | **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. | +| **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) diff --git a/docs/dev/HANDOFF-ARCHIVE.md b/docs/dev/HANDOFF-ARCHIVE.md index cb51a5bb..109fb7e0 100644 --- a/docs/dev/HANDOFF-ARCHIVE.md +++ b/docs/dev/HANDOFF-ARCHIVE.md @@ -1,8 +1,9 @@ # HANDOFF ARCHIVE — session-by-session narrative -> **Reference only.** Current state, next task, and environment live in -> `docs/HANDOFF.md`; per-finding detail in `docs/internals.md` §F/§H -> (indexed at the top of §F). This file is the frozen accumulation of +> **Reference only.** Current state lives in the [README](../../README.md) +> "Status" section and `docs/dev/LEVEL-STATUS.md`; per-finding detail is in +> [`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 > reasoning behind a fix is recoverable. Everything below is as-written > at the time and may be superseded. diff --git a/docs/dev/agentic-development.md b/docs/dev/agentic-development.md index 76c04bf2..5c61e2a4 100644 --- a/docs/dev/agentic-development.md +++ b/docs/dev/agentic-development.md @@ -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 @@ -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 | | 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 | 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 First rendered frames :m4, 2026-08-22, 1d 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 Claude joins :milestone, 2026-08-27, 0d 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 - 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 ``` @@ -75,26 +90,22 @@ gantt - **Day 11** (27 Aug): second agent joins. - **Day 13** (29 Aug): **all 21 solo missions load, render, and survive an unattended play window without crashing.** -- **Day 14** (30–31 Aug): front end playable end to end (menu -> mission - select -> difficulty -> briefing -> start); file-backed saves. +- **Day 14** (30–31 Aug): front end playable end to end (menu → mission + select → difficulty → briefing → start); file-backed saves. 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 through the front end into the early game" — with audio and a set of cosmetic 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 | | | |---|---| | Calendar time | 16 days (16 Aug – 1 Sep 2026), one person part-time | -| Commits on the port | 217 | -| Root-caused bugs logged | 160 (`D1`–`D167` in [`findings.md`](findings.md)) | -| Handoff sessions | ~30 (`M-2` … `M-32`) | +| Commits on the port | ~223 | +| Root-caused bugs logged | 162 (`D1`–`D169` in [`findings.md`](findings.md); some later merged or withdrawn) | +| Handoff sessions | ~33 (`M-2` … `M-33`) | | Game-source files given `#ifdef PORT` ABI edits | 63 files, 241 blocks | | New port-layer / tooling files | 128 | | Port layer | ~17,000 lines C/C++ (`port/`) | @@ -108,20 +119,24 @@ xychart-beta 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"] 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 -joining, plus the parallel multi-agent "bursts" used near the end. +Days with no commits are omitted. The 8/25–8/26 gap is between phases; the +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 ```mermaid -pie showData title "Commits by phase" - "Phase A - local model, solo (16-24 Aug)" : 26 - "Phase B - collaborative (27 Aug-1 Sep)" : 191 +pie showData title "Commits by agent (raw count)" + "Claude" : 161 + "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 | |---|---|---| | 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 | | Intro rendering (logos → gun-barrel → cast) | local model | 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 | | Front-end flow (menu → briefing → start), EEPROM saves | Claude | 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 | — | | Every build, playtest, frame capture, integration, and direction | human | — | -**Estimated effort split.** By raw commit count it is ~28% local model / -~72% Claude (Phase A entirely local, ~15–20% of Phase B local). Weighting by -milestone difficulty rather than commit count — the foundation the local model -built is a heavier third of the project than its commit count suggests — the -developer's estimate is roughly: +**Estimated effort split.** The raw commit count above (~28% local / ~72% +Claude) undercounts the local model: Phase A landed the build system and boot +chain in relatively few, large commits, and the local model kept contributing +~15–20% of Phase B in parallel. Weighting by milestone difficulty rather than +raw commits — the foundation is a heavier third of the project than its commit +share suggests — the developer's estimate is roughly: ```mermaid -pie showData title "Estimated agent effort (milestone-weighted)" +pie showData title "Agent effort, milestone-weighted" "Claude" : 60 "Local model (Qwen 3.8 / pi)" : 40 ``` @@ -163,8 +179,8 @@ This is the part worth paying attention to. ```mermaid flowchart LR - H[Human: direction, integration,
build + playtest verification] - C[Claude / Claude Code
frontier, hosted] + H["Human: direction, integration,
build + playtest verification"] + C["Claude / Claude Code
frontier, hosted"] Q["Qwen 3.8 via pi
open-weight, local RTX 5090"] D[(Shared artifacts:
HANDOFF.md · findings.md · porting-notes.md)] @@ -172,10 +188,10 @@ flowchart LR H -->|scopes task, budget, files| Q C <-->|reads / appends| D Q <-->|reads / appends| D - C -.->|usage limit reached ->| Q - Q -.->|hard structural bug ->| C - C -->|patch + writeup| H - Q -->|patch + writeup| H + C -.->|usage limit reached| Q + Q -.->|hard structural bug| C + C -->|patch + write-up| H + Q -->|patch + write-up| H ``` 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 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. -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 model) are pointed at the relevant entries before they start. 3. **`porting-notes.md`** — the append-only "recurring bug classes" file. The 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 [`../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 files so patches never collided; - **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); - **the human owns verification** — building, running the game, capturing a frame, and judging it against N64 reference footage was never delegated. diff --git a/docs/img/archives-1.png b/docs/img/archives-1.png deleted file mode 100644 index 96052755..00000000 Binary files a/docs/img/archives-1.png and /dev/null differ diff --git a/docs/img/archives-2.png b/docs/img/archives-2.png deleted file mode 100644 index 806909d6..00000000 Binary files a/docs/img/archives-2.png and /dev/null differ diff --git a/docs/img/attract-silo.png b/docs/img/attract-silo.png deleted file mode 100644 index 21666ff2..00000000 Binary files a/docs/img/attract-silo.png and /dev/null differ diff --git a/docs/img/bunker1-1.png b/docs/img/bunker1-1.png deleted file mode 100644 index 682726a3..00000000 Binary files a/docs/img/bunker1-1.png and /dev/null differ diff --git a/docs/img/bunker1-2.png b/docs/img/bunker1-2.png deleted file mode 100644 index dc7c7a0c..00000000 Binary files a/docs/img/bunker1-2.png and /dev/null differ diff --git a/docs/img/bunker1-3.png b/docs/img/bunker1-3.png deleted file mode 100644 index 4a6c99ae..00000000 Binary files a/docs/img/bunker1-3.png and /dev/null differ diff --git a/docs/internals.md b/docs/internals.md index 767c7c1b..3e07f7db 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -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 * **Feasibility: HIGH.** GoldenEye and Perfect Dark share the same Rare diff --git a/docs/media/goldeneye-demo.gif b/docs/media/goldeneye-demo.gif new file mode 100644 index 00000000..b5a6237a Binary files /dev/null and b/docs/media/goldeneye-demo.gif differ diff --git a/docs/porting-notes.md b/docs/porting-notes.md index 9617910c..0e4aeaa1 100644 --- a/docs/porting-notes.md +++ b/docs/porting-notes.md @@ -1,13 +1,29 @@ # Porting notes — recurring N64→PC bug classes -A one-screen field guide to the bug classes that keep recurring when running -big-endian 32-bit N64 game code, unmodified, on a little-endian 64-bit host. -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. +A field guide to the bug classes that keep recurring when running big-endian +32-bit N64 game code, unmodified, on a little-endian 64-bit host. Terse by +design — each entry compresses a full investigation to a symptom, a fix, and a +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 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 decomp struct with pointer fields, or one pun-allocated into a fixed diff --git a/scripts/__pycache__/generate_prop_model_c.cpython-312.pyc b/scripts/__pycache__/generate_prop_model_c.cpython-312.pyc deleted file mode 100644 index 55ec2665..00000000 Binary files a/scripts/__pycache__/generate_prop_model_c.cpython-312.pyc and /dev/null differ diff --git a/scripts/__pycache__/generate_prop_model_c.cpython-38.pyc b/scripts/__pycache__/generate_prop_model_c.cpython-38.pyc deleted file mode 100644 index c7d78378..00000000 Binary files a/scripts/__pycache__/generate_prop_model_c.cpython-38.pyc and /dev/null differ