Read the English 1.0 and Australian cartridges besides 1.1 (#84)
Checks / web (push) Failing after 19s
Private ROM checks / private-rom (push) Failing after 25m36s

PRET's crystal and crystal_au builds reproduce both retail cartridges,
and every label the profile pins keeps its address in all three;
check:reference now verifies that when the rebuilds are present. The
revision comes from the header. Revision 1.0's Battle Tower draws only
the first 21 trainers and picks its texts' gender from the name's sixth
character, checked against each cartridge. A native backup imports
across the three, which share every map, event and object.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kawaandClaude Opus 5.5 committed 2026-10-17 16:12:00 +02:00
1 parent acdaf62eaa
commit 3c480a28f0
17 files changed
+317 -26

No files matched your search

+4
View File
@@ -10,6 +10,9 @@ To recreate the private reference:
git clone https://github.com/pret/pokecrystal.git .reference/pokecrystal
git -C .reference/pokecrystal checkout 7a7881d0d62e0ddbd82dcf10e7116807487ac651
make -C .reference/pokecrystal crystal11 -j4
# Optional: the US 1.0 and Australian cartridges, for tests/revisions.test.ts
# and tests/reference-revisions.spec.ts.
make -C .reference/pokecrystal crystal crystal_au -j4
npm run check:reference
```
@@ -62,6 +65,7 @@ These paths refer to the pinned [PRET source](https://github.com/pret/pokecrysta
| `game/party/day-care.ts`, `game/scripts/day-care.ts`, Day-Care and Route 34 | `engine/events/daycare.asm`, `engine/pokemon/breeding.asm`, `engine/pokemon/move_mon.asm`, `engine/pokemon/breedmon_level_growth.asm`, `DayCareStep`, `_GiveOddEgg` | Deposit refusals, level growth/price, move learning on retrieval, compatibility and egg moves/DVs/species, the egg countdown/chance, collection and Odd Egg tables run from the user's ROM. Retrieval keeps the original experience truncation. The save holds both parents and the prepared egg, active/compatible bits, countdown and mother index, with flag consistency validation and absence migration. Day-Care map objects resolve their deposited species' ROM icons. Six controlled-RNG cartridge comparisons cover routine state and byte consumption; native tests cover map scripts and save/reload. Keeper UI/audio timing and fence OAM/palettes are not reference-validated. Hatching is the row above. |
| `game/party/hall-of-fame.ts`, `game/scripts/hall-of-fame.ts`, `game/scripts/pc.ts` | `engine/events/halloffame.asm` (`GetHallOfFameParty`, `_HallOfFamePC`, `LoadHOFTeam`, `DisplayHOFMon`), `engine/menus/save.asm` (`AddHallOfFameEntry`), `engine/events/pokecenter_pc.asm` (`.ChooseWhichPCListToUse`, `HallOfFamePC`) | Up to 30 recorded teams, newest first, with the capped win count; saved and migrated by absence, separate from the League flag. Nothing records a team until the League is ported. The PC lists HALL OF FAME from the count; pages browse with A, Start and B as the original does, and keep its unreachable "HOF Master!" title. A cartridge comparison of 255 teams checks the tilemap, attributes, graphics and palette; the frontpic animation (`HOF_AnimateFrontpic`) is not presented. |
| `game/scripts/league.ts`, the League, the Hall of Fame and the credits | `engine/events/halloffame.asm` (`HallOfFame`, `RedCredits`, `AnimateHallOfFame`, `AnimateHOFMonEntrance`, `HOF_SlideBackpic`, `HOF_SlideFrontpic`, `HOF_AnimatePlayerPic`), `engine/movie/credits.asm` (`Credits`, `ParseCredits`, `Credits_LoadBorderGFX`, `Credits_LYOverride`, `ConstructCreditsTilemap`, `GetCreditsPalette`), `engine/movie/init_hof_credits.asm`, `engine/events/prof_oaks_pc.asm` (`ProfOaksPCBoot`, `ProfOaksPCRating`, `Rate`, `FindOakRating`), `engine/gfx/player_gfx.asm` (`GetPlayerBackpic`, `HOF_LoadTrainerFrontpic`), `home/vblank.asm` (`VBlank_Credits`), `engine/overworld/scripting.asm` (`Script_halloffame`, `Script_credits`, `Script_wait`), `home/text.asm` (`PlaceEnemysName`) | The ceremony records the team and win, pauses the play time and shows each Pokémon's slides and page, the player's card and Oak's rating; the credits run frame by frame (text by thirds, banner tiles by halves, palette VBlanks, border scroll), with each command group's measured spill frames; after the Hall of Fame the world continues at New Bark as Continue would, after Red at Mt. Silver. Checked against the cartridge by `tests/reference-credits.spec.ts` and `tests/reference-hall-of-fame-ceremony.spec.ts`. |
| `rom/validate.ts`, `game/rom/revision.ts` | `Makefile` (`crystal`, `crystal11`, `crystal_au`: rgbfix's game code and version), `engine/events/battle_tower/load_trainer.asm` and `trainer_text.asm` (their `_CRYSTAL11` conditionals) | The three English cartridges by SHA-1, and their revision from the header. Revision 1.0 draws Battle Tower trainers from the first 21 and picks their texts' gender from the name's sixth character; the profile's addresses hold for all three (`check:reference`). |
| `game/scripts/kanto.ts` | `engine/events/specials.asm` (`SnorlaxAwake`, `TrainerHouse`), `engine/events/haircut.asm` (`BillsGrandfather`), `engine/events/diploma.asm` (`PlaceDiplomaOnScreen`, `Diploma`, `PrintDiploma`), `engine/gfx/cgb_layouts.asm` (`_CGB_Diploma`) | Snorlax wakes to the Poké Flute channel (wMapMusic) from `.ProximityCoords`; the Trainer House always fights CAL, as without a Mystery Gift partner; Bill's grandpa reads the party Pokémon shown. The Diploma is drawn from DiplomaGFX and its tilemap with the player's name in `PalPacket_Diploma`'s palette; printing it finds no printer. Checked by `tests/reference-kanto.spec.ts`. |
| `game/scripts/magnet-train.ts` | `engine/events/magnet_train.asm` (`MagnetTrain`, `MagnetTrain_Jumptable`, `MagnetTrain_UpdateLYOverrides`, `MagnetTrain_LoadGFX_PlayMusic`, `DrawMagnetTrain`, `MagnetTrainBGTiles`, `MagnetTrainTilemap`), `engine/overworld/scripting.asm` (`Script_newloadmap`'s `MAPSETUP_TRAIN`) | The ride frame by frame both ways: the player's sprite (Chris or Kris) running its animation with the last frame flipped, the bushes' and train's row scrolls, the station's palettes with an extra palette frame and eight frames of teardown. Checked against the cartridge by `tests/reference-magnet-train.spec.ts`. |
| `game/scripts/tin-tower.ts`, Tin Tower and Whirl Islands | `engine/pokemon/search_owned.asm` (`BeastsCheck`, `MonCheck`, `CheckOwnMonAnywhere`, `CheckOwnMon`) | `CheckOwnMonAnywhere` returns nothing with an empty party, then reads the party structs' species (an Egg counts as its species), `sBox` and the thirteen other `sBoxN` copies, matching the player's ID and the OT's first five letters (`NAME_LENGTH_JAPANESE - 2` compares, stopping early at a shared terminator); the Day-Care is not searched, preserving the original's explicitly documented bug even now that deposits run. The original searches the current `sBox` and skips its numbered `sBoxN` copy; the port searches each logical box once. The sages, Suicune, Ho-Oh and Lugia run on ported primitives (`BATTLETYPE_SUICUNE`, `BATTLETYPE_FORCEITEM`). `tests/tin-tower.test.ts` and two playthrough stages cover them. |
+10 -1
View File
@@ -4,7 +4,7 @@
Translate Crystal's Game Boy assembly systems into a native TypeScript game. The browser runs the translated engine; the user's original ROM supplies data and assets. The emulator is a separate development reference for checking behavior, never a dependency of the native release.
PRET's [disassembly](https://github.com/pret/pokecrystal) is pinned at `7a7881d0d62e0ddbd82dcf10e7116807487ac651`. Its `crystal11` build with RGBDS 1.0.3 was verified byte-for-byte against the supplied English US/Europe 1.1 ROM. Required SHA-1: `f2f52230b536214ef7c9924f483392993e226cfb`. Other revisions require separate verified profiles.
PRET's [disassembly](https://github.com/pret/pokecrystal) is pinned at `7a7881d0d62e0ddbd82dcf10e7116807487ac651`. Its `crystal11` build with RGBDS 1.0.3 was verified byte-for-byte against the supplied English US/Europe 1.1 ROM (SHA-1 `f2f52230b536214ef7c9924f483392993e226cfb`). Its `crystal` and `crystal_au` builds reproduce the retail English 1.0 (`f4cd194bdee0d04ca4eac29e09b8e4e9d818c133`) and Australian (`a0fc810f1d4e124434f7be2c989ab5b5892ddf36`) cartridges, which the same profile reads (board #84). Other languages require their own verified profiles.
The emulator-backed prototype is now at `/reference.html`. The default application is the native port. The previous plan to progressively modify an emulated ROM has been superseded.
@@ -549,6 +549,15 @@ The numbered sections below keep their full scope. Each one opens with a checkli
- Tests: `tests/kanto.test.ts` (Snorlax's coordinates, 2×2 block and flute battle; Bill's grandpa's Everstone; the Trainer House's CAL; the Magnet Train both ways; the Diploma and its printer; Oak opening Mt. Silver; the move tutor; the rival in Mt. Moon and at Indigo Plateau on Mondays but not Tuesdays). The playthrough continues with fourteen stages: the S.S. Aqua, the eight Kanto badges in the order Thunder, Marsh, Cascade (with the Power Plant's manager, the Machine Part and Misty's date), Boulder (after the power returns, Rock Tunnel, the EXPN card and Snorlax), Volcano, Soul (Blue on Cinnabar), Rainbow (Cycling Road) and Earth, Oak opening Mt. Silver, training outside Silver Cave, TM26 from Victory Road, and Red with the credits, ending at `SPAWN_MT_SILVER`. Test saves: `vermilion-city`, `saffron-city`, `celadon-city`, `mt-silver`, `red-beaten`.
- Not presented: Mystery Gift's Trainer House opponents and printing; the Diploma's B prompt cursor (the page has no ▼).
## Implemented: the other English cartridges (board #84, increment A)
- Accepted: the English US/Europe revisions 1.1 and 1.0 and the Australian release (`src/rom/validate.ts`), the three cartridges PRET rebuilds byte for byte. Every label the profile pins has the same address in all three; `check:reference` now verifies that against `pokecrystal.sym` and `pokecrystal_au.sym` whenever those rebuilds are present, and checks their hashes.
- `romRevision` (`game/rom/revision.ts`) tells them apart from the header (game code BYTE or BYTU, mask ROM version 0 or 1). Revision 1.0's two Battle Tower bugs are reproduced: `LoadOpponentTrainerAndPokemon` draws only the first 21 trainers (BATTLETOWER_NUM_UNIQUE_MON), and `BattleTowerText` indexes `BTTrainerClassGenders` with the sixth character of the trainer's name. The Australian release differs only in the Game Corners' and Celadon's texts and one Buena call, which come from the ROM.
- Saves: each cartridge keeps its own list (slots are keyed by the ROM's SHA-1), and a native backup from one of the others imports, with a "Cartridge" line in the preview; the three share every map, event and object, so nothing is converted. Cartridge `.sav` files have the same layout in all three.
- Reference: `tests/reference-revisions.spec.ts` runs the cartridge's `BattleTowerText` on 1.1, 1.0 and the Australian rebuild for every trainer, six random values and the three texts. Tests: `tests/revisions.test.ts` (each cartridge is accepted under its name and recognised from its header, a changed byte is refused, the Battle Tower's trainer range), `tests/save-slots.test.ts` (a backup carried over between cartridges). The whole unit suite and the playthrough from the introduction to Red pass with `CRYSTAL_ROM_PATH` set to each rebuild (only the private CI downloader's 1.1 check is specific).
- Not affected: 1.0's other differences, the Pokédex's `wPokedexStatus` sharing a byte with `wPrevDexEntryBackup` (it misplaces the cursor after a search result's entry; the search mode is not ported) and the mobile Stadium 2 tilemap.
- Not supported: the French, German, Italian, Spanish and Japanese releases. PRET builds none of them, and no copy was available to verify a profile against; each needs its own addresses, character set and name lengths (the Japanese release most of all).
## Native battles: current state
The battle core, ROM tables, encounter hooks, battle UI and whiteout hooks are present. Unit tests cover wins, escape, loss, experience, move learning and capture; reference tests compare damage, type effectiveness, stat calculation and experience curves. Browser tests drive a test-only wild encounter through the real UI: victory with level-up and move learning, escape, whiteout, catching with a nickname, keyboard and on-screen D-pad menu navigation, mid-battle backup restore, rollback of unsupported effects, switching through the party menu and a Potion from the Items pocket. Real Route 29 encounters now use the ROM's encounter tables. Every ball can be thrown; only the contest's Park Ball handling remains.