decomp-cpp-class-form

A guide for choosing C++ source code that makes an older Nintendo DS game compiler produce the same machine-code layout as the original game. It focuses on classes, constructors, destructors, virtual functions, and related compiler output.

In plain words
What is it for?
Use it when turning a data structure into a C++ class, matching a ROM's functions and symbols, or investigating destructor order, virtual calls, struct copies, and name mangling.
Why use it?
Matching the original compiled game depends on how the code is written, not only on what it means. The guide uses the compiler to test source-code forms instead of relying on guesses about binary details.

Skill for Claude CodeCodex

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add skills/tangosdev/sm64ds-decomp/decomp-cpp-class-form
Any agent
npx skills add tangosdev/sm64ds-decomp --skill decomp-cpp-class-form
Clone the repo
git clone --depth 1 https://github.com/tangosdev/sm64ds-decomp

Made for: Claude Code, Codex.

Per session 135 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 1,810 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00135 $0.01810
Opus 5 $0.00068 $0.00905
Sonnet 5 $0.00027 $0.00362
Haiku 4.5 $0.00014 $0.00181

Measured 2d ago against content hash e28a26b23f4a, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

decomp-cpp-class-form scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.claude/skills/decomp-cpp-class-form/SKILL.md · 113 lines

How it starts

The opening of the file, as written. The whole thing — 113 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Making mwccarm emit the ROM's shape

Byte-matching a real C++ class is a question about source form, not about being "more correct". The compiler is an oracle — ask it rather than reasoning about the ABI.

Ask the compiler, don't hand-mangle

python tools/mangle.py candidate.cpp
python tools/mangle.py candidate.cpp --expect _ZN5Actor8BehaviorEv
python tools/mangle.py candidate.cpp --mangled-only --json

It compiles with the pinned 2004/b56 C++ flags and reads defined GLOBAL/WEAK ELF symbols, so substitutions, thunks, ctor/dtor variants and static data are the compiler's answer, not a guess. It uses match.DEFAULT_FLAGS, which differs from rombuild.CFLAGS (-w illpragmas vs -Cpp_exceptions off) — verified not to change the emitted symbol set, so it is sound for the checks below.

Ordering cannot be read from st_value. mwccarm emits one .text section per function, so every symbol's st_value is 0. Order lives in the section index.

Destructor variants: the form decides the order

The ROM typically has D1 then D0 and no D2 (e.g. ov045: D1 0x021111a0 size 0x44, D0 0x021111e4 size 0x58, landing exactly on the next function). Measured:

source form instantiated in TU? emits order
X::~X() {} out of line no D2, D0, D1 + _ZTV D0 before D1 — wrong
X::~X() {} out of line yes (new X()) D2, D0, D1 + _ZTV D0 before D1 — wrong
virtual ~X() {} in class body no nothing at all no variants, no _ZTV
virtual ~X() {} in class body yes (new X()) D1, D0 + _ZTV D1 then D0 — matches

Two conditions, both necessary: define the destructor inline in the class body, and make the TU actually instantiate the class. The inline form also emits no D2, which removes a homeless _ZN…D2Ev that has no symbols.txt entry and cannot be dropped under -nodead.

In the winning form the destructor pair is emitted first, ahead of everything else — which is what a TU whose ROM range starts with D1 needs.

Read the full file on GitHub · 113 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 113 lines · 135 tokens per session scan A e28a26b23f4a

Subscribe to this mod's changes

decomp-cpp-class-form is a skill published in the GitHub repository tangosdev/sm64ds-decomp (138 stars, last pushed 2d ago), licensed MIT. It adds 135 tokens to every session and 1,810 once invoked, about $0.0007 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other skills, from other repositories

th08-re

Reconstruct bounded functions from the original Japanese TH08 1.00d executable using hash-attested target evidence, upstream GensokyoClub source, and explicitly labeled TH06/TH07 corroboration. Use for TH08 disassembly, ABI recovery, function naming, layout recovery, source migration, or implementation work.

N0zoM1z0/th08 · 69 tokens

th08-semantic

Replace raw TH08 object offsets, anonymous fields, and absolute field views with evidence-backed C++ types and names while preserving accepted VC7 bytes and playable modern-port behavior. Use for semantic cleanup of already-authored source; do not use for new function recovery or target-linked library work.

N0zoM1z0/th08 · 62 tokens

unreal-cpp-gameplay

Write Unreal Engine 5 C++ gameplay code: the UCLASS/UPROPERTY/UFUNCTION reflection macros, the Gameplay Framework (GameMode, Pawn, Character, PlayerController, Actor components), and the module Build.cs. Use when writing or debugging UE C++, deriving from AActor/ACharacter/ AGameModeBase, exposing properties to the…

gamedev-skills/awesome-gamedev-agent-skills · 105 tokens

gdextension

Use when building native extensions for Godot — godot-cpp (C++) or gdext (Rust), binding classes, building, and GDScript/C# interop.

jame581/GodotPrompter · 38 tokens

th08-matching

Compile TH08 functions with the repository VC7 build and compare configured COFF functions against the hash-attested 1.00d target using config/match-units.toml and scripts/compare-function.py. Use for focused code-generation tuning, relocation diagnosis, or exact-match verification.

N0zoM1z0/th08 · 62 tokens

th08-typed-re

Generate and interpret target-pinned TH08 instruction and ABI fact packets with scripts/typed-re.py. Use for stack layout, register homes, access widths, direct calls, return cleanup, or VC7 source-shape diagnosis before strict comparison.

N0zoM1z0/th08 · 54 tokens