Files
Crystal/docs/SESSION_HANDOFF.md
T
Sébastien QUEROLandClaude Opus 5.5 0d1bedb3b1 Translate Opportunist, Aggressive and Risky trainer AI
Add the AI_Opportunist, AI_Aggressive and AI_Risky scoring layers with
the ROM's stall, reckless and risky tables, HP thresholds, last-wins
ties and strict knockout test. AIDamageCalc is ported as a
pre-variation damage estimate, including a critical-hit flag left over
from an earlier move, which the original also reads. Smart remains the
only refused layer, so the rival stays gated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 14:36:46 +02:00

198 lines
10 KiB
Markdown

# Recovered Claude session
Recovered on 2026-09-23 from the local Claude Code transcript
`~/.claude/projects/-Users-kawa-Crystal/4ac88f30-29e6-4fd5-a4b2-b6a318dd83b3.jsonl`.
The session stopped at its usage limit at 09:54 UTC, during research, without a final handoff.
## Resumed increment: completed 2026-09-23
The movement increment below is complete. The remaining sections preserve the
original recovery context.
- Added directional two-tile ledge jumps with the existing arc/shadow animation.
Unsupported terrain, invalid destinations and occupied landings remain refused.
- Corrected directional mats to wait for exit input. Warp arrivals keep their
actual coordinates and appropriate facing; doors, stairs and caves animate a
downward exit. Removing the old inward teleport also corrected Elm's scripted
introduction position.
- Mid-walk, mid-jump and mid-connection saves retain the source position. Landing
scenes rewind to the actual source of a jump, rather than the intervening wall.
- Restored compatibility with early version-3 saves lacking the money field.
- Replaced the scratch diagnostic with synthetic movement regressions and
optional-ROM tests covering five Route 29 ledge types. Route 29 is enabled only
inside that test fixture, not in production.
- Fixed the battle test suite's eager ROM read so missing-ROM runs really skip
private tests. Updated browser stair inputs and added an exit-mat save/reload
flow. Updated the roadmap and architecture to distinguish the existing battle
code from its unfinished integration.
Final checks: 75 unit tests passed with the local ROM; without it, 55 passed and
20 private tests skipped. All 24 Chromium/WebKit browser tests passed. Native and
reference builds, release isolation, pinned-reference checks, vendor checks and
`git diff --check` passed. No commit or push was made.
Next: validate the overworld-to-battle browser flow and complete Route 29's
remaining script, capture/tutorial and item interactions before enabling the
route. Player turn timing also remains a documented comparison gap.
## Scope and current state
The original request was to read ARCHITECTURE.md, PLAN.md and PRESENTATION_PLAN.md
and continue the native port. The working tree contains substantial uncommitted
work from multiple increments; preserve it when continuing.
- Opening scenes, scripted movement, starter selection, naming, the aide's Potion
and version 3 saves are implemented and documented.
- Native battle modules, ROM tables, damage/type parity tests, encounter handling,
battle UI and whiteout handling have been added. These later changes are not
fully reflected in the architecture and roadmap documents.
- Only the original six maps are enabled in `NATIVE_MAPS`. Route 29 (`24:3`)
remains disabled. Passing battle unit tests does not establish a playable
Route 29 encounter or the full opening quest.
## Exact stopping point
Claude was preparing to revise player movement in `src/game/world/world.ts`.
Its last investigation concerned spawn facing after warps. It had not implemented
the planned ledge/warp revision.
The pinned local PRET checkout contains the relevant routines:
- `engine/overworld/player_movement.asm`: `.TryStep`, `.TryJump`,
`.CheckLandPerms`, `.CheckWarp` and the direction tables.
- `engine/overworld/tile_events.asm`: `CheckWarpCollision` and
`CheckDirectionalWarp`.
- `engine/overworld/player_object.asm`: `SpawnPlayer`.
- `engine/overworld/map_objects.asm`: movement/turn timing.
Research found that ledge tops have land permission; the jump check uses the
current tile and facing after an ordinary step fails. Doors use collision `$71`,
downward warp mats `$70`, and stairs `$7a`. Directional warp mats require their
designated input rather than an immediate warp simply upon entry. Verify these
rules against the local routines before changing the existing movement flow.
`tests/zz-scratch.test.ts` is Claude's unfinished diagnostic: it logs local-ROM
warp and ledge collisions, contains no assertions and unconditionally requires
the private ROM. Replace it with meaningful optional-ROM or synthetic tests
before treating the suite as ready for public CI.
## Validation after recovery
Run against the current working tree with the local ROM and reference checkout:
- `npm test`: 45 passed, including the assertion-free scratch diagnostic.
- `npm run build`: passed.
- `npm run test:e2e`: 22 passed across Chromium and WebKit, including native
damage/type comparisons against original routines in the reference emulator.
- `npm run check:reference`: ROM, pinned rebuild and profile addresses match.
- `npm run check:release`: native output excludes emulator and game assets.
- `npm run check:vendor`: passed.
These checks do not establish complete battle behavior, browser battle UI flows,
Route 29 progression or physical-device compatibility. No gameplay source was
changed during session recovery.
## Original next-increment notes (movement now completed)
Finish ledge and directional-warp movement with focused regression tests,
including interrupted movement/save behavior and preservation of the existing
opening scenes. Audit Route 29 callbacks, scripts and unsupported destinations
before enabling it. Then test wild encounters and battle controls through the
browser, including win, escape, loss and save/reload, and reconcile the roadmap
with the verified behavior.
## Battle integration increment: 2026-09-23 (resumed from Codex)
Codex committed and pushed `c08d250`, then stopped mid-increment with the
keyboard/D-pad battle test failing. Claude Code completed it:
- Browser battle flows run through the real UI via `tests/battle-fixture.ts`
(encounter selection only; production maps stay gated): win with level-up and
Smokescreen, escape, whiteout, keyboard/D-pad menus, mid-battle backup restore
and unsupported-effect rollback. `tests/battle-world.test.ts` covers the same
at world level, plus pending stat experience and whiteout callback rollback.
- Saves accept stored stats between the no-stat-exp and full-stat-exp values,
since `GiveExperiencePoints` awards stat experience without `CalcMonStats`.
- A script warp (e.g. whiteout) validates its destination and commits healing,
money loss and destination callbacks together; aborts restore state and map.
- Keyboard and on-screen D-pad navigate battle menus (`battle-selected`); A
continues messages, B leaves the move list.
- Fixed a phone-width layout bug: a long notice sat in the Play button's auto
grid column and crushed the status text, pushing the game panel off-screen.
Below 720px the notice now has its own row.
- Test fixes: the navigation test now presses A through the intro message, and
uses a real pointer click on the D-pad (synthetic pointer events cannot be
captured).
Final checks: 82 unit tests with the local ROM (55 passed, 27 skipped without
it); 36 Chromium/WebKit browser tests; native and reference builds; release,
vendor and reference checks; `git diff --check`. Not committed.
Next: Route 29 (`24:3`) scripts, catching tutorial and items before enabling it;
then capture, switching and PACK in battle.
## Route 29 and Cherrygrove increment: 2026-09-23
Enabled Route 29, its Route 46 gate, Cherrygrove City and its five buildings.
Item balls, the Pokémon Center nurse and the Poké Mart were each ported by a
Sonnet sub-agent in an isolated worktree, reviewed against the disassembly and
merged; the rest was done directly.
- Fruit trees run `FruitTreeScript`; a native `CheckDailyResetTimer` clears
the daily engine flags once per game day. `VAR_BOXSPACE` reads an empty box.
- Item balls run `FindItemInBallScript` with a native `TryReceiveItem`.
- The nurse runs `PokecenterNurseScript`; `HealParty` now applies
`ComputeMaxPP`'s PP Up clamp. `EnterMapWarp`'s spawn recording makes
whiteouts return to the last Pokémon Center entered.
- Standard marts run natively (`StandardMart`/`BuyMenu`/`SellMenu`).
- Battle command `recoil` (Struggle) was the only refusal found by a local
stress run of 360 Route 29 battles across starters and times of day.
- Save format 3 gained `fruitTrees`, `dailyReset` and `lastSpawnMap`
(migrated by absence).
- The phone-width status bar layout and parity test map counts were fixed.
Still refused: `catchtutorial` and Cherrygrove's rival scene (both after the
Mystery Egg), Route 30/46. NPCs do not roam yet.
Next: NPC roaming movement (`map_objects.asm` random walk/spin, radius and
visibility rules, deterministic RNG in tests), trainer sight lines and trainer
battles, Route 30 and Mr. Pokémon, capture and the catching tutorial.
## Trainer AI continuation: 2026-09-24
The trainer foundation was subsequently committed through `3e92936`. The next
AI increment translates Opportunist, Aggressive and Risky scoring, including
the ROM's stall/reckless/risky tables and Aggressive/Risky's deterministic
pre-variation damage estimate. Smart is now the only refused move-scoring layer,
so the rival remains gated. Continue with Smart before the rival, or with
trainer sight lines and normal trainer-object scripts for the already-supported
Youngster and Bug Catcher classes on Route 30.
## AI layer review: 2026-09-24 (resumed from Codex)
Claude Code checked Codex's uncommitted Opportunist, Aggressive and Risky layers
against `engine/battle/ai/scoring.asm`. The HP thresholds, `AI_50_50` (≥128),
`79 percent - 1` (200), last-wins ties, the power < 2 and reckless exclusions,
the strict-borrow KO test and the constant-damage paths all match.
One fix: `AIDamageCalc` goes through `EnemyAttackDamage` and
`BattleCommand_DamageCalc`, and both read `wCriticalHit`. A flag left over from
an earlier move therefore selects unboosted stats (ignoring screens) and
doubles the estimate. `enemyAIDamage` now reads the native `criticalHit`
instead of hard-coding `false`. It also reuses `truncate`. A local-ROM test
fixes the estimate at 4, 3 (Reflect) and 6 (leftover critical).
Known side effects of `AIDamageCalc` that are not modelled: it overwrites
`wCurDamage`, `wTypeModifier`, `wAttackMissed` and `hBattleTurn`. `CheckTurn`
resets the modifier and miss flag before each move. Whether the `wCurDamage`
overwrite can reach Counter/Mirror Coat still needs checking before those
effects are ported.
Final checks: 147 unit tests with the local ROM; 42 Chromium/WebKit browser
tests; native and reference builds; reference, release and vendor checks;
`git diff --check`. Not committed.
Next (unchanged): Smart AI before the rival, or trainer sight lines and
normal trainer-object scripts for Route 30's Youngster and Bug Catcher.