Skip to content

Navigate Oak's Lab and select starter Pokemon#6

Merged
bdougie merged 12 commits intomainfrom
feat/oak-lab-pokemon-selection
Mar 10, 2026
Merged

Navigate Oak's Lab and select starter Pokemon#6
bdougie merged 12 commits intomainfrom
feat/oak-lab-pokemon-selection

Conversation

@bdougie
Copy link
Contributor

@bdougie bdougie commented Mar 10, 2026

Summary

  • Adds a state machine to navigate Oak's Lab (Map 40) and successfully pick up a starter Pokemon
  • Uses B-button text dismissal to avoid re-triggering Oak's dialogue loop
  • Routes the player: south past Oak → east to Pokeball column → face up → interact with Pokeball at (7,3)
  • Handles post-selection scripted sequence with A/down alternation

What changed

  • Lab navigation state machine (phases 0→1→2): B to clear text, move south, move east, face table, press A
  • B button support in action dispatch (previously all non-directional inputs defaulted to A)
  • Oak trigger sequence: waits for Oak's Route 1 escort animation, mashes A through lab intro dialogue
  • Door cooldown increased to 8 turns with left-sidestep to prevent re-entry loops
  • Diagnostic logging: lab script value, screenshots at key positions, post-intro state capture

Test plan

  • Agent reaches Oak's Lab in ~50 turns
  • Party count goes from 0 to 1 (Pokemon selected)
  • Post-selection rival sequence needs battle handling (next branch)

bdougie added 8 commits March 9, 2026 18:04
…ridian goal

- Add door_cooldown system to prevent re-entering buildings after exit
- Add perpendicular escape when stuck 5+ turns on axis-aligned navigation
- Add waypoint skipping when stuck 8+ turns within 3 tiles of target
- Make map 0 EARLY_GAME_TARGET conditional on party_count == 0
- Expand Route 1 waypoints from 2 to 7 for finer navigation
- Add Viridian City milestone detection
- Increase position logging frequency (every 10 on map 0, 50 elsewhere)
Introduce a system for reading Claude Code JSONL tapes and distilling
them into prioritized observations written to memory files.

- tape_reader.py: pure-stdlib JSONL parser with dataclasses for entries,
  tool uses, tool results, token usage, and session/subagent grouping
- observer.py: heuristic-based observer extracting errors, file creations,
  session goals, subagent dispatches, and token summaries
- observe_cli.py: CLI with --dry-run, --session, --reset, --project-dir
- 100% test coverage (89 new tests, 226 total)
Add section explaining the tape reader and observer pipeline,
what it extracts, priority classification, and CLI usage.
Update project structure to include new scripts.
Distinguish between the Tapes telemetry database (.tapes/tapes.sqlite)
and Claude Code session logs (~/.claude/projects/). The observer reads
the latter, not the former.
Replace JSONL file reader with SQLite reader that queries the Tapes
database at .tapes/tapes.sqlite. Conversations are content-addressable
DAGs traced via parent_hash chains. Root nodes (parent_hash IS NULL)
serve as session identifiers.

- tape_reader.py: queries nodes table with recursive CTEs
- observer.py: takes db_path instead of project_dir
- observe_cli.py: auto-detects .tapes/tapes.sqlite, --db flag
- README: rewritten to reference Tapes as the sole data source
- Removed SubagentSession (not needed with Tapes node model)
- Removed make_tape_entry conftest fixture (tests use SQLite now)
- 220 tests, 100% coverage
Document how Tapes provides durable memory across context compaction
boundaries. Describe the session start/end pattern for long speed runs
and update file structure with new observer scripts.
Add a state machine to handle Oak's Lab (Map 40) when the player
has no Pokemon. The agent now:

- Uses B button to dismiss Oak's dialogue without re-triggering it
- Walks south from (5,3) to clear Oak's position
- Walks east to the Pokeball column
- Faces up toward the table and presses A to select a starter
- After selection, alternates A/down to advance the rival scripted
  sequence while moving away from furniture

Also adds:
- B button support in the action dispatch loop
- Oak trigger sequence with wait/mash-A for the Route 1 escort
- Door cooldown improvements to prevent re-entry loops
- Diagnostic screenshots and logging for lab script progression
- Post-intro state capture for debugging
@bdougie
Copy link
Contributor Author

bdougie commented Mar 10, 2026

Agent Run Results

Ran the agent against the current branch to validate the Pokemon selection flow.

Pokemon selected at ~100 turns (party goes from 0→1 between turns 90-100). Full milestone breakdown:

Turn Event
0 Start in Red's bedroom (Map 38)
7 Downstairs to House 1F (Map 37)
~25 Exit house into Pallet Town (Map 0)
50 Reach north edge, Oak trigger fires at y=1
~55 Escorted into Oak's Lab (Map 40), lab navigation begins
~100 Pokemon selected (party_count=1)

Wall clock time: ~3 seconds total from boot to Pokemon selection (2s for intro/naming sequence, 1s for the 100 gameplay turns).

After selection, the agent gets stuck at (7,5) in the lab — the a/down alternation isn't advancing through the rival's dialogue/battle trigger. This matches the "Post-selection rival sequence needs battle handling (next branch)" item in the test plan.

bdougie added 4 commits March 9, 2026 20:37
Resolve conflicts from observational memory work merged via both
PR #4 (main) and a direct branch merge. Take main's versions for
shared files (observer, tape_reader, tests). Keep branch's README
with SQLite description from main.
The run() method now calls take_screenshot("post_intro", force=True)
which bypasses the screenshots flag and hits Image.fromarray on a
MagicMock. Fix by:
- Using defaultdict(int) for mock memory so _read() returns ints
- Patching agent.Image to None in run() tests that don't need screenshots
- Updating lab test assertion for new B-button dismiss phase
- Blocking PIL import in dunder_main test's runpy.run_path
Move milestone detection before maps_visited.add() so it actually
fires on first visit. Add tests for door cooldown, lab phases, Oak
trigger, B-button dispatch, and waypoint logging to reach 100%
coverage on agent.py.
@bdougie bdougie merged commit 934f868 into main Mar 10, 2026
1 check passed
bdougie added a commit that referenced this pull request Mar 13, 2026
* fix: use game-progression map for fitness scoring instead of raw map IDs

Pokemon Red map IDs are arbitrary (Oak's Lab = 40, Viridian City = 1),
so using them directly as a progress signal caused Oak's Lab to score
40x higher than Viridian City despite being earlier in the game. This
led evolution runs to favor params that got stuck in Oak's Lab over
params that reached Viridian.

Adds MAP_PROGRESS dict mapping map IDs to sequential progress values
reflecting actual game order: houses -> Oak's Lab -> Pallet Town ->
Route 1 -> Viridian City -> Route 2 -> Viridian Forest -> Pewter City.

* style: apply ruff formatting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant