Port weather, copying moves, held items and obedience (#28)
Checks / web (push) Canceled after 0s

Complete the weather, Substitute, Transform, called-move and forced-switch effects. Add held-item behavior, Exp. Share awards and badge-based traded Pokemon obedience, and persist trainer berry consumption.

Validated with 576 passing unit tests and 149 browser tests, native/reference builds, reference/vendor/release checks and 320 Metal Powder emulator comparisons per browser. Smart AI and special balls/battle types remain on #28.
This commit is contained in:
Sébastien QUEROL committed 2026-10-03 15:03:19 +02:00
1 parent 8f5b464efc
commit 32d736ecae
13 files changed
+1509 -75

No files matched your search

+17
View File
@@ -282,6 +282,23 @@ The numbered sections below keep their full scope. Each one opens with a checkli
- The trainer's party struct now follows its Pokémon where the original updates it (`UpdateEnemyMonInParty`: status changes, heals, waking up), and moves used by the enemy spend PP in its party struct or in `wWildMonPP`, so a caught Pokémon keeps the PP it used and a trainer's Pokémon sent back in keeps its spent PP.
- A move missing from its user's move list (after Metronome, for instance) is refused by Spite, Disable and Encore, which search on past the list in the original.
## Implemented: weather, substitutes and moves that copy or switch
- Rain Dance and Sunny Day (renewed when used again) and Sandstorm (which fails when already raging) last five turns with the original messages between turns; a sandstorm hurts all but Rock, Ground, Steel and digging Pokémon. `DoWeatherModifiers` scales Water and Fire damage before STAB (else rain halves Solarbeam's), in the AI's estimate too; Thunder, Solarbeam's charge, freezing and the time-based heals follow the weather.
- Substitute (a quarter of the maximum HP, which needs more HP than that) takes the hits in `DoSubstituteDamage`, and its break clears the attacker's move effect unless it hits several times. The animation commands now keep their `wBattleAnimParam` effects with a substitute up, which Triple Kick counts from.
- Transform (5 PP per move, the enemy's own DVs kept for Attract and capture), Mimic, Metronome, Mirror Move and Sleep Talk (which run the called move through `ResetTurn`), Snore, Conversion, Conversion2 and Sketch (for good, in the party struct or the wild Pokémon's kept moves). Catching a transformed wild Pokémon gives a Ditto with its own DVs and moves, as in the original.
- Baton Pass hands the substatuses and stat levels to a Pokémon chosen without a send-out text; Roar and Whirlwind end a wild battle or drag out a random healthy Pokémon of a trainer's; Teleport ends a wild battle, which a wild Pokémon always manages (a kept bug).
- A trainer's Pokémon sent back in with a status no longer has its paralysis or burn penalty applied, as in the original.
- Every move's effect script now runs. The battle rollback tests use Psywave at level 1 instead, which loops forever in the original and stays refused. `tests/reference-move-effects.spec.ts` also compares `Stab` with the weather; two deliberate mutations of the weather modifier failed it.
## Implemented: held items, Exp. Share and obedience
- Smoke Ball escapes wild battles after the trapping checks; Metal Powder uses the original species even after Transform, with the byte-overflow quirk in both damage and AI estimates. MysteryBerry restores the first exhausted stored move (one PP for Sketch, otherwise five), preserves PP Ups and leaves copied moves alone. Berserk Gene activates before the menu and keeps the original confusion-count bug. The unused held stat-raising effects also follow their between-turn order.
- Exp. Share halves experience and stat-experience bytes before splitting the participant and holder pools. Healthy holders receive the second pool, including a holder that also fought; fainted holders are excluded. Existing traded, trainer, Lucky Egg and Pokérus modifiers still apply to each award.
- Traded Pokémon obey according to the world's Johto badges. Disobedience preserves the original random draws and can ignore orders, nap, hurt itself or use another move; it spends only the alternate move's PP and breaks Encore where the original does.
- Consumed healing and confusion berries are removed from a trainer's stored party too, so switching cannot restore them.
- Local-ROM regressions cover these paths; the reference emulator compares Metal Powder over 320 cases in each browser. The other new routines have source review and unit coverage, without a direct emulator comparison yet. Smart AI handlers remain unfinished; card #28 is still in progress.
## 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. Only the special Kurt and Park balls remain unported among battle items.
+60 -1
View File
@@ -1,6 +1,6 @@
# Recovered Claude session
Latest continuation: see **Field items, fishing, Select and MAIL: 2026-10-03**
Latest continuation: see **Battle effects, held items and obedience: 2026-10-03**
at the end of this file. Earlier sections are historical snapshots.
Recovered on 2026-09-23 from the local Claude Code transcript
@@ -1165,3 +1165,62 @@ Rod was checked once in Chromium and WebKit.
Next: the remaining battle commands, move effects and Smart AI handlers
(board #28).
## Battle effects, held items and obedience: 2026-10-03
Recovered the latest Claude Code session from
`~/.claude/projects/-Users-kawa-Crystal/d316d957-8ee4-4b55-aa7b-12be1bcd8726.jsonl`.
Its request was "continue the plan", taking card #28. It hit the usage limit
at 09:25 UTC while researching held items, Exp. Share and CheckObedience.
Claude had committed three groups:
- `9e0a2cd`: multi-hit and special-damage effects.
- `c53edb7`: moves spanning several turns.
- `8f5b464`: status and field move effects.
Its next group was uncommitted: weather, Substitute, Transform, Mimic,
Metronome, Mirror Move, Sleep Talk, Snore, Conversion/Conversion2, Sketch,
Baton Pass, Roar/Whirlwind and Teleport. Every move's effect script now has
a handler. Rollback fixtures use level-1 Psywave, which would loop in the
original and remains explicitly refused. These changes were preserved;
the recovered tree passed 546 unit tests before further edits. Claude's
last recorded browser run had 147 passed and 19 skipped.
The resumed increment adds:
- Smoke Ball, Metal Powder (also in the AI damage estimate), MysteryBerry,
Berserk Gene and the original unused held stat-raising effects. Item
order and stored/battle PP follow `engine/battle/core.asm`. Metal Powder
checks original species after Transform and retains byte overflow;
Berserk Gene retains the 256-turn/stale confusion-count bug.
- Exp. Share's separate participant/holder awards, halving bytes before
dividing each pool, including stat experience and existing modifiers.
- Traded Pokémon obedience, including badge thresholds, alternate moves,
nap, self-damage and idle outcomes. The world supplies its Johto badge
byte. RNG rejection loops fail closed for an invalid random source.
- Correct removal of consumed trainer healing/confusion berries from
the stored party, preventing them from returning on a switch.
- `tests/battle-held-items.test.ts` (30 local-ROM tests) and
`tests/reference-held-items.spec.ts` (320 Metal Powder cases per browser,
running the unmodified original routine). The new tests skip without
the private ROM; the emulator test also needs the pinned symbol file.
The reference harness must keep sentinels out of `$c6ff` (player screens).
The move-effect and held-item specs use audio RAM `$c0f0`, with interrupts
disabled, instead.
Validation on the final code: `npm test` passed 576 tests, with 3 skipped;
without the private ROM, 136 passed and 443 skipped. The full Chromium/WebKit
suite passed 149 tests, with 19 intentional skips, including the original
Tin Tower pillars case on this run. Native/reference builds, profile and
pinned-reference verification, vendor integrity, release isolation and
`git diff --check` passed. Metal Powder has direct emulator evidence;
the other new held-item, experience and obedience paths have local unit
coverage and source review. No CI or physical-device validation was run.
Next: complete the Smart AI effect dispatch in `src/game/battle/ai.ts`;
card #28 remains open. Other explicit boundaries include the special balls,
Unown generation, Beat Up with Eggs, and original routines that run off a
move list or loop indefinitely. Johto badge stat boosts are still absent;
the new badge option implements obedience only. Do not claim the battle
engine or the full card is complete. Delivery is tracked by the commits
referencing card #28; its commit list includes the recovered groups above.