Port capture and the Route 29 catching tutorial
Checks / web (push) Canceled after 0s
Checks / web (pull_request) Canceled after 0s

Battle PACK opens the Balls pocket and runs PokeBallEffect: the Poké,
Great, Ultra and Master Ball multipliers, the original HP arithmetic
(including the overflow above 341 maximum HP), the sleep/freeze bonus
(BRN/PSN/PAR add nothing), HELD_CATCH_CHANCE and the catch draw.
GetPokeBallWobble draws per shake from WobbleProbabilities and picks the
break-free text. Trainer battles block the ball but still use it and the
turn.

A catch reloads the Pokémon as LoadEnemyMon does (the wild item roll is
redrawn, then the item restored), keeps its HP, status, item and DVs,
restores the moves and PP it appeared with, adds it to the party with
SetCaughtData, registers it and offers a nickname with InitName's
default. A catch with six Pokémon needs the PC and is refused.

catchtutorial runs BATTLETYPE_TUTORIAL as "DUDE": no send-out, an
automatic catch that keeps nothing and prompts that continue on their
own. Both Route 29 triggers, declining and the Dude's repeat offer run
from the ROM. The text reader now handles TX_LOW.

PLAN.md gains a status overview and done/remaining checklists; the
README, help dialog, routine map and handoff describe the milestone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-09-24 20:57:36 +02:00
1 parent dc10343520
commit 9ac111f262
20 files changed
+1101 -65

No files matched your search

+89 -5
View File
@@ -8,6 +8,24 @@ PRET's [disassembly](https://github.com/pret/pokecrystal) is pinned at `7a7881d0
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.
## Status overview
| Area | Status |
| ---------------------------------------------------------------------------- | --------------------------------------- |
| Exploration foundation, rendering, saves and shell | Done |
| Opening story: New Bark Town to Mr. Pokémon, the rival and the return to Elm | Done |
| Route 29, Cherrygrove City, Route 30 and their buildings | Done |
| Wild and trainer battles, capture and the catching tutorial | Done for the areas that are open |
| 1. Complete the overworld foundation | In progress |
| 2. Opening story and first battle slice | Mostly done |
| 3. Complete Crystal | Early |
| 4. Modern mobile presentation and delivery | First increment done |
| 5. World map and Pokédex | Not started (current-area minimap only) |
| 6. Internet Link and friends | Not started |
| 7. Optional Pokéwalker-style egg assistance | Not started |
The numbered sections below keep their full scope. Each one opens with a checklist: `[x]` is done and tested, `[ ]` is remaining. The "Implemented" sections record what each completed increment delivered.
## Implemented: first native exploration milestone
- Bounds-checked ROM access, banked pointers and native LZ decompression.
@@ -57,7 +75,7 @@ The emulator-backed prototype is now at `/reference.html`. The default applicati
- The battle engine gained `recoil` (Struggle). A local stress run of 360 Route 29 battles across all starters and times of day finishes without refusals.
- Save format 3 gains `fruitTrees`, `dailyReset` and `lastSpawnMap`; older backups migrate by absence.
- NPCs roam as `HandleNPCStep` does: random walks (Y, X, XY) and slow/fast spins from `SpriteMovementData`, `CanObjectMoveInDirection` (side walls, land, objects' current and previous tiles, radius stored plus one, screen edge), random sleeps, freezing during text and `applymovement`, and deletion/respawn at home beyond the object window. Wandering positions are not saved; objects start from home on reload.
- Still refused: the catching tutorial (`catchtutorial`), reachable after the Mystery Egg errand.
- The catching tutorial (`catchtutorial`) runs since the capture section below.
## Implemented: first scripted trainer battle slice
@@ -92,14 +110,38 @@ The emulator-backed prototype is now at `/reference.html`. The default applicati
- Save format 3 gained `rivalName` and `specialPhoneCall` (migrated by absence to "???" and 0).
- Next: the catching tutorial on Route 29 (`catchtutorial`) with capture; then player switching and items in battle.
## In progress: native battles
## Implemented: capture and the catching tutorial
The battle core, ROM tables, encounter hooks, battle UI and whiteout hooks are present. Unit tests cover wins, escape, loss, experience and move learning; reference tests compare damage and type effectiveness. Browser tests drive a test-only wild encounter through the real UI: victory with level-up and move learning, escape, whiteout, keyboard and on-screen D-pad menu navigation, mid-battle backup restore, and rollback of unsupported effects. Real Route 29 encounters now use the ROM's encounter tables. Capture, player switching, items in battle and the rest of the opening quest remain unfinished.
- Battle PACK opens the Balls pocket. Throwing a ball runs `PokeBallEffect`: the catch rate with the Great/Ultra multipliers and the original HP arithmetic, the sleep/freeze bonus and `HELD_CATCH_CHANCE`, then one `Random` draw. Master Balls always catch. The original bugs are kept: burn, poison and paralysis add nothing, and a maximum HP above 341 overflows the formula. A maximum HP of 342 would divide by zero and is refused.
- `GetPokeBallWobble` runs with `WobbleProbabilities` for each shake and picks the break-free message. Every throw uses the ball and, if the Pokémon breaks free, the turn. In trainer battles the ball is blocked, but the ball and turn are still used.
- A caught Pokémon is reloaded as `LoadEnemyMon` does, which redraws the wild item roll (the item itself is kept). It keeps its current HP, status, item and DVs, and gets back the moves and full PP it appeared with. It joins the party with `SetCaughtData`, is registered as caught (with the new-data message once the Pokédex is owned) and can be nicknamed; a blank name keeps the species name. The Pokédex page itself is not presented yet.
- Route 29's `Route29Tutorial1/2` and `CatchingTutorialDudeScript` run from the ROM. `catchtutorial` runs the battle as "DUDE": no Pokémon is sent out, the Dude's own Poké Ball always catches, and the Rattata is only seen, not kept. Messages advance on their own, as with `CatchTutorial`'s auto input.
- A catch with six Pokémon in the party would go to the PC (`SendMonIntoBox`), which is not ported, so the battle is refused and discarded. Other balls (Kurt's balls, Park and Safari) and non-ball items in battle are not usable yet.
- A local stress run of 2,160 wild battles (three starters, ten early species, six levels) caught 2,047 Pokémon without refusals.
- Next: the PC and boxes, player switching and other items in battle, then party and bag menus.
This is still not a complete new game. Party/bag/Pokégear menus, story progression beyond Cherrygrove, decorations, animated terrain, surfing and audio remain unfinished. Save slots, a Johto/Kanto atlas, Pokédex records, online Link, friends and real-world steps come later.
## 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 and type effectiveness. 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, and rollback of unsupported effects. Real Route 29 encounters now use the ROM's encounter tables. Player switching, items other than balls in battle and the PC remain unfinished.
This is still not a complete new game. Party/bag/Pokégear menus, the PC, story progression beyond Route 30 and Mr. Pokémon's house, decorations, animated terrain, surfing and audio remain unfinished. Save slots, a Johto/Kanto atlas, Pokédex records, online Link, friends and real-world steps come later.
## 1. Complete the overworld foundation
- [x] Map headers for all 26 groups, location names, connection offsets and connected-border drawing
- [x] Walking, collisions, doors, stairs, ledges and directional warp mats
- [x] Coordinate events, scene scripts, map callbacks and scripted movement
- [x] NPC random walks and spins, trainer sight lines
- [x] Item balls, hidden items and fruit trees with the daily reset
- [x] Connected transitions for every enabled map (New Bark Town to Route 30)
- [ ] Dynamic warps, elevators, ice, currents and the remaining forced movement
- [ ] Surfing, cycling, Cut trees and Strength boulders
- [ ] Decorations and tile changes (`changeblock`)
- [ ] Remaining NPC movement types (followers, bouncing) and movement commands
- [ ] Terrain animation, layering and special palettes
- [ ] Reference comparison of player turn timing
- [ ] Acceptance: outdoor, interior, cave and connected-map traces match the reference engine
Map headers, location names, connection offsets, connected-border drawing, coordinate events, scene scripts, map callbacks and scripted movement are in place (see above). Next: enable connected transitions as their maps are ported; add dynamic warps, elevators, ice, currents, remaining forced movement, surfing, cycling, cut trees and boulders. Player turn timing still needs a reference comparison.
Port decorations, tile changes (`changeblock`), the remaining NPC movement types (followers, bouncing, Strength boulders) and the remaining movement commands. Complete terrain animation, layering and special palettes. Record deviations from the original until a comparison test closes them.
@@ -108,11 +150,26 @@ Acceptance: representative outdoor/interior/cave/connected-map traces produce ma
## 2. Opening story and first battle slice
- [x] Native player, party, Pokémon, bag, money and quest models with versioned saves
- [x] Typed ROM decoders for species, moves, growth rates, items, encounters and trainers
- [ ] Decoder for evolutions (not needed before the first evolution)
- [x] Mom, Elm's introduction, the starter, naming and the aide's Potion
- [x] Route 29, Cherrygrove City, the Poké Mart and the Pokémon Center
- [x] Route 30's trainers, Mr. Pokémon's house, the Mystery Egg and the Pokédex
- [x] The Cherrygrove rival battle, Elm's call and the return to Elm
- [x] Capture and the catching tutorial
- [x] Battles: stats, damage, types, accuracy, criticals, status, turn order, fainting, experience, move learning, trainer AI, trainer send-outs and prize money
- [ ] Player switching, and items other than balls, in battle
- [ ] The PC and boxes (catching with a full party)
- [ ] The introduction's naming and clock screens
- [ ] Controlled-seed comparisons with the original beyond damage and type effectiveness
- [ ] Acceptance: one continuous playthrough of the opening quest with save/reload. The scenes are tested individually from fixtures so far.
Introduce native player, party, Pokémon, inventory, money and quest models. Read species, moves, growth curves, evolutions, encounters, trainers and items through typed ROM decoders. Define serialization/migrations before persisting new systems.
Expand script calls, choices, scene state, inventory commands and native special handlers. Translate routines reached through assembly calls into explicit native services; never fall back to emulator execution in the shipping game.
Meeting Mom, Elm's introduction, the starter, the aide's Potion, Route 29, Cherrygrove, Route 30's trainers, Mr. Pokémon's house, the Cherrygrove rival battle and the return to Elm run now. Next: capture and the catching tutorial; then the introduction's naming and clock screens.
Meeting Mom, Elm's introduction, the starter, the aide's Potion, Route 29, Cherrygrove, Route 30's trainers, Mr. Pokémon's house, the Cherrygrove rival battle, the return to Elm, capture and the catching tutorial run now. Next: the PC, then the introduction's naming and clock screens.
Complete and validate the native battle engine: deterministic randomness, stats, move selection, accuracy/critical checks, damage, status, turn order, switching, fainting, experience, capture and rewards. Compare controlled seeds and states with the original, including integer rounding and overflow behavior.
@@ -120,6 +177,14 @@ Acceptance: finish the opening quest, including encounters and the rival battle,
## 3. Complete Crystal
- [x] Pokémon Center healing, standard Poké Marts and Reflect/Light Screen
- [ ] Remaining battle commands, move and item effects, AI layers and special battles
- [ ] Evolution, breeding, happiness, eggs and PC storage
- [ ] Field moves, gyms, Rocket events, the phone and Pokégear, puzzles, minigames, daily events, roaming Pokémon and the postgame
- [ ] Johto beyond Route 30, the League, Kanto and the final battle
- [ ] Music and sound through Web Audio
- [ ] Acceptance: main-game and postgame playthroughs, battle regression vectors, long sessions and save recovery
Port remaining battle commands, move/item effects, AI, special battles, evolutions, breeding, happiness, eggs and PC storage. Gen II behavior is the baseline; list intentional changes separately.
Complete field moves, gyms, Rocket events, phone/Pokégear, shops, healing, puzzles, minigames, daily events, roaming Pokémon and postgame. Cover Johto, the League, Kanto and the final battle. Track unsupported script/special handlers and add fixtures before translating each one.
@@ -130,6 +195,16 @@ Acceptance: main-game/postgame playthroughs, representative optional content, ba
## 4. Modern mobile presentation and delivery
- [x] Crystal-style shell with Game, Savegames, Map, Pokédex, Link and Friends tabs
- [x] Adaptive canvas, live local minimap, keyboard and on-screen controls
- [x] Save, backup export and import for the single native save
- [x] Touch battle commands, move list, PACK (Balls pocket) and naming fields
- [ ] Party, pack, PC and Pokégear menus outside battle
- [ ] Scalable text, configurable controls and fuller accessibility
- [ ] Save slots with migration, atomic writes and import previews
- [ ] Installable web app with offline app shell, safe updates and quota handling
- [ ] Acceptance on physical iPhone and Android devices
The first presentation increment replaces the landing page and handheld frame with a restrained Crystal-style interface. Game, Savegames, Map, Pokédex, Link and Friends stay above a viewport-filling native canvas. The renderer draws more world tiles as space grows instead of stretching a 160 × 144 image. The game and Map tab share a live local minimap; the atlas and unsupported tabs remain honest planned states. The linked UI reference could not be inspected through automated access because the site returned a Cloudflare challenge, so exact screenshot matching is not claimed.
Build touch interfaces directly over native models: party, pack, battle commands, PC and Pokégear. Keep UI separate from gameplay calculations. Add scalable text, configurable controls and accessible focus/announcements.
@@ -146,6 +221,11 @@ Acceptance: installation, offline startup, portrait/landscape, touch/audio, back
## 5. World map and Pokédex
- [x] Current-area minimap in the game and Map tab
- [x] Seen and caught sets saved from real game state
- [ ] Johto/Kanto atlas with visited areas and Fly destinations
- [ ] Pokédex tab with ROM-derived records and habitat views
Promote the current-area minimap into a Johto/Kanto atlas after all map groups, connections and location names can be decoded from the selected ROM. Derive region geometry, visited areas, player location and Fly destinations from native map and story state. Do not ship copied map artwork or claim navigation through maps whose collisions and events are still unsupported.
Build the Pokédex from typed ROM decoders for species names, base data, evolutions, moves and graphics. Seen, caught, forms and habitat or area views must come from native game state and encounter tables. Keep ROM-derived records unavailable until a verified ROM is selected.
@@ -156,6 +236,8 @@ Acceptance: atlas positions and Pokédex records match pinned PRET fixtures and
## 6. Internet Link and friends
- [ ] Not started. Link and Friends tabs show their planned scope only.
Implement a game-level protocol over native state. This architecture does not need to tunnel serial timing or synchronize GB CPU cycles.
Separate `LinkTransport`, `TradeSession` and `BattleSession`. Start with local peers, then private invite rooms using signaling and WebRTC data channels or a relay. Negotiate compatible schema/game versions and exchange only required game data. Never transmit ROMs or extracted assets.
@@ -170,6 +252,8 @@ Acceptance: cross-network trades/battles and induced duplicate messages, latency
## 7. Optional Pokéwalker-style egg assistance
- [ ] Not started. Depends on eggs, hatching and a native companion app.
This optional mobile feature uses real-world walking to assist egg hatching after native party, breeding, eggs and faithful in-game hatching are complete. The pinned Crystal engine decrements party egg counters from overworld walking in [`CountStep`](https://github.com/pret/pokecrystal/blob/7a7881d0d62e0ddbd82dcf10e7116807487ac651/engine/overworld/events.asm#L866-L900) and [`DoEggStep`](https://github.com/pret/pokecrystal/blob/7a7881d0d62e0ddbd82dcf10e7116807487ac651/engine/pokemon/breeding.asm#L174-L196); battles do not advance them. A battle-based bonus would therefore be an explicit, separately enabled extension rather than Crystal behavior.
Separate a platform `StepProvider`, local activity ledger and reward rules. Request read access to steps only, after an explicit explanation and opt-in. Keep real-world steps distinct from the in-game tile counter, show what interval will be credited and provide a disconnect/delete control. Do not request distance, heart rate, workouts or permission to write health records. Keep raw activity data on device by default.