Skip to content

Add portable trainer.before_battle and battle-local party scopes - #150

Closed
Roxas2712 wants to merge 25 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/portable-trainer-preparation
Closed

Roxas2712 wants to merge 25 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/portable-trainer-preparation

Conversation

@Roxas2712

@Roxas2712 Roxas2712 commented Oct 23, 2026 •

Copy link
Copy Markdown

Gen1Recomp mods can prepare a trainer battle through trainer.before_battle, but Gen2Recomped currently constructs the battle directly. Add native admission before ordinary trainer challenge completion and scripted trainer construction, with a retained one-shot continuation, cancellation and ordered battle-local player-party selection.

Return literal true to defer; call continueBattle() to start, continueBattle({cancel=true}) to cancel, or pass playerPartyIndices={3,2} to select that ordered subset. Save-party identity/order and the original Game are preserved. The selected view drives leads/doubles, switches, native party menus, EXP, party-based moves/AI and exhaustion.

Native ownership and cancellation

  • Retained admission is tied to its Game/save/data/stack/session, party members, hook subscriptions and native actor/map or script coroutine. Removed owners and stale requests cannot construct a battle.
  • Native core-update cleanup preserves other callbacks and return values. Cancellation releases its field/script owner and suppresses same-tile trainer re-entry.
  • A cancelled script retires its own coroutine rather than running post-battle rows: no defeat flags, victory rewards or deferred win callbacks, including immediate cancellation and strict mod scripts.
  • Ordinary trainer victory text, rewards, flags, transitions and post-battle handling remain native. Wild/link/first-battle/tutorial-marked script routes remain separate.
  • The producer covers all 15 hosts' ordinary/scripted trainer routes. Private direct/facility constructors are not globally intercepted.
  • Context identifiers remain native. Pinned Gen1 API 3 exposes a shallow Game context view; Gen2 keeps Game opaque. These boundaries and reproduction commands are documented.

Validation

  • 5,043/5,043 focused checks: public/shared contract 154, native dialogue/script/lifetime 4,439, real battle-local party scope 450.
  • Capability suite: 376/376.
  • Unmodified pinned Gen1 suites: trainer_before_battle 15/15, unified_gen2_hooks 645/645, unified_gen3_hooks 2,004/2,004.
  • One unchanged consumer passes on Red, Yellow, Gold, FireRed and Emerald with API 1, native/unified API 2 and API 3. Final feature/integration matrix: 80 native worker runs / 560 paired observations, using real Loaders and native battle constructors/engines.
  • Feature quick suite: 100/110 engine suites, SDK 3/3, B30 pass. Parent Add portable world.talk dispatch and cross-engine NPC contracts #149 is 97/107; the same 10 known baseline suites and all 26 failure lines remain unchanged.
  • Combined with the existing portability and baseline-fix PRs: 154/154 engine suites, SDK 3/3, B30 pass.
  • StyLua, actionlint and git diff --check pass. Validation is ROM-free; imported-ROM playthroughs and GPU pixel equivalence are not claimed.

CI pins clean Gen1 commit 79ea62f45fb2ea8f65d081a109431e4eb1bbdb36, runs the untouched reference suites and uploads cross-engine reports. Classic workers use the native prepare helper and real constructors; Gen1 Gold uses its own scripted battle engine, and Gen1 GBA uses its actual BattleBridge.

Stack

Depends on #149 and its prerequisites. This PR targets main to follow the existing series. Review the feature-only comparison against #149; please merge in stack order.

Hosted CI

All eleven fork workflows currently require maintainer approval (action_required), including the new trainer preparation contract run. Its job list contains 0 jobs; hosted tests have not run yet. The passing results above are local, reproducible ROM-free runs.

# Conflicts:
#	src/mods/Loader.lua
# Conflicts:
#	docs/modding.md
#	src/mods/Loader.lua
#	src/world/WorldAPI.lua
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