Commit Graph

18 Commits

Author SHA1 Message Date
1jamie 8621d024dc feat(game3): implement roaming legendary beasts, Seagallop ferry, field weather, and overworld fixes
- Implement roaming legendary beast system (Raikou, Entei, Suicune) matching pokefirered (src/roamer.c), including 31-cap IV fix, Roar despawn fix, battle flee logic, and trapping interactions (Mean Look, Shadow Tag, Arena Trap, Wrap).
- Implement Seagallop ferry crossing cutscene and transit between Sevii Islands and Kanto.
- Implement field weather engine, weather extraction, and particle rendering.
- Implement renewable hidden items and step events.
- Fix poison step sound effect (SE_FIELD_POISON).
- Fix encounter cooldown lookup for grass/cave terrain.
- Add comprehensive test suites for roamers, weather, Seagallop animations, and ladders.
2026-09-23 13:46:57 -05:00
bryanthaboi ebbf4709c8 CLOSES #2411, CLOSES #2418, CLOSES #2420, CLOSES #2422, CLOSES #2423, CLOSES #2424 2026-09-23 05:51:05 -04:00
bryanthaboi d920f7acdb clean up 2026-09-22 17:05:12 -04:00
Shane McGovern e2454bf568 fix(game3): review v3 fixes (battle, field, script, save) + gated T6 tier
Second wave of fixes from the Gen 3 codebase review (210 findings), the
regressions the full-suite sweep surfaced, and a T6 tier so the top-level
tests/game3_*.lua suites run inside ./scripts/test.sh instead of outside it.

Battle: Knock Off and Thief/Trick item persistence follow the ROM, not the
review - the party slot is never written through during battle, and the
knocked-off mask suppresses the item on later send-outs
(pokefirered/src/battle_script_commands.c:2731 MOVE_EFFECT_KNOCK_OFF with the
STICKY_HOLD guard at :2732, opponent-steal guard at :2610-2622, mask use at
:4489). Rapid Spin keeps its one-per-use chain order (:8435-8474); Growl
keeps pret's target (src/data/battle_moves.h, include/battle.h:63).

Scripting: operand layouts match pret/asm/macros/event.inc - givemon 15 bytes
(:989-997), comparestat {B,W} (:1573-1576), setptr/loadbytefromptr/setptrbyte
take a word pointer (:118-137). 18 of the 20 E10 ops are wired per
src/scrcmd.c (per-op citations in docs/game3/e10-opcode-spec.md), money and
random and the warp family read their operands as VarGets
(src/scrcmd.c:1798-1830, :455-461, :719-731), and the day-care party-full
guard is in place (src/daycare.c:525,:1081).

Field and UI: fishing counts rounds as the ROM does
(src/field_player_avatar.c:1740-1765), an unresolved map section no longer
reports Pallet Town (src/region_map.c:3782), and a font provider sits behind
a FireRed capability/profile seam.

Save data: profile-driven Options.block, a save version round-trip, and slot
id validation that blocks path traversal (slotDiskPath("firered", "../evil")
returns nil).

Importer: the parallel import path now writes both completion markers,
object kind/clone bytes decode as pret defines them
(include/global.fieldmap.h:110-130), and the HM table drops Whirlpool
(include/constants/items.h:411-418).

Tests: six new scenario suites (battle_ai, capture, event, menu, move,
overworld) and eight engine suites (profile, capabilities, cache paths, font
provider, options block, save version round-trip, version dispatch,
versions_game). T6 runs every top-level game3 suite at GAME3_JOBS default 8
with per-suite logs, failure cause classification and a KNOWN_GAME3_FAILURES
ceiling of 23 as a shrinking guard.

Docs: the working notes under docs/game3 (triage ledger, pret citation audit,
e10 opcode spec, RSE seams, sweep v3/v113, test baseline, artifact
conversions, merge trial).

Full gate at this snapshot: exit 0, all tiers passed - engine 624/624,
T6 279/279 (0 known, 0 fresh failures), gen2 146/146, modkit 37/37, luacheck
clean, privacy gate 3/3 over a 9,711-file publication set.
2026-09-22 12:22:50 +01:00
Shane McGovern 2c356f28ea fix(game3): save, item, map, script and importer bugs found in review
The rest of the Gen 3 review fixes, each with a gated suite in tests/engine/.
ROM semantics were checked against pret/pokefirered.

Scripts
- givemon carried the wrong operand layout, found earlier; four more layout
  desyncs came out of pret asm/macros/event.inc: comparestat is {byte,word},
  and setptr / loadbytefromptr / setptrbyte each carry a leading byte plus a
  word. A wrong size mis-decodes every instruction after the bad one, so
  Versions.CACHE_VERSION moves to 113 and existing caches re-import.
- handlers for previously handler-less verbs: comparestat,
  bufferitemnameplural, setmonmove, setmonmetlocation, the modern
  fateful-encounter pair, the script-locals family (copylocal, setptr,
  loadbytefromptr, setptrbyte, copybyte, compare_local_to_* and
  compare_ptr_to_*), the RAM-script family (setvaddress, vgoto, vcall,
  vgoto_if, vcall_if, vmessage, vbuffermessage, vbufferstring, endram,
  returnram) and the same-map forms of the *at verbs.
- setdooropen / setdoorclosed read their coordinates through VarGet.

Battles
- Knock Off and Thief / Trick persist the item change instead of only
  touching the in-battle copy.
- knocked-off party slots are tracked in a bitmask, so a slot reused later
  does not inherit the flag.

Field and UI
- Player.reset restores facing and clears the surf flags.
- a definition-less Map.load no longer leaves collision unbound.
- an unresolved region-map section no longer reports PALLET TOWN.
- the naming screen splits input from the timer, so update(dt) stops
  indexing a number.
- the hall of fame commits through the engine save path and serializes its
  fields.

Persistence
- gameStats, the link-battle records and the trainer card are serialized.
- the PC deposit refuses at the 999 cap instead of destroying the overflow.

Robustness
- Data.load runs cached modules sandboxed.
- the file browser quotes shell arguments.
- .meta dimensions are bounds-checked and mids.idx validates its header.
2026-09-22 03:28:39 +01:00
bryanthaboi 2945ed8987 firered: elevators, braille, alt layouts, on-frame scripts, fly and heal data, field item use 2026-09-21 05:39:03 -04:00
bryanthaboi 92b4fb9eb5 firered: forced movement, darkness, safari, rocket hideout, victory road, script ops 2026-09-20 21:17:57 -04:00
bryanthaboi 1af407498c firered softlocks, specials, cave encounters, sevii ferry 2026-09-20 17:31:31 -04:00
bryanthaboi 605654a086 CLOSES #2310 2026-09-20 13:21:16 -04:00
Shane McGovern 38a7e03f13 Show retail location previews for every FireRed map section
Most map sections never showed a Location Preview because the preview
artwork and the region-map GUIDE text were hand-authored placeholders:
only a handful of sections had art and none of it came from the ROM.

Read the real tables out of the dump instead.

Extraction (new):
- src/import/gba/region_map_tables.lua locates and validates
  sMapPreviewScreenData. The pinned offset from versions.lua is tried
  first and a bounded +/-0x8000 scan is only a guard. Validation is
  structural (mapsec in 88..196, type 0/1, three in-range ROM pointers,
  and the shipped invariant that the palette block is the first 0x40
  bytes of the tile block) so all 28 entries must hold.
- src/import/gba/map_preview_extract.lua bakes 21 deduplicated 240x160
  RGBA artworks (28 entries reuse art: Pattern Bush and the six Tanoby
  chambers), 109 mapsec names verified against sRegionMapSectionIdToName,
  and the 19 sDungeonInfo entries. Palette banks 13/14; bank-0 tilemap
  refs only occur in off-screen padding columns.
- src/import/gba/bg_bake.lua holds the shared 4bpp BG baking helpers;
  berry_pouch_extract.lua is refactored onto them (-94 lines).

Runtime:
- src/ui/game3/map_preview_screen.lua ports
  Task_RunMapPreviewScreenForest: 120-frame first-visit hold, 40-frame
  revisit, 48-frame fade-out, artwork and name window composited into one
  canvas so they fade together. Only MPS_TYPE_FOREST (8 sections) takes
  over the screen; the 20 MPS_TYPE_CAVE sections only change the warp
  fade colour, matching pret.
- src/core/game3/map.lua gives a changed section with a forest preview
  precedence over the map name popup (overworld.c state 12).
- src/core/game3/warp.lua routes every fade through warpFadeModes,
  applying WarpFadeOutScreen/WarpFadeInScreen: a section change into a
  cave-preview map forces FADE_TO_BLACK, otherwise MapTransitionIsEnter/
  IsExit decide white vs black on MAP_TYPE_UNDERGROUND.
- setworldmapflag feeds the transient visit flag; the HUD ticks and
  dismisses the screen; the dataset installs the cache on hydrate.
- region_map.lua's GUIDE panel uses the retail geometry, tint ramp and
  delayed text, and ROM names/dungeon text overlay the hand-authored
  fallbacks via ensureGenerated().

Two retail quirks are tolerated: MPS_ROCKET_WAREHOUSE and Berry Forest
share flagId 2231 (as do the six Tanoby chambers), and the Tanoby mapsec
is spelled MAPSEC_DILFORD_CHAMBER.

CACHE_VERSION 99 -> 100.

Verified: tests/game3_map_preview_extract_test.lua (new; ROM-gated, all
28 entries, 8 forest / 20 cave, 21 artworks, 109 names, 19 dungeons, the
shared flag, Pattern Bush art reuse), tests/game3_town_map_test.lua,
tests/run_engine.lua 587/587, scripts/test.sh --quick all tiers,
luacheck src 0 warnings / 0 errors.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-19 14:21:30 +01:00
Shane McGovern b84c2c1511 Port FireRed wild encounter grace period
Gen3 (FireRed) had no cooldown between wild battles, so every step on an
encounter tile rolled at the area's full rate -- Route 1 (~21%) landed a
battle on roughly one step in five. Gen2 already had this via
World:wildCooldownStep(); game3 never did.

Port pret/pokefirered wild_encounter.c:

- GetMapBaseEncounterCooldown -> Encounters.mapBaseCooldown: steps of
  immunity derived from the area's own rate (rate >= 80 -> none, < 10 ->
  8, else 8 - rate/10).
- HandleWildEncounterCooldown -> Encounters.handleCooldown: a soft floor,
  not a hard gate -- once the minimum elapses a 5%/step leak lets a battle
  through anyway. Includes the White/Black Flute, Cleanse Tag, Stench and
  Illuminate modifiers in pret's application order (Cleanse Tag before the
  ability mod, which changes the result).
- ResetEncounterRateModifiers -> Encounters.resetRateModifiers, wired to
  the two places pret resets: map load (Map.load, including seamless
  connection crossings) and battle start (BattleBridge.startWild). The
  latter is the bug-#1229 class -- scripted battles and fishing re-arm the
  grace period even though no step rolled.

Measured on Route 1 over 4000 steps: 843 encounters before, 397 after;
first encounter never lands before step 7.

Not ported (makes encounters more likely, so it does not affect the
reported symptom): the encounterRateBuff anti-frustration ramp and the
Mach/Acro bike rate modifier.

tests/engine/wild_encounter_cooldown.lua covers the cooldown golden table,
the counter/leak mechanics, all five modifiers, both re-arm paths and the
end-to-end step count.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-19 09:46:02 +01:00
bryanthaboi 661d75ef1c junk 2026-09-18 16:49:48 -04:00
bryanthaboi bdfac727aa bing bang bong 2026-09-18 15:42:32 -04:00
bryanthaboi dbe0c5c9f0 all the fun features 2026-09-17 10:51:09 -04:00
1jamie 06dd4ffba8 game3: add fanfare/emote parity, pause & main menu exit flows, and bump fr cache 2026-09-15 15:41:51 -05:00
bryanthaboi d615ad39ab bazinga 2 2026-09-13 03:34:39 -04:00
1jamie 2426e519b2 bit of fixes for door transition and stub placeholders for field moves 2026-09-09 16:37:01 -05:00
1jamie 52ad498b8b feat(game3): self-contained ROM-derived FireRed extraction & cache contract alignment
- Align CacheContract firered overrides with pure ROM extraction
- Fix door animation extraction tile sizes, palettes, and strides
- Update storage chrome, pokedex, summary, and battle chrome extractors
- Ensure 100% self-contained ROM extraction without external dependencies
2026-09-09 14:14:40 -05:00