From 1ca37b3d87ade7d6a59705ea9026599ff5e88823 Mon Sep 17 00:00:00 2001 From: Matthew Stanley <1379tech@gmail.com> Date: Thu, 9 Jul 2026 22:36:57 -0700 Subject: [PATCH] docs: merge contributor-facing CONTRIBUTING guidance + README section Fold the best of a generic CONTRIBUTING draft into the architecture-aware one: AI-assisted-and-human contribution rules, a concrete cross-game regression checklist (boot/attract/save/load/gameplay), an expanded no-copyrighted-assets list, and bug-report/PR templates tuned to this project's execution paths (LLE / HLE / dirty-RAM interp; SW/GL/VK). Add a "Framework changes and the pin" section describing how a framework fix reaches a game through its submodule pointer (source of truth; some older repos still carry psxrecomp-v4.pin as a human-readable record), and whether consuming it needs a pin bump / regen. Add a dedicated Contributing section to the README linking CONTRIBUTING.md. Co-Authored-By: Claude Opus 4.8 (1M context) --- CONTRIBUTING.md | 168 +++++++++++++++++++++++++++++++++++++++++++++--- README.md | 15 +++++ 2 files changed, 173 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be8444fe..06fbe1c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,8 @@ Thanks for your interest! PSXRecomp is a static recompiler, not an emulator, and it holds itself to a high correctness bar. This guide covers how the project is organized, the rules that keep it faithful, and how to get a change merged. +Contributions are welcome — AI-assisted or not — as long as they are reviewed, +tested, and keep the core game-agnostic. New to the codebase? Read [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) and [`docs/EXECUTION_MODEL.md`](docs/EXECUTION_MODEL.md) first, then @@ -13,13 +15,21 @@ New to the codebase? Read [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) and - **`mstan/psxrecomp`** (this repo) — the framework: the recompiler tool (`recompiler/`), the runtime engine (`runtime/`), shared tools, and docs. Framework changes go here. -- **Per-game repos** (`mstan/TombaRecomp`, `mstan/MegaManX6Recomp`, …) — one per - title. Each contains only that game's config, seeds, and build glue and links - this framework in as a submodule at `psxrecomp/`. Game-specific work goes in - the game repo; nothing game-specific belongs in the framework. +- **Per-game repos** (`mstan/TombaRecomp`, `mstan/MegaManX6Recomp`, + `mstan/ApeEscapeRecomp`, …) — one per title. Each contains only that game's + config, seeds, and build glue and links this framework in as a submodule at + `psxrecomp/`. Game-specific work goes in the game repo; nothing game-specific + belongs in the framework. -See [Linking the framework](docs/BUILDING.md#linking-the-framework) for the -submodule + local-junction dev setup. +Each game repo pins an **exact framework commit** — the git submodule pointer at +`psxrecomp/` (some older game repos also carry a human-readable `psxrecomp-v4.pin` +record; the submodule pointer is the source of truth). The framework evolves on +its own cadence; a game only moves to a newer framework when someone deliberately +bumps that submodule pointer. See +[Linking the framework](docs/BUILDING.md#linking-the-framework) for the submodule ++ local-junction dev setup, and +[Framework changes and the pin](#framework-changes-and-the-pin) below for how a +framework change actually reaches a game. ## The core rules @@ -30,15 +40,18 @@ un-debuggable emulators. The full engineering constitution is 1. **Build the faithful core; no per-game hacks in the foundation.** The correct fix is the general, hardware-accurate one, not a surgical workaround for one - title. (Per-game *enhancements* — widescreen, faster loads — are legitimate - once the faithful core is proven; see [`ENHANCEMENTS.md`](ENHANCEMENTS.md).) + title. No title checks in the runtime, no magic PC addresses, no spoofed + return values for one game. (Per-game *enhancements* — widescreen, faster + loads — are legitimate once the faithful core is proven; see + [`ENHANCEMENTS.md`](ENHANCEMENTS.md).) 2. **No stubs.** A function is fully implemented or it fails loudly. No `return 0;` placeholders, no `// TODO` behavior, no hand-delivered fake events. If execution reaches code we can't handle, we stop and fix discovery/codegen — we don't fake the result. 3. **Never hand-edit generated code.** Files under `generated/` and the recompiler's output are build artifacts. If the emitted C is wrong, fix the - recompiler (`recompiler/src/`), then regenerate. + recompiler (`recompiler/src/`), then regenerate. (The one exception: a PR + whose explicit purpose is to *inspect or prove* a generator bug.) 4. **LLE is the baseline; HLE is a validated subsystem replacement, never a starting point.** The recompiled BIOS is the reference and oracle. An HLE tier is allowed only where the LLE path has a genuine landmine, must be general @@ -51,6 +64,56 @@ un-debuggable emulators. The full engineering constitution is 6. **Fix broken tooling immediately** — don't route around it with indirect evidence, and don't infer correctness from two implementations sharing a bug. +## AI-assisted and human contributions + +Both are welcome. Using AI does not reduce your responsibility for the result: +review, understand, and test any code before submitting it, and don't submit a +large AI-generated rewrite you can't explain or validate. A PR — however it was +written — is likely to be rejected if it: + +- Introduces broad, unfocused changes, or combines unrelated refactors with + behavioral fixes. +- Hardcodes game-specific behavior into the framework, or adds a title check to + the core runtime. +- Modifies generated output instead of fixing the generator/source. +- Introduces regressions in known-working games. +- Contains code the contributor cannot reasonably explain, or whose verification + cannot be stated. + +## Game-specific work belongs in game repos + +The framework stays game-agnostic. Per-game patches, launcher UI, assets, memory +maps, metadata, config, and workarounds live in the appropriate game repo, not +here. If a behavior differs by game, disc, executable, region, BIOS, or runtime +configuration, it should be **parameterized** (config option, per-game manifest +value, a parameter passed in from the game repo) or **modeled** as the real +hardware/runtime behavior — never special-cased in the core. + +Known game repos: + +- [TombaRecomp](https://github.com/mstan/TombaRecomp) — *Tomba!* +- [MegaManX6Recomp](https://github.com/mstan/MegaManX6Recomp) — *Mega Man X6* +- [ApeEscapeRecomp](https://github.com/mstan/ApeEscapeRecomp) — *Ape Escape* + +### Framework changes and the pin + +Because each game pins an exact framework commit (its `psxrecomp/` submodule +pointer), a framework fix does **not** reach a game until that game bumps that +pointer. When your framework change is meant to fix or improve a specific title: + +- **Link the game repo** in your PR (and a matching game-repo branch/commit/PR if + you have one). This lets maintainers build and test the fix in its real + integration environment. +- **Build the game against your framework branch** to prove it. The game's + `CMakeLists.txt` points `PSXRECOMP_ROOT` at the submodule; you can build + against a working checkout via the junction/symlink dev setup, or override + `PSXRECOMP_ROOT` at configure time to point at your branch — no submodule + surgery required. See [`docs/BUILDING.md`](docs/BUILDING.md#linking-the-framework). +- **Say whether a pin bump is required to consume the fix**, and whether it + requires a **regen** (codegen/emitter changes do; runtime-only changes usually + don't — note which). Bumping the submodule pointer is a deliberate, reviewable + change made in the game repo, not something a framework PR does on its own. + ## Verifying a change Correctness is demonstrated, not asserted: @@ -63,6 +126,40 @@ Correctness is demonstrated, not asserted: - **A decoder / codegen change requires a playthrough check**, not just a clean build: cosim/lockstep first, then run the affected area. +### Regression checklist + +A framework change should not break a game that worked before it. When practical, +build against the known-working game repos above and confirm, for each: + +- The game **boots**. +- The **attract demo** plays without issue. +- A save file can be **created**. +- A save file can be **loaded**. +- **Gameplay is reachable** after saving/loading. + +Perfect compatibility across every game isn't required for every PR, but the PR +must clearly document **what was tested and on which games**. Useful notes: host +OS, compiler/toolchain, game repo + version/region, whether it boots / reaches +gameplay / save-load works, and whether memory cards, audio, video, input, CD +loading, or overlays were touched. Call out any known regression or uncertain +area explicitly — a documented uncertainty is fine; a silent one is not. + +## No copyrighted assets + +Do not submit copyrighted binary content to this repository. This includes, but +is not limited to: + +- PlayStation BIOS files +- Game ROMs, ISOs, BIN/CUE files, or disc images +- Extracted game assets — music, sound, textures, models, video, fonts, artwork +- Proprietary SDK files +- Decompiled copyrighted game source + +Small factual references — addresses, symbols, hashes, structure descriptions, +compatibility notes — are acceptable when used for tooling, debugging, or +documentation. The local artifacts above are gitignored in every repo for exactly +this reason (copyright + size); keep them out of commits. + ## Adding a new game At a high level: create a game repo from the template, add this framework as the @@ -74,11 +171,15 @@ menu → gameplay, oracle-checking as you go. The existing game repos ## Pull requests +Keep PRs focused — one thing: one bug, one feature, one diagnostic, one isolated +refactor, or docs for one topic. Avoid combining unrelated refactors, formatting +churn, and behavioral fixes in the same PR. + - Branch off `master`; keep framework changes and game changes in their respective repos. - **Do not commit** local artifacts: BIOS images, disc images, generated C (`generated/`), memory cards, Ghidra databases, build outputs, or overlay - capture files. These are gitignored for good reasons (copyright + size). + capture files. - Explain *what hardware behavior* the change matches and *how you verified it* (oracle diff, screenshot, playthrough). Changes that can't state their verification are hard to accept. @@ -86,6 +187,53 @@ menu → gameplay, oracle-checking as you go. The existing game repos config). If you find yourself editing generated code or adding a stub, step back — the real fix is upstream of that. +When opening a PR, please include: what changed and why; whether it's +game-agnostic or needs per-game configuration; what games/tests were run; any +risks or known limitations; links to affected game repos/branches/commits when +the change targets a specific game; and screenshots, logs, or traces when useful. + +## Bug reports + +Good bug reports are extremely helpful. Please include: + +- The game repo being used, and version/region if known. +- Your OS and build type/configuration. +- Steps to reproduce, expected behavior, and actual behavior. +- Logs, traces, screenshots, or video if available. +- Whether it happens in **LLE (recompiled BIOS)**, **HLE**, and/or the + **dirty-RAM interpreter** path — and in the software vs OpenGL vs Vulkan + renderer, if relevant. +- Whether it's a **regression** from a previous commit, and the last good one if + you know it. + +For gameplay bugs, include the nearest save file or a reproduction path when +possible. For build failures, include `gcc -v` / your toolchain / the generator. + +## Dependencies and portability + +Avoid unnecessary dependencies. When adding one, explain why it's needed and how +it affects portability, build complexity, licensing, or distribution. The project +should stay practical to build and run for contributors. + +## Style and maintainability + +Prefer clear, boring, maintainable code that reads like the code around it: match +the surrounding style and naming, keep changes localized, and comment non-obvious +hardware behavior or timing assumptions. Prefer diagnostics that can be compiled +out when not needed. Avoid cleverness unless it's clearly justified. + +## Licensing + +By contributing, you agree your contribution is licensed under the same license as +the project. Do not submit code you don't have the right to contribute, and do not +copy from incompatible licenses or proprietary sources. + +## Be respectful + +Contributors use different tools, workflows, and levels of AI assistance. Review +the contribution, not the person. Technical criticism is welcome; personal attacks +are not. + ## Questions / community Development happens with the **R.A.I.D. (Retro AI Development)** community — diff --git a/README.md b/README.md index 97aaa10a..5bf6963f 100644 --- a/README.md +++ b/README.md @@ -273,6 +273,21 @@ copyrighted material — keep it on your own machine, alongside your disc image. A metadata-only contribution format (addresses and checksums, no game code) is planned so discoveries can be shared safely in the future. +## Contributing + +Contributions are welcome — AI-assisted or not — as long as they're reviewed, +tested, and keep the core game-agnostic. A few things hold this project together: +the faithful recompiled BIOS is the baseline and oracle, generated code is never +hand-edited (fix the recompiler and regenerate), and a change proves itself +against the Beetle oracle / on screen rather than by assertion. Game-specific work +lives in the game repos, which pin an exact framework commit as a submodule. + +Read [`CONTRIBUTING.md`](CONTRIBUTING.md) before opening a PR — it covers the core +rules, how to verify a change, the regression checklist across the known games, +and how a framework fix reaches a game through its pin. Bugs and build problems go +to GitHub issues (include `gcc -v` / OS / generator for build failures); design +discussion happens in the **R.A.I.D.** Discord (invite below). + ## License PolyForm Noncommercial 1.0.0. See `LICENSE`.