Skip to content

Repository files navigation

gen2recomp

Godot 4.8.dev2 GDScript Platforms Status: early MIT licence Discord X

A native Godot 4 reimplementation of Generation 2 Game Boy Color games Gold, Silver and Crystal. It is written from scratch in GDScript, not an emulator, static recompilation or disassembly. A user-supplied cartridge dump is SHA-1 verified, decoded once into a cache, then released. No game data ships here: bring your own ROM.

Inspired by gen1recomp.

Status: early

Not a complete game yet. What works today:

  • Import. Species, moves, items, types, the type chart, learnsets, evolutions, palettes, every Pokémon sprite, trainer pics and parties, the font, text-box borders, the battle HUD, maps, overworld menus, 34 mart lists, phone contacts, special calls and music/SFX pointers. A scene-free host resolves all of it without reopening the ROM.
  • Battles. Parties, switching, stats, damage, accuracy, turn order, status and substatus effects, trainer AI, experience, levelling, move learning and capture input on a real 160x144 screen.
  • Overworld. Real maps, map connections, script requests, trainer battles with imported win/loss text, map reloads, save-safe blackout recovery, object lifecycle, followers, block edits, emotes, surf, ledge hops, grass, fishing, roaming, repel and wild encounters. The service overlay covers menu selection, mart dialog variants and quantity purchases, source-timed phone dispatch and bounded music, effects and cries.
  • Saves. Three slots, .sav import, and a 14-box PC model with 20 slots per box. Gifts, eggs, NPC trades, HP/status items, repel and captures commit through a validated candidate save; a full party routes into the first free box slot and full storage refuses atomically. Format 1 saves migrate without inventing a world position.
  • Mods. A mod under user://mods/ can register a replacement world renderer, which is what a 3D or HD view needs.

The real-data story preview walks the Crystal route from Elm's lab through Route 29, Cherrygrove, Route 30 and Mr. Pokémon's Mystery Egg event to the Zephyr Badge. Missing: full story state, dex, trainer card, options, the remaining special-call branches and story-driven permanent contacts.

Getting started

You need Godot 4.8 or newer. Enable the commit guard once per clone:

git config core.hooksPath .githooks

Put dumps in roms/, then verify them. See roms/README.md.

godot --headless --path . -s res://tools/verify_rom.gd

Supported cartridges

Matching uses SHA-1, never filenames. Unknown hashes are refused because an uncharacterised bank layout could produce corrupt assets.

Game SHA-1
Gold (USA/Europe) d8b8a3600a465308c9953dfa04f0081c05bdcb94
Silver (USA/Europe) 49b163f7e57702bc939d642a18f591de55d92dae
Crystal (USA/Europe Rev 1) f2f52230b536214ef7c9924f483392993e226cfb

Importing

godot --headless --path . -s res://tools/import_rom.gd

Import takes a few seconds per game. The cache is keyed by game and hash and lives in Godot's user://, never in the project or an export. Use --verify to check without writing.

Data Contents
Species Names, base stats, types, held items, egg groups and TM/HM flags
Learnsets All 251 species' level-up moves in cartridge order
Evolutions Every evolution and method/requirements
Moves Names, power, type, accuracy, PP, effect and chance
Items, types 255 item names, prices, effects, menus, pockets, healing metadata and 28 type names
NPC trades Gold/Silver six-row or Crystal seven-row records with requested/offered species, DVs, held item and OT data
Type chart Every matchup and the two Foresight-cancelled entries
Trainers Class names, pics, palettes, AI flags, DVs and every party
Palettes Normal and shiny 15-bit cartridge colours
Sprites Front/back for 251 species and all 26 Unown forms
Font and borders 128 glyphs and eight six-tile text-box frames
Battle HUD HP/EXP bars, panel borders and colours
Overworld Maps, tilesets, collisions, events, scripts, movement, palettes, animation and object sprites
Wild encounters Normal/swarm grass and water, 13 fishing groups with day/night substitutions, 16-row roaming graph, map-linked rates and slots, time-of-day selection, surf variance and repel checks
World services Referenced menus, mart inventories, phone contacts, special calls, bounded scripts/text, music, SFX, cries and shared waveform assets

Sprites remain colour indices and receive a palette at draw time, so shiny rendering needs no duplicate images.

Preview decoded graphics:

godot --headless --path . -s res://tools/preview_pics.gd -- gold /tmp/gold.png front

Use trainers, font or frames instead of front. Dump decoded tables with species, moves, items, types, matchups, trainers, learnsets, evolutions, growth or all:

godot --headless --path . -s res://tools/dump_tables.gd -- gold moves

matchups prints a grid; learnsets and evolutions resolve numbers into names; growth checks all 251 species against the six curves and base EXP.

Running

Smoke test the main scene:

godot --headless --path . --quit-after 30

The launcher lists Gold, Silver and Crystal cache status, imports a selected ROM, and opens its save screen: three validated slots, .sav import, party inspection and the development battle. A new game starts with an empty party at the Crystal home spawn with source starting money; Elm's imported lab scripts offer Chikorita, Cyndaquil or Totodile at level 5 holding Berry. Continue enters the overworld and F5 saves its map, inventory, event and clock snapshot. See docs/SAVES.md for the save and SRAM contract.

Development scenes:

Scene Keys
game/render/pic_viewer.tscn left/right species, S shiny, B front/back, T trainer classes
game/render/text_viewer.tscn Space advances, F cycles borders, C shows every glyph
game/battle/battle_screen.tscn A turn, Space events, W switch, left/right matchup, S/D damage either side; in wild battles B opens the ball selector, left/right changes ball, Space throws
game/world/world_screen.tscn arrows/WASD move, Space or Z confirms, F fishes while facing water with an owned rod, P opens the phone list, Enter/Tab opens the start menu, Esc closes an overlay, V cycles world renderers, F5 saves

Battle-screen moves are random and a full move set declines the learn offer; use show_trainer(trainer_class) for a real party and trainer AI, or show_matchup for a fallback pairing.

The world screen's start menu wires Pokemon, Pack, Pokegear, Save and Exit; Pokedex, Player and Options appear in their source position but do nothing yet. The Pack opens each item's own source submenu and can use one: a Potion asks which Pokemon and heals it, a Repel sets its step count, and GIVE, TOSS and SEL keep their source position marked unavailable. The party submenu offers Cut, Surf and Whirlpool to a Pokemon that knows one; all three show their message first and change the world on the acknowledge, and stepping from water back onto land stops surfing. Standing on a whirlpool, waterfall, door, staircase or cave tile overrides the pressed direction the way the cartridge does. The imported Players House PC opens the embedded box storage screen. The host clock advances one game minute per real minute and crosses source day boundaries. preview_emote(), preview_wild_encounter(), preview_fishing_battle(), preview_script_event(), preview_battle_request(), preview_world_battle_loss(), preview_capture() and preview_party_transaction() drive their live paths; the API also exposes swarm/roaming updates, repel countdowns and a JSON-safe snapshot.

Headless tools, all against a real imported cache:

Tool Checks
preview_world_services.gd <png> mart overlay, deterministic integration cache
preview_fishing.gd <png> [game map] fishing, for example silver 2 5; one-argument form is a fixture smoke test
preview_world_story.gd map entry callbacks, event-flag visibility, facing interactions and the story route
validate_crystal_route30_trainer.gd trainer record, sight line, approach, battle request, beaten flag, later interaction
validate_ledge_hops.gd the eight hop codes, accepted directions, Route 30's ledge record and the two-cell landing, in both games
validate_side_walls.gd the side-wall/side-buoy codes, their face masks and map census, in both games; Celadon Mansion Roof's fence and staircase landings on Crystal
validate_cut.gd the cut block tables, the profile-split tileset numbers and cuttable-cell census, and Ilex Forest's tree, in all three games
validate_surf.gd the surf sprites and music record, the surf-entry cell census, and New Bark Town's east shore, in all three games
validate_whirlpool.gd the whirlpool block table, the forced-tile cell census, and Dragon's Den B1F's whirlpool, in all three games
# Crystal map 3/19: block edits, hidden object, facing interaction
godot --headless --path . -s res://tools/preview_world_story.gd -- crystal 3 19 3 5 1 37,1744
# bedroom PC and the bedroom-to-town warp chain
godot --headless --path . -s res://tools/preview_world_story.gd -- crystal 24 7 2 2 1 none home
# the full walked route, ending at the Zephyr Badge
godot --headless --path . -s res://tools/preview_world_story.gd -- crystal 24 7 2 2 1 none home story

World text follows the cartridge command stream: $50 is a page break, $57 ends a text box and $58 pauses for a prompt. The story runner keeps the source yes/no order, weekday wrapping and first eight temporary event flags, which reset on a map reload.

Tests

GUT is in addons/gut; configuration is in .gutconfig.json.

godot --headless -s res://addons/gut/gut_cmdln.gd -gdir=res://tests -ginclude_subdirs -gexit

Exit code 0 means all tests passed. They use synthetic files and a known SHA-1 vector, never a real cartridge. Overworld integration suites can run alone with -gdir=res://tests/integration; service coverage includes menus, marts, phone calls and audio requests.

Layout

Path Contents
game/ Feature folders with colocated scenes and scripts
autoload/ Project singletons
assets/ Authored or freely licensed assets
assets/brand/ Logo and banner; see its README
addons/ Third-party plugins
tests/ GUT unit and integration tests
tools/ Headless developer scripts
roms/ User cartridges, excluded from Git and Godot imports
game/mods/ Mod manifest and host
mods/examples/ Example mods to copy into user://mods/
docs/ Contributor notes

Platforms

Windows, macOS, Linux, Android and iOS use GL Compatibility. export_presets.cfg covers all five and writes into builds/. Install the matching export templates first, then:

godot --headless --path . --export-release "Linux" builds/linux/gen2recomp.x86_64

Tests, tools and GUT are excluded, and roms/ and the user:// cache are not reachable from an export at all. Signing identities are placeholders: set the bundle identifiers, Android SDK paths and Apple team ID before publishing.

iOS forbids JIT and runtime native code, so mods must be interpreted GDScript, not compiled extensions. The project is therefore GDScript-first. See docs/MODS.md.

Contributing

Read docs/CONTRIBUTING.md. No cartridge-derived data may enter the repository: no ROM, .sav, extracted sprites, text, maps or audio. .gitignore, the pre-commit hook and tests enforce this; do not weaken them. For reproducible comparisons with the upstream disassemblies, see docs/REFERENCES.md.

Licence

MIT covers the engine source here, not the games or supplied dumps, which remain the property of their respective owners.

About

A native Godot 4 reimplementation of the Gen 2 Game Boy Color games. Not an emulator, bring your own ROM.

Topics

Resources

Contributing

Stars

11 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages