Skip to content

Inventory a game ​

Skill re-inventory. First look at a game's files (Windows PE, or DOS MZ/NE/LE executables) - which binaries hold the game's own code, which engine and middleware it uses, whether it is native, managed, scripted or packed, which data containers and save files exist - and record it in docs/FINDINGS.md. Use at the start of a project, or when a new binary or file type turns up.

Copy this prompt into your coding agent. Replace the part in angle brackets.

text
In my GameFrame project, use the re-inventory skill for <the task>.
Read the skill first and follow its steps in order.
Report the evidence it asks for, with its label: observed, measured, inferred or unknown.

Before any decompiling, make a short map of the game with evidence. It says what to analyse, with which tool, and what to leave alone. A wrong choice here (decompiling a packed binary, or analysing the C++ runtime of a Unity game instead of its C# code) wastes days.

0. Get the files out of their installer ​

A purchased game often arrives as an installer (GOG's Inno Setup .exe, a Steam depot, an NSIS or InstallShield setup, an .msi, a .dmg or .pkg, GOG's Linux .sh). Never run it: extract it.

bash
scripts/extract-installer.sh --detect "~/Downloads/setup_game.exe"     # what it is, which tool
scripts/extract-installer.sh "~/Downloads/setup_game.exe" target/gog
python3 tools/triage/compare_trees.py target/game target/gog         # same version?
python3 tools/triage/compare_trees.py target/game /dev/null --hashes > docs/HASHES.txt
  • A small macOS .app named after the game is often only GOG Galaxy's web installer: no game.
  • Store releases bundle extras worth reading: DOSBox or ScummVM configs (the CPU speed and sound hardware the publisher tuned the game for), manuals and cheat sheets as PDF, saves.
  • When you have two releases, compare them before choosing one. Identical executables mean every address and finding carries over; record the hashes (they are not game material) so every later finding names the exact version it was made on.

1. List the files ​

bash
find target -maxdepth 3 -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn | head -30   # by extension
find target -maxdepth 3 -type f -size +5M -exec ls -lh {} \; | sort -k5 -h               # the big ones

Group them: executables and libraries (.exe .dll .so .dylib), data containers (large files with custom extensions: .pak .pkg .dat .arc .bin .wad .pck .assets), configuration (.ini .cfg .xml .json .lua), saves (often in the user's Documents or AppData, not the game folder).

2. Look at every binary ​

bash
for b in target/*.exe target/*.dll; do .venv/bin/python tools/pe/peinfo.py "$b"; echo; done

For each, note: 32- or 64-bit, EXE or DLL, PDB path (a leaked build path names the engine and project), compiler (a Rich header means MSVC), imports, exports, RTTI count (C++ class names are recoverable), engine fingerprints, and packer warnings.

Decide which binaries are the game's own code: usually the EXE and any DLL with a game-like name and many exports or imports between them. Leave out operating-system DLLs, the C/C++ runtime (msvcp140.dll, vcruntime140.dll), and known middleware (FMOD, Wwise, Bink, PhysX, Havok, Steam/GOG SDKs): document what they are and move on.

Engines often ship a runtime DLL that exports C++ class names (?Rand@Random@System@@...). Its exports are free, accurate names: decompile it together with the EXE.

DOS and 16-bit programs ​

file saying "MS-DOS executable" (or peinfo refusing the file) means a DOS program. Use:

bash
for b in target/*.EXE target/*.exe target/*.OVL; do python3 tools/dos/dosinfo.py "$b"; echo; done

It names the format (MZ real mode, NE 16-bit protected mode, LE/LX 32-bit extender), gives Ghidra's selector for every NE segment, lists imports and exports, and fingerprints the compiler, extender, packer and sound libraries. Two lines matter most:

  • debug symbols: Turbo Debugger: the original names of every procedure, global and type are in the file. Run python3 tools/dos/tdinfo.py BINARY summary now; see docs/DOS.md section 3. This can save weeks.
  • A packer (LZEXE, PKLITE, EXEPACK, DIET): unpack before anything else.

Launchers are common: a small MZ that runs the real program (tyrian.exe running file0001.exe). The DOSBox-X file log (scripts/dosbox-run.sh --fileio) shows which program and which data files are opened, in order. Runtime files (RTM.EXE, DPMI16BI.OVL, DOS4GW.EXE) are the compiler's DOS extender, not game code. The whole DOS route is in docs/DOS.md.

3. Choose the route ​

What peinfo showsWhat it meansRoute
Native x64/x86, MSVC or MinGW, no packerOrdinary compiled C/C++GameFrame: re-ghidra, re-trace, re-emulate
mscoree.dll / _CorExeMain, or Assembly-CSharp.dll.NET managed code (XNA, MonoGame, Unity Mono)Decompile C# with ILSpy or dnSpyEx, or REA inspect_managed_artifact; the game logic is in the managed DLLs
GameAssembly.dll + global-metadata.datUnity IL2CPP: C# compiled to C++Recover names with Il2CppDumper (or Cpp2IL), then Ghidra with the generated script
UE4/UnrealEngine strings, .pak filesUnreal EngineMost logic is in the EXE plus Blueprint bytecode in .uasset; tools such as FModel and UE4SS read the assets
lua_pcall, .lua/.luac filesLua scripting on a native engineDecompile the scripts (unluac, luadec) for game rules; the native side is the engine
GameMaker / RPG Maker / Godot stringsA known engine with its own formatUse the engine's community tools for the data; the native binary is the stock runtime
dosinfo: MZ or NE, Borland/Microsoft/Watcom runtime16-bit DOS or Windows 3.x codeGameFrame's DOS route: dosinfo.py, tdinfo.py, Ghidra, dos_emu, DOSBox-X (docs/DOS.md)
dosinfo: LE/LX (DOS/4GW, PMODE/W)32-bit DOS-extender programGhidra with an LE/LX loader extension; run it in DOSBox-X
A ROM or disc image for a console (.nes, .sfc, .md, .z64, .bin/.cue, .iso)Console code at fixed addresses, often banked, no OSThe console route: docs/consoles/ (platforms, tools, routes to a port)
An engine's archives or DLLs (.WAD, .PAK, .GRP, .u, .MPQ, glide2x.dll, Engine.dll)A known engine or libraryRead docs/engines/recognising.md; use the engine's documented formats and released source where it exists
High-entropy executable section, .vmp0, .themida, UPXPacked or protectedStop. Unpack first (UPX: upx -d), or work from a memory dump with the user's agreement; Denuvo and VMProtect are out of scope for static analysis

For an Android or iOS game, an Electron or browser game, or an archive you cannot identify, use REA's routing (re-rea): it has dedicated tools for each.

4. Data containers ​

For each large file type:

bash
xxd target/data.pak | head -8                         # magic number, header fields, offsets
.venv/bin/python -c "import math,collections,sys;d=open(sys.argv[1],'rb').read(1<<20);c=collections.Counter(d);print(-sum(n/len(d)*math.log2(n/len(d)) for n in c.values()))" target/data.pak

Entropy near 8.0 means compressed or encrypted; 4 to 6 means plain structured data. Look for known signatures in the first bytes and inside: PK\x03\x04 (ZIP), \x78\x9c/\x78\xda (zlib), \x28\xb5\x2f\xfd (zstd), \x04\x22\x4d\x18 (LZ4 frame), RIFF, OggS, DDS , \x89PNG. Find the code that opens the file (search its name or extension in the strings), then decode it with re-format.

5. Record ​

Fill docs/FINDINGS.md (correct any first-look numbers the tools overturn, such as an NE segment with no bytes in the file, which is uninitialised data): the binaries table (file, role, architecture, compiler, notes), the engine and middleware with the evidence for each (the import or string that showed it), the data containers, and the open questions. Add the first lines to docs/CHECKLIST.md.

Also record the hardware the game was written for: the minimum CPU, the video modes, the 3D APIs, the sound devices and the input devices it supports (docs/hardware/). Its setup program and its readme list them.

6. Classify the game ​

Look at the game itself, not only its files: play it or watch it played. Then place it in the taxonomy (docs/games/README.md): who drives (a stream with controls, software over a simulation, an environment, turns and choices), its time model, where its rules live, what must repeat exactly, and its family. Read the family page and copy its rule set into the project's AGENTS.md, adjusted to the game. Record in docs/FINDINGS.md how exact the interface must be, and why. A mixed game gets one line per mode, and the state that switches between them. Next: re-observe.

Code: Apache 2.0. Content: CC0 1.0. No game material: bring your own copy.