-
Notifications
You must be signed in to change notification settings - Fork 8
Decomp Project Mode
Decomp project mode lets FEBuilderGBA treat a Fire Emblem decompilation source tree (e.g. an agbcc-built pret-style project) as the source of truth, instead of a single .gba binary. You open the project directory rather than a ROM; the built ROM is loaded only as a read-only preview, and edits are written back to the owning C struct array or JSON element in the source tree — producing a clean, reviewable diff that survives a rebuild.
This is the opposite workflow from classic ROM mode: in classic mode the .gba is canonical and edits mutate ROM bytes; in decomp mode the source is canonical and the ROM is a build artifact.
Classic ROM mode is completely unchanged. Decomp mode is purely additive and opt-in — you only enter it by opening a project directory (Avalonia Open Decomp Project) or passing
--project=<dir>to the CLI.
| Step | CLI | What it does |
|---|---|---|
| Open project |
--project=<dir> (+ --rom-info) |
Detect the project, load the built ROM for preview, show the mode badge |
| Resolve address | --resolve-addr=<hex> |
Map a ROM address to a source symbol (name / source artifact / offset) |
| Diff-to-source | --migrate-diff |
Classify built-vs-edited ROM changes by symbol/category/confidence (advisory) |
| Write to source | --write-source |
Rewrite the owning C-struct / JSON element instead of mutating the ROM |
| Write a shop list | --write-shop |
Rewrite the owning u16 ITEM_NONE-terminated shop list in source |
| Export an asset | --export-asset |
Dump a ROM asset to a source-tree path (palette / graphics / map / text) |
| Validate an asset | --validate-asset |
Structurally validate an import asset on disk (never touches the ROM) |
| Build & reload | --build-project [--reload] [--yes] |
Run the manifest build command (explicit opt-in) and reload the rebuilt ROM |
| Audit coverage | --decomp-audit |
Print the round-trip coverage matrix (source-backed / exporter / preview / manual / ROM-only) |
| NMM ↔ manifest |
--nmm-to-manifest / --manifest-to-nmm
|
Bridge Nightmare .nmm table schemas ↔ decomp manifest table defs |
See Command-Line Interface for the full per-command reference.
When you open a directory, FEBuilderGBA detects a decomp project by looking for a Makefile declaring the ROM (ROM/BUILD_NAME/agbcc usage). Detection works without any extra file, but an optional manifest unlocks the source-backed writers, builds, and schema bridge:
your-decomp-project/
├── Makefile # ROM / BUILD_NAME / agbcc — used for auto-detection
├── febuilder.project.json # optional manifest (see below)
├── <build_name>.gba # built ROM — loaded as a read-only preview
├── <build_name>.map # GNU-ld map — layered into symbol resolution
├── <build_name>.elf # ELF symbols — layered into symbol resolution
└── src/ data/ ... # C/JSON source the writers edit
febuilder.project.json (the manifest) declares:
- A build section — the build command, working dir, and the path of the ROM it produces (used by
--build-project). - A tables section — for each structured table (items, units, classes, …), the owning C struct array or JSON file, so
--write-sourceknows which source element to rewrite.
When no manifest is present you still get preview, address resolution, diff migration, and asset export; the source-backed writers and builds require the manifest's owner/build declarations.
--resolve-addr=<hex> (requires --project) maps a ROM address to a source symbol, layering the project's own symbols over the shipped symbol set:
- GNU-ld
.mapfile - ELF symbols
-
.sym/ JSON symbol files
It prints the symbol name, the source artifact it came from (map / elf / sym / json / shipped), and the byte offset into that symbol. The same resolution also lights up the Pointer Tool ("What is this address?") inside the GUI.
FEBuilderGBA.CLI --resolve-addr=0x08012345 --project=decomp/--migrate-diff is an advisory, read-only assistant for moving an existing FEBuilder-edited ROM back onto a decomp source tree. It treats the project's built ROM as the canonical baseline, compares it against your edited ROM (--rom2), and classifies each changed range by symbol, category, source artifact, and a confidence score. It never writes the ROM or the source — it just tells you what changed and where it likely belongs.
FEBuilderGBA.CLI --migrate-diff --project=decomp/ --rom2=edited.gba --out=migrate.tsv--write-source rewrites the owning C struct-array element (or JSON element) for a table entry instead of mutating ROM bytes. Properties:
-
Coverage: items, units (alias
characters), classes,map_settings/chapter,support_units/support_attributes/support_talks. - Signed fields are handled (the value is taken as the two's-complement magnitude).
-
Multi-field edits in one call — repeat
--field/--valuepairs. - Churn-free minimal diffs — only the changed initializer element is rewritten.
- Marks the project as "needs rebuild" after a write.
-
Unsupported / pointer-like fields fall back to ROM-only / manual (they aren't silently written). Shops are source-backed via the separate
--write-shopcommand when the shop's ROM address resolves to a manifestu16-list owner (both literal raw-hex and symbolicITEM_*item-id-only lists); otherwise they degrade to--export-asset --kind=shop/ manual.
FEBuilderGBA.CLI --write-source --project=decomp/ --table=items --id=1 --field=might --value=0x0A
FEBuilderGBA.CLI --write-source --project=decomp/ --table=units --id=1 --field=hp --value=18 --field=pow --value=7Shops are a variable-length u16 ITEM_NONE-terminated list with no fixed struct owner, so they are written by their own command rather than --write-source. --write-shop rewrites the owning source list in place when the shop's ROM address (or symbol) resolves to a manifest u16-list owner — handling both literal raw-hex lists and the symbolic ITEM_* item-id-only form (include/constants/items.h is consulted for the id↔macro map). When no owner resolves it reports not owned (exit 2) and you degrade to --export-asset --kind=shop / manual.
FEBuilderGBA.CLI --write-shop --project=decomp/ --symbol=ItemList_WM_FluornArmory --items=0x01:5,0x02:3
FEBuilderGBA.CLI --write-shop --project=decomp/ --shop-addr=0xB2A18 --items=0x16:1--export-asset dumps a ROM asset to a decomp source-tree path so it lives in the repo as a real file:
--kind |
Output |
|---|---|
palette |
JASC .pal
|
graphics |
indexed PNG (4bpp/8bpp indexed) |
map |
.mar (always LZ77-decompressed, with a .mar.json sidecar) |
mapchange |
raw u16 map-change overlay tile block (.change + .change.json) |
mapanime2pal |
raw u16 map tile-animation-2 palette block |
mapanime1gfx |
raw 4bpp map tile-animation-1 graphics block |
objtiles |
LZ77-decompressed 4bpp OBJ tile payload |
mapchipconfig |
LZ77-decompressed chipset TSA/config payload |
text |
directory (--out = dir) containing texts.txt + textdefs.txt
|
shop |
shop item list (EA migration artifact) |
Music, portrait, and battle-animation assets are exported via the existing dedicated commands (--export-midi, --export-portrait-all, --export-battle-anime).
FEBuilderGBA.CLI --export-asset --kind=palette --rom=rom.gba --addr=0x5524 --out=gfx/palette.pal
FEBuilderGBA.CLI --export-asset --kind=map --rom=rom.gba --addr=0x200000 --out=map/chapter1.mar--validate-asset structurally validates a source-tree graphics / palette / portrait / icon / map / mapchange / mapanime2pal / mapanime1gfx / objtiles / mapchipconfig / portrait-package asset before you wire it into a rebuild. It is strictly read-only — it never mutates the ROM — and reports actionable ERROR / WARN findings so a bad asset is caught at desk rather than at build time.
FEBuilderGBA.CLI --validate-asset --kind=graphics --in=gfx/tiles.png--build-project runs the manifest's declared build command — but only with explicit opt-in via --yes. It captures stdout/stderr; with --reload it reloads the freshly built ROM and re-parses symbols on success. FEBuilderGBA never runs an arbitrary build command implicitly.
FEBuilderGBA.CLI --build-project --project=decomp/ --reload --yes--decomp-audit prints the maintained matrix of how each editor behaves in decomp mode. Categories:
The Coverage column prints the tier enum name; the meanings are:
| Coverage (enum) | Meaning |
|---|---|
| SourceBackedWriter | Edits rewrite the owning C/JSON source element (--write-source / --write-shop) |
| SourceTreeExporter | Asset is dumped to the source tree (--export-asset / existing exporters) |
| ImportPreviewOnly | The GUI previews an import but final apply is ROM-side |
| ManualMigration | No automated source path yet — edit the source by hand |
| RomOnlyUnsupported | Pointer-like / unsupported in source; only the ROM is written |
FEBuilderGBA.CLI --decomp-audit --format=md --out=docs/decomp-coverage.mdFEBuilderGBA can bridge Nightmare module (.nmm) table schemas to/from decomp manifest table definitions:
-
--nmm-to-manifest— parse a.nmminto a manifesttables[]entry JSON. Pointer / variable-length / odd-size fields are kept and flagged"unsupported": true(never dropped). -
--manifest-to-nmm— emit.nmmtext for a manifest table owner; pointer/var fields are flagged unsafe via warnings.
FEBuilderGBA.CLI --nmm-to-manifest --in=items.nmm --table=items --out=items.tables.json
FEBuilderGBA.CLI --manifest-to-nmm --project=decomp/ --table=items --out=items.nmm| Area | Decomp behaviour |
|---|---|
| Items, units/characters, classes, map/chapter, support (units/attributes/talks) |
source-backed via --write-source
|
| Palette, graphics, map, text assets |
exporter via --export-asset (+ existing exporters for music/portrait/battle-anim) |
| Shops (item lists) |
source-backed via --write-shop when the list resolves to a manifest u16-list owner; else --export-asset --kind=shop / manual |
| Pointer-like / unsupported struct fields | ROM-only / manual |
| Address lookups | resolved against project .map/ELF/.sym/JSON, layered over shipped symbols |
Run --decomp-audit for the authoritative, always-current matrix.
- Command-Line Interface — full flag-by-flag reference
- Editors Reference — the editors whose data the writers/exporters cover
- Native Android — the other cross-platform frontier from this release line