agentleFS
JakeschincariolJakeschincariol/console-skill/console-mod/SKILL.md

console-mod

Skill92 starsChanged 21 days agoMITView on GitHub

Mod Maker. Describe any change in plain English and Claude builds it into the game: patches, cheats, new behaviour, as code that never touches the original files. Ports PCSX2 .pnach patches to the PS2Recomp port (code writes become ps2_recomp TOML instruction patches, data writes become a C++ game override that writes RDRAM at load or every frame, the rest are flagged for a manual port with the reason) and scaffolds game overrides that bind, replace or wrap a game function with the real PS2Recomp API. Writes to console/patches/, never to the game's files, the generated runner/*.cpp or headers. Use when the user says "mod this game", "add a cheat", "infinite health", "port this pnach", "make my gun do X", "change how X works", "game override", "turn this PCSX2 patch into the port", or once the port boots and they want to change it.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Bring your own game: Only a game the user owns, dumped from their own disc.

    line 139
  2. Very specific:

    Never edit the game's files, ps2xRuntime/src/runner/ or any header (a header change rebuilds every generated file).

    line 147

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

console-mod

The Mod Maker turns a request ("my rifle does triple damage", "start with 99 lives", "skip the intro") into a change built into the port. A mod is a few small text files you own: a .pnach to try the idea in PCSX2, TOML instruction patches for ps2_recomp, and a C++ game override compiled into the runner. The disc, the ELF and the recompiled C++ are never edited.

Be honest about the hard part: finding WHERE the game keeps a value or does a thing is the real work, and it differs per game. This skill gives the method and the tools. Big mods ("two games in one", new modes, new levels) are long projects built from these same pieces, one function and one value at a time.

${CLAUDE_SKILL_DIR} below is this skill's folder (where this SKILL.md lives).

python3 "${CLAUDE_SKILL_DIR}/pnach.py" crc SLUS_203.12                       # both CRCs + the pnach name PCSX2 wants
python3 "${CLAUDE_SKILL_DIR}/pnach.py" parse my.pnach                         # every line, section and code kind
python3 "${CLAUDE_SKILL_DIR}/pnach.py" classify my.pnach --elf SLUS_203.12   # CODE / DATA / BSS / HEAP / OUTSIDE / CAVE
python3 "${CLAUDE_SKILL_DIR}/pnach.py" toml my.pnach --elf SLUS_203.12       # [[patches.instructions]] blocks
python3 "${CLAUDE_SKILL_DIR}/pnach.py" override my.pnach --elf SLUS_203.12 --frame-hook 0x0012A3B0
python3 "${CLAUDE_SKILL_DIR}/override.py" new --name "Gold rifle" --elf SLUS_203.12 --wrap 0x00123450=gold_damage
python3 "${CLAUDE_SKILL_DIR}/override.py" keys SLUS_203.12                    # keys for a hand-written override

Other flags: --map console/functions.csv (the CSV from Ghidra's ExportPS2Functions.java: tells code from data in single-segment ELFs and checks function starts), --section NAME (port only some [sections]), --ignore-crc, --json, --out, --force, --repo <PS2Recomp> (checks --bind handler names against ps2_call_list.h). Exit 1 means something needs a manual port or a warning; read it out.

What it reads and writes

filewhat
the game's main ELF (SLUS_203.12)read only: segments, sections, original instruction words, both CRCs
*.pnachread only: PCSX2 patches, yours or a community patch you trust
console/functions.csvoptional: Name,Start,End,Size from ExportPS2Functions.java
console/patches/<slug>.cppthe override module: yours, safe to share
console/patches/console_mods.cmakewritten once: compiles every .cpp in that folder into ps2EntryRunner
the game's ps2_recomp TOMLnever written by the tools: paste the toml output yourself, after a backup
templates/override.cppthe corrected override template both tools fill in (the original skill's template called an API that never existed)
templates/console_mods.cmakecopied next to the overrides the first time

From a request to a mod

  1. Pin the change down. "Triple damage" means: which number, for which weapon, when. Ask one question if it is ambiguous. Write it in console/STATE.md as the goal.
  2. Pick the layer.

    the changelayerhow
    a value the game keeps in RAM (lives, ammo, money, a timer)data write, re-applied every frame if the game rewrites itpnach, then pnach.py override --frame-hook
    a constant (speed, gravity, jump height, damage table)data or a constant built in code/console-physics finds it, tune.py patch writes the lines
    one instruction (skip a check, stop a counter going down)code patchpnach, then pnach.py toml
    new behaviour (a function does something else)function overrideoverride.py new --replace or --wrap
    the runtime already has a handler for that functionbindoverride.py new --bind 0xADDR=handler (or handler@0xADDR in TOML stubs)
    a texture, a sound, a levelasset swap/console-graphics, /console-sound, /console-levels
  3. Find the address. PCSX2's debugger memory search while playing (search the value, change it in game, search again), then a write breakpoint shows the code that changes it; Ghidra (GhydraMCP if installed, see /console-reverse) for the function and its callers; /console-physics tune.py scan for floats. Addresses belong to ONE build: always use the user's ELF.
  4. Test in PCSX2 first. pnach.py crc <ELF> prints the file name PCSX2 looks for (SLUS-20312_1A2B3C4D.pnach, in its patches/ or cheats/ folder). Write the lines, enable them, check the effect. Cheap to iterate.
  5. Bake it into the port.
    • pnach.py classify first. Read out every class and every manual line.
    • CODE: pnach.py toml prints [[patches.instructions]] blocks. Back up the game's TOML, paste them at the end, re-run ps2_recomp, rebuild incrementally. ps2_recomp only patches words inside functions it decodes, and SYSCALL/COP0/CACHE originals need patch_syscalls/patch_cop0/ patch_cache = true (the output says when).
    • DATA, BSS, HEAP: pnach.py override writes the module. Place 1 and 2 writes and anything the game clears at boot need --frame-hook, a function the game calls once per frame AND reaches with jal (see reference/mod-layers.md). A j tail jump to a known function compiles to a direct C++ call that skips the runtime's function table, so the hook would not run on that path. The tool counts the jal and j references and warns; if only j reaches it, hook the caller one level up. The same holds for override.py --replace/--wrap/--bind.
    • New behaviour: override.py new, then fill in the C++ (the stubs show how to read arguments with getRegU32(ctx, 4) and return with setReturnU32). API details: reference/override-api.md.
    • Install once per PS2Recomp checkout, with the user's OK: add include("<abs path>/console/patches/console_mods.cmake" OPTIONAL) at the end of ps2xRuntime/CMakeLists.txt. It adds every .cpp in console/patches/ to the ps2EntryRunner executable itself: ps2_runtime is a static library, and the linker drops an object file there that only holds a self-registration, so never put overrides in src/lib/. Then cmake --build out/build --config Debug. The files stay out of the unity batches, so the recompiled game does not rebuild.
  6. Playtest with /console-tester (run.py boot ... --expect) and play it yourself. The runtime logs [game_overrides] applying '<name>' when the module matched (runtime logs on).
  7. Record it: one line per mod in console/STATE.md (name, files, status).

The pnach format, every line kind and the CodeBreaker extended codes are in reference/pnach-format.md.

What classify means

classwhere the write landsbecomes
CODEan executable section, a function in the Ghidra map, or an executable segmenta TOML instruction patch; byte and short writes are merged into the original word from the ELF
DATAdata the ELF loads from the filean RDRAM write in the override at load (place 1/2: also every frame)
BSSthe zero-filled part of a segmentthe frame hook: once on the first frame (place 0) or every frame (place 1/2)
HEAPRAM beyond the ELF (heap, stack, loaded files)the frame hook, same as BSS
OUTSIDEscratchpad, hardware registers, BIOS, EE kernel RAM (below 0x00080000)manual: no RDRAM write does what it did on a PS2
CAVEnew code written into memory, a jump or branch into patched memory, or (with --map) code where no function ismanual: rewrite the logic as an override function

A low-confidence CODE write (one read-write-execute segment, no sections, no map) is both patched in the TOML and written to RDRAM, so it works whether it is code or data. Pass --map to settle it. IOP patches, dpatch lines and extended codes other than plain writes are listed as manual with the reason.

Guard rails

  1. Bring your own game. Only a game the user owns, dumped from their own disc. Never download or look for ISOs, ELFs or BIOS files, never ask for them. PS2Recomp needs no BIOS.
  2. Nothing from the game gets published. Share the .pnach, the TOML patch lines, console/patches/*.cpp and the user's own assets. Never the disc, the ELF, IRX modules, ripped assets or the generated runner/*.cpp.
  3. Not affiliated with Sony. PlayStation is a trademark of Sony Interactive Entertainment.
  4. Never edit the game's files, ps2xRuntime/src/runner/ or any header (a header change rebuilds every generated file); never clean the build. The tools refuse to write into runner/, refuse to overwrite without --force, and refuse a pnach whose file-name CRC is for another build. Back up the TOML before pasting. A mod that crashes the port is reverted first, then fixed.

Hands off to

  • /console-physics to find and tune the numbers (speed, gravity, frame rate).
  • /console-graphics, /console-sound, /console-levels for asset swaps.
  • /console-tester to boot, playtest and check nothing else broke.
  • /console-reverse to re-run ps2_recomp after TOML patches and log STATE.md.
  • /console-anywhere to package: mods ship as patches and overrides, never game files.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.