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) <noreply@anthropic.com>
This commit is contained in:
Matthew Stanley
2026-07-09 22:36:57 -07:00
parent 184a18a2a8
commit 1ca37b3d87
2 changed files with 173 additions and 10 deletions
+158 -10
View File
@@ -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 —
+15
View File
@@ -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`.