Custom agent imported from jaytheham/body-harvest-decompilation (
.github/agents/MatcherOrchestrator.agent.md). Copyright stays with the author.
Overview
This is a matching decompilation project for Body Harvest (N64). The goal is to create C code that "matches" - compiles to the exact same assembly as the original game ROM. You will be given a C file to target, follow this process:
- Begin by creating a new git branch named with this format:
matcher-YYYY-mm-dd-HH-MM-SS, include the date and time. - Scan the C file for all functions with a NON_MATCHING wrapper, these functions have been decompiled but do not yet match the original assembly when compiled.
- Orchestrate processing of these NON_MATCHING functions one at a time. For each function, you will:
- Remove the
NON_MATCHINGwrapper around the target function so the C code is included in the build instead of the assembly .s file. A file undersrc.us/core/, or one inshared_overlay_files.txt, is compiled for both ROMs, so verify both withpython tools/verify_build.py --rebuild(seedocs/pal-vs-na.md). - Build the ROM so the diff tool can calculate the C implementation's CURRENT difference value. It is normal that the build will return
FAILEDat this stage because the function does not yet match. - After building check the current difference value with the diff tool, a lower value is better,
CURRENT(0)is a match. Update the comment above the function with the new value, e.g.CURRENT(1234). - Create a subagent, agentName
BH Matcher, and tell the subagent to target the function.
- After a subagent finishes, undo any changes outside of:
/ExampleFixes/include/src.ussymbol_addrs.us.txtundefined_syms.us.txt
- Move any variables, structs, or function definitions the subagent added to a C file in
src.us/into the appropriate header file ininclude/(e.g. variables tovariables.us.h, structs tostructs.us.h, and function prototypes tofunctions.us.h). - Make sure the function is not wrapped with
NON_MATCHING, then build, if build returnsbuild/bh.us.z64: OKthen the decompilation is matching, commit the remaining changes with a message likeMatched func_80092ADC_A1A8Cand then return to step 3 and process the next function. - If the build returns
FAILED, check the function's CURRENT difference value withdiff.ps1. If the difference value is lower than the original value that's good, restore theNON_MATCHINGwrapper, update the comment above the wrapper with the new valueCURRENT(X), and commit the changes. If the difference value is the same or higher, undo all changes - including the removal ofNON_MATCHINGand check the build is OK before moving on to the next function.
Tell the subagents to resolve the differences in assembly as much as possible, they should keep going after they make a positive improvement, and only stop when they can no longer find any changes that reduce the number of assembly differences.
Ask each subagent to target a single function.
Subagents are not to commit any changes. After they finish you will check the current changes, then add NON_MATCHING if needed, fix any errors, revert any unintended changes, and fix whatever else is necessary to return the build to build/bh.us.z64: OK before committing. Make sure the function has a comment with the current difference value before committing. Only commit when the build is OK.
Keep going automatically until all NON_MATCHING functions in the file have been processed by subagents. Skip NON_MATCHING functions with switch statements, don't attempt to match them.
Retain any existing comments.
Project Structure
asm/nonmatchings: Readonly - target assembly of unmatched functions.asm/matchings: Readonly - target assembly of functions with a matching C implementation, for reference.build/: Readonly - compiled object files and the final ROM image.tools/: Readonly - tools for other tasks.src.us/: C source files of the NTSC (US) build.src.us/core/: C source files in this directory are also compiled into the EU build, so an edit there changes both ROMs.- The overlay files in
shared_overlay_files.txt(every file of the frontend, inside and outside overlays, the data-only ones included, and the C file of each level overlay) are also compiled into the EU build, so an edit to one changes both ROMs. An address of a level overlay or of the gameplay overlays written as a number in a shared file goes through the macros ofinclude/version_shift.h(LEVEL_PTR(0x802D531C)), or the EU ROM stops matching. include/: Header files for variables, functions, and structs.ExampleFixes/: Hints for decompilation.
Tools
These powershell tools exist to assist you:
- Build the ROM:
.\tools\make.ps1 - Get the difference value for a function:
.\tools\diff.ps1 <target function name> <next function name> --show-score | Select-Object -First 1.
