Open the League: Victory Road, the Elite Four, the Hall of Fame and the credits (#33)
Routes 26 and 27 with their houses, Tohjo Falls, the Victory Road gate, Victory Road, Route 23, Indigo Plateau, the Elite Four's rooms, Lance's room and the Hall of Fame are open. - halloffame (game/scripts/league.ts): the music fades as SAVING RECORD shows, the win and the team (without Eggs) are recorded, each Pokémon's back picture passes and its front picture slides in for its "New Hall of Famer!" page and cry, then the player's card with the play time and Professor Oak's rating; the play time stops meanwhile. The world then continues at New Bark as Continue does after the cartridge's reset. - credits and the credits after the Hall of Fame (CreditsMachine): the ROM's script, strings, banner Pokémon and THE END, frame by frame as VBlank_Credits presents them, with the frames each command group runs over measured on the cartridge. B shortens credits seen before. - wait, appear/disappear of the player, and rival names in battle texts (PlaceEnemysName prints wRivalName alone: "???" before he is named). - The tile-screen renderer wraps hSCX/hSCY at 256 pixels and gives rows their own hSCX. - Reference: the credits match the cartridge on every frame (BG map, banner tiles, CRAM palettes, LY overrides, parser), with and without B; the ceremony's pages match for every species and the player's card for Chris and Kris. - Playthrough: five stages from Tin Tower to the Hall of Fame (HM07 from Ice Path, Tohjo Falls' waterfall, Victory Road's ladders, the Elite Four and Lance); the driver follows warps within a map and fights carefully from here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b6fdc23508
commit
f05fd8ebee
23 files changed
+1943
-107
No files matched your search
@@ -61,6 +61,7 @@ These paths refer to the pinned [PRET source](https://github.com/pret/pokecrysta
|
||||
| `game/scripts/blackthorn.ts`, the Radio Tower takeover, Ice Path, Blackthorn and Dragon's Den | `engine/events/dratini.asm` (`GiveDratini`), `engine/events/move_deleter.asm` (`MoveDeletion`), `engine/pokemon/mon_menu.asm` (`ChooseMoveToDelete`), `engine/events/whiteout.asm` (`Script_Whiteout`), `data/maps/setup_scripts.asm` (`MapSetupScript_Continue`) | `GiveDratini` searches the party backwards by species and writes `.Movesets` 0 (WRAP, THUNDER WAVE, TWISTER, EXTREMESPEED) or 1 with each move's base PP; a value of 2 or more changes nothing. `MoveDeletion` follows the routine's order of questions; `ChooseMoveToDelete` is shown as a list of the moves, and `.DeleteMove` shifts the later moves and PP bytes, PP Ups included. A save records objects whose visibility no longer matches their flags: `MapSetupScript_Continue` skips `LoadMapObjects`, so a flagless object a script made disappear (the Radio Tower director) stays gone after Continue and one that appeared with its flag set stays visible; a later visit rebuilds them from the map. A battle lost inside an `scall` jumps to `Script_Whiteout` without unwinding; its `newloadmap` is followed by `endall`, which drops the caller. The switch room's doors, the warehouse's reset, the Ice Path and Blackthorn Gym stone tables, whirlpools and the Dragon Shrine quiz run on ported primitives. `tests/blackthorn.test.ts`, `tests/radio-tower.test.ts` and six playthrough stages cover them. |
|
||||
| `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`. |
|
||||
| `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. |
|
||||
| `game/scripts/battle-tower.ts`, the Battle Tower | `engine/events/battle_tower/battle_tower.asm` (`BattleTowerAction`, `RunBattleTowerTrainer`, `ReadBTTrainerParty`, `CopyBTTrainer_FromBT_OT_TowBT_OTTemp`, `BattleTower_GiveReward`, `BattleTower_RandomlyChooseReward`, `LoadOpponentTrainerAndPokemonWithOTSprite`, `CheckForBattleTowerRules`), `engine/events/battle_tower/load_trainer.asm`, `engine/events/battle_tower/rules.asm`, `engine/events/battle_tower/trainer_text.asm`, `mobile/mobile_46.asm` (`_BattleTowerRoomMenu`, `BattleTower_LevelCheck`, `BattleTower_UbersCheck`), `mobile/mobile_5f.asm` (`Menu_ChallengeExplanationCancel`), `engine/link/link.asm` (`TryQuickSave`), `engine/battle/core.asm`, `engine/battle/effect_commands.asm`, `engine/battle/misc.asm` (`DoBadgeTypeBoosts`) | The Battle Tower's SRAM and the work RAM its scripts share are saved as `battleTower`. The trainer sampler keeps its index as the running byte after a repeated trainer; the Pokémon sampler starts again from `hRandomAdd`; both fold `Random`'s `hRandomAdd` into a byte below a power-of-two mask, which the port draws from its random source. `BattleTowerText` reads the class's gender (1.1 behaviour) and picks the greeting from `hRandomAdd` (0-24 male, 0-14 female), keeping it for the end texts. Each battle start counts the battle and marks the challenge in progress, as `CopyBTTrainer_FromBT_OT_TowBT_OTTemp` does; `LoadPokemonData` then returns the party, Pokédex and Unown Dex to the quick save's. The level menu shows the levels as a list; its CANCEL/B question and the mobile code's YES/NO flow are modelled from their outcomes (YES leaves with $a, NO picks a level again). `TryQuickSave` asks the overwrite question for the player's own save and shows the saving texts; the port keeps the place and Pokémon data `LoadPokemonData` and `Reset` return to. The native game saves itself, so the original's "left without saving" state (a reset during a challenge) cannot arise: a reload replays the room's script. `Reset` returns the player to the quick save's place with the 1F scene set to check the challenge; the original's rollback of money gained by Pay Day is not reproduced. In battle, `wInBattleTowerBattle` turns off obedience, `DoBadgeTypeBoosts`, `BadgeStatBoosts`, experience, the pack (BattleMenu_Pack says items can't be used), AI items and prize money, uses Falkner's AI attributes, keeps Sleep to `%011` and skips the AI's random failure for Sleep, Poison, stat-lowering and Paralyze moves; a loss shows BattleTowerText and does not white out. `DoBadgeTypeBoosts` was added to every battle (it was missing). BATTLETOWERACTION_LEVEL_CHECK and _UBERS_CHECK and the mobile actions are reached only from unreferenced scripts and stay refused. `tests/battle-tower.test.ts`, `tests/battle-tower-engine.test.ts` and `tests/reference-badges.spec.ts` cover them. |
|
||||
| `game/scripts/slot-machine.ts`, `game/scripts/card-flip.ts` | `engine/games/slot_machine.asm`, `engine/games/card_flip.asm`, `engine/gfx/cgb_layouts.asm` | Both on a realtime tile screen (two frames per tick, buffered buttons). Slots: reel strips, spin rates and scrolling, bias tables with the lucky machine and seven streak, reel 3's Golem and Chansey replay with their sprites, payouts. Card Flip: deck, 12×11 board, cursor sprites and `ChooseCard_HandleJoypad`, paytable. Tilemaps, all 48 cursor positions, selected reel states and whole Golem/Chansey/Egg sequences are checked against the ROM (`tests/reference-game-corner.spec.ts`, which runs `CardFlip_UpdateCursorOAM`, `Slots_UpdateReelPositionAndOAM`/`.SpinReel` and the sprite-animation engine's own Golem/Chansey/Egg routines): the cursor, the reel symbols and the three creatures each anchor an OAM-relative pixel pair 8 (x) and 16 (y) beyond the screen's, as `cursorSprites` reads; `depixel`'s own two arguments end up swapped by `_InitSpriteAnimStruct` (confirmed against the reference emulator), so Golem/Chansey/Egg's X and Y bases were swapped to match, and Golem's own OAM table X-flips its right half. `PlaySpriteAnimations` is compared frame by frame over a three-Golem run and a Chansey round with two eggs (shadow OAM, `wSlotsDelay` and `hSCY`): frames last 8 ticks (the first draw plus 7 decrements); Golem's frames 3 and 4 flip the whole OAM set (offsets become −8−offset); a sprite removed by `DeinitializeSprite` is still drawn that tick, because `UpdateAnimFrame` runs after the animation function; the Golem's roll toggles `hSCY` by ±2, which the tile screen shows with the space tiles `_SlotMachine` filled the BG map with. The rows scrolled in use palette 0, since the attribute map beyond row 18 is not reproduced. No sound. |
|
||||
|
||||
+13
-2
@@ -515,7 +515,7 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
## Implemented: the Hall of Fame PC (board #29)
|
||||
|
||||
- `wHallOfFameCount` and `sHallOfFame` are saved as `hallOfFameCount` and `hallOfFameTeams` (newest first, at most 30 teams of up to six Pokémon with species, ID, DVs, level and nickname), migrated by absence to none and validated against each other. They are separate from `hallOfFame` (`STATUSFLAGS_HALL_OF_FAME_F`), which the Battle Tower, radio, Pokégear and marts read.
|
||||
- `GetHallOfFameParty` (Eggs left out) and `AddHallOfFameEntry` (the oldest of 30 teams drops off, the count stops at 200) are ported as `addHallOfFameEntry`, but nothing calls it until the League's ceremony is ported.
|
||||
- `GetHallOfFameParty` (Eggs left out) and `AddHallOfFameEntry` (the oldest of 30 teams drops off, the count stops at 200) are ported as `addHallOfFameEntry`, which the League's ceremony calls (below).
|
||||
- `PokemonCenterPC.ChooseWhichPCListToUse` picks `PCPC_POSTGAME` from the count, as the original does, so HALL OF FAME appears once a team is recorded. `_HallOfFamePC`, `LoadHOFTeam` and `DisplayHOFMon` show each Pokémon's page with its cry: A shows the next Pokémon, then the next team; Start skips to the next team; B returns to the PC. The original's unreachable "HOF Master!" title (it needs a count of 201) is kept.
|
||||
- `tests/reference-hall-of-fame.spec.ts` writes 255 teams (every species, Unown, level 100, the Nidorans, win 200, all eight frames) into the cartridge's SRAM, runs its `_HallOfFamePC`, and compares the tilemap, attributes, graphics and palette with the port's page. `HOF_AnimateFrontpic` is the one routine stubbed: the port shows the picture at rest, without the `ANIM_MON_HOF` animation. `tests/hall-of-fame.test.ts` covers the records, the PC menu with and without them, browsing, and save, reload and migration.
|
||||
|
||||
@@ -528,11 +528,22 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
- Refused with the reason: unported maps, the Bug-Catching Contest, a Battle Tower challenge in progress, characters outside the naming screen (traded Japanese names, ligatures). Not carried over, with a note in the preview: the tiles walked count, Mystery Gift items, link battle records; time-windowed objects follow the clock again.
|
||||
- Savegames → Import backup reads `.sav`/`.srm`/`.dat` files (or any 32 KiB non-JSON file), previews trainer, place, progress, which copy and clock were used and the notes, then adds or replaces a save like a native backup (`SlotSession.previewCartridge`). Tests: `tests/cartridge-save.test.ts` (the committed real `.sav` and Virtual Console `sav.dat`, backup fallback, clock footers, day counters, refusals), `tests/save-slots.test.ts` and `tests/save-slots-browser.spec.ts`.
|
||||
|
||||
## Implemented: the League, the Hall of Fame and the credits (board #33, increment A)
|
||||
|
||||
- Open: Routes 26 and 27 with their three houses, Tohjo Falls, the Victory Road gate (badge check), Victory Road with the rival, Route 23, Indigo Plateau's Pokémon Center and mart, the Elite Four's rooms (doors that lock and open), Lance's room with Mary and Oak's scene, and the Hall of Fame. Route 22, Route 28 and the rest of Kanto stay closed.
|
||||
- `halloffame` (`HallOfFame`, `game/scripts/league.ts`): the music fades as "SAVING RECORD…" shows for 100 frames, `STATUSFLAGS_HALL_OF_FAME_F` is set and the League win and team recorded (`addHallOfFameEntry`), `MUSIC_HALL_OF_FAME` plays, each Pokémon's back picture passes (`HOF_SlideBackpic`, hSCX $90 to $70 by 4) and its front picture slides in (`HOF_SlideFrontpic`) before its "New Hall of Famer!" page and cry (60 frames), then the player's pictures, name, ID and play time (`HOF_AnimatePlayerPic`) with `ProfOaksPCRating`'s count, rating text (drawn into the text box from the ROM's characters, so ligatures keep their one tile) and sound; then the credits. `GAME_TIMER_COUNTING_F` is cleared meanwhile. The cartridge saves and resets after the credits and Continue spawns at New Bark (`SPAWN_LANCE` → `SPAWN_NEW_BARK`, `MAPSETUP_WARP`, `JumpRoamMons`); the port has no title screen and continues there directly; its own save is the script's committed state, so a reload during the ceremony replays it from the Hall of Fame's entrance, counting the win once.
|
||||
- `credits` (`RedCredits`) and the credits themselves (`CreditsMachine`): `CreditsScript`'s strings, scenes and waits from the ROM, the four banner Pokémon's frames, the scrolling borders and THE END, presented as VBlank_Credits does (the text a third of the screen per VBlank, eight banner tiles per VBlank, a palette change taking its whole VBlank, the bottom border scrolled one frame before the top). How many frames each group of commands takes on the cartridge depends on `_UpdateSound`'s work within VBlank, so the 46 groups' spills are recorded as measured. B shortens credits seen before (from a second League win, and after Red); A closes them after THE END. The port reads B pressed rather than held.
|
||||
- `wait` (Script_wait: six frames, `n` times) and `disappear`/`appear` of the player (the sprite is gone until the map loads again) are ported. Battle texts now name a rival (RIVAL1, RIVAL2) by `wRivalName` alone, as `PlaceEnemysName` does: "??? wants to battle!" in Cherrygrove, "SILVER wants to battle!" later (the port printed "RIVAL ?").
|
||||
- The tile-screen renderer reads the background line by line, wrapping at 256 pixels as hSCX and hSCY do, and gives rows their own hSCX (`rowScroll`, wLYOverrides).
|
||||
- Reference: `tests/reference-credits.spec.ts` runs the cartridge's `InitDisplayForRedCredits` and `Credits` with interrupts after a boot and compares every frame (about 7,000, past THE END) with `CreditsMachine`: the displayed BG map, the banner's tiles, the palettes in CRAM, wLYOverrides and the parser where it rests; once without B and once with B held. `tests/reference-hall-of-fame-ceremony.spec.ts` compares `DisplayNewHallOfFamer` for every species and `HOF_AnimatePlayerPic`'s card for Chris and Kris (tilemap, displayed attributes, palette and tiles) with only frame waits, `HOF_AnimateFrontpic` and `ProfOaksPCRating` stubbed.
|
||||
- Tests: `tests/league.test.ts` (Route 27's first step into Kanto, the gate's badge check, the ceremony's records without Eggs, the paused play time, the 200-win cap and 30 teams, B on the credits, the text-box decoder, the renderer's wrap and row scroll). The playthrough gains five stages: back to Ice Path for HM07, home to New Bark, Route 27, Tohjo Falls' waterfall, Route 26 and Victory Road, Indigo Plateau and the Elite Four, Lance and the Hall of Fame (the driver now fights carefully from here: accuracy-weighed moves, Full Heals for poison, paralysis and burns, healing below two thirds). Test saves: `indigo-plateau`, `hall-of-fame-new-bark`, `hall-of-fame-ceremony`.
|
||||
- Not presented: `ANIM_MON_HOF` (pictures at rest, as in the PC), the credits' first 36 frames of setup are shown white without their exact frame count, the rating text appears whole rather than letter by letter. The Plateau's rival (after Mt. Moon) and Kanto are increments B and C.
|
||||
|
||||
## 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.
|
||||
|
||||
This is still not a complete new game. The Pokégear's radio, the Pokédex's area view, search and other modes, the League, Kanto and the postgame remain unfinished. The start menu opens the party menu and the pack, and Select uses the registered item, such as the Bicycle; the PCs store Pokémon, items and decorations. Surfing and terrain animation now have native implementations; Kanto's maps remain gated. Save slots, online Link, friends and real-world steps come later.
|
||||
This is still not a complete new game. The Pokédex's area view, search and other modes, Kanto and the postgame remain unfinished. The start menu opens the party menu and the pack, and Select uses the registered item, such as the Bicycle; the PCs store Pokémon, items and decorations. Surfing and terrain animation now have native implementations; Kanto's maps remain gated. Save slots, online Link, friends and real-world steps come later.
|
||||
|
||||
## 1. Complete the overworld foundation
|
||||
|
||||
|
||||
Reference in new issue
Block a user