3
Guide Total Conversions
bryanthaboi edited this page 2026-08-15 23:44:59 -04:00

Total conversions

Building a new game on the engine — new region, new dex, new story, new branding — without touching engine source. The capstone tutorial (Tutorial 12) walks a small one end-to-end; this page is the map of the territory.

The profile

{ "id": "my_conversion", "profile": "total_conversion", "api": 2, ... }

profile = "total_conversion" labels the mod in the manager and defaults affects_link to true, so the link fingerprint carries your content (Compatibility). The scaffold wires it:

python3 tools/modkit.py scaffold my_conversion --profile total_conversion

What a conversion replaces (all data)

Surface Mechanism
The world maps / tilesets / encounters registries; field (ledges, hidden items, fly network, town map, badge gates)
The boot flow field.boot — spawn, names, money, naming presets, screens = { splash, title, newGame } resolved through the screens registry. To keep OakSpeech but add questions / sprite beats / answers, wrap intro.oak_speech.build instead of replacing newGame
The roster pokemon / moves / type_chart / statuses / move_effects / growth_rates / evolution_methods
The people trainers / ai_classes; NPCs as map objects + map_scripts
The story map_scripts (compose; an override chain excludes the vanilla contribution per map), commands, tokens, text, text_pointers
The rules constants — dex size, badges (override for a whole new set), bag/party/box caps, level cap, HM list
The sound music / sfx / cries / map_songs; ChipAsm for authentic tracks
The look palettes / font / sprites / transitions; asset transforms and overrides/ (Art Pipeline)
The screens screens registry + the ui.* menu hooks
The saves save.new_game hook when field.boot is not enough; mod.save + mod.migrations for your own state

The deep registries take override as the total-conversion verb: it replaces a whole key where patch folds into it.

One generation at a time

A total conversion is a Gen 1 project today. The surfaces the table above leans on hardest are Gen 1 surfaces: field.boot, map_scripts, text_pointers, rulesets and transitions have no Gen 2 home, so on a Gold boot those writes are taken, dropped and reported, and there is no sanctioned way to replace Gold's boot flow or story (Data Model). Omitting the manifest's games key already means Gen 1 only, so an existing conversion is safe by default; declare games explicitly only if you also ship Gen 2 content, and keep the conversion itself off Gold boots rather than half-loading there (Preparing Your Mod for Gen 2).

What a conversion must not replace

  • The ROM import. It stays mandatory — it supplies fonts, UI plumbing and audio infrastructure, and it is the legal foundation: the player's own verified ROM is the only game-content input. Conversions overlay the imported world; they never substitute for it.
  • Engine source. Everything you need is a registry, hook, or event; a conversion that requires private modules is unsupported and must declare permissions = ["engine_internals"].
  • Someone else's content. Porting an existing ROM hack means rebuilding it natively: data re-expressed as registry records, mechanics rewritten against the mod API, art regenerated via transforms. The loader never executes IPS/BPS/UPS patches.

Coverage discipline

A conversion is done when every surface the player meets is deliberate. Iterate the merged registries (mod.content.<name>:each()) in a dev build to hunt vanilla leftovers — a Kanto map song on your route, an unreplaced trainer party, a dex entry you forgot. Keep a DIFFERENCES.md in the mod enumerating what diverges from vanilla; the base game's own ledgers stay clean because your changes vanish with the mod (Compatibility).

Shipping

modkit pack gates distribution on the no-ROM-content lint; the link fingerprint keeps two players of your conversion in sync and refuses a silent desync against vanilla (Link Compatibility, Publishing).