Skip to content

Add portable core.update dispatch and cross-engine contracts - #144

Closed
Roxas2712 wants to merge 18 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/portable-core-update
Closed

Roxas2712 wants to merge 18 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/portable-core-update

Conversation

@Roxas2712

@Roxas2712 Roxas2712 commented Oct 23, 2026 •

Copy link
Copy Markdown

Gen1Recomp mods can poll every interactive frame or pause Game simulation through core.update; Gen2Recomped currently calls Game:update(dt) directly, so registered callbacks never run. Add the matching (next, game, dt) seam through a small PlatformHooks.update helper, plus native capability and unified callback catalog entries.

Depends on #143 and its public-API prerequisites. Merge those first and rebase before merging. This PR's new work is isolated in one commit: implementation-only diff. It does not require the rendering or shader PRs.

Normal interactive frames dispatch once outside the fixed-step loop. Omitting next pauses Game:update while the pausing wrapper and host housekeeping can continue on subsequent frames. next() forwards current arguments; explicit replacement arguments also change the native update target/delta. The hoisted native default discards Game:update results exactly as Gen1 does. Existing hook priority, error, unsubscribe and owner rules remain in force.

The native host boundary is preserved: launcher/importer, editors, boot reports and absent-Game frames bypass the seam. Autopilot and coroutine-driver paths retain their direct deterministic 1/60 updates and bypass the hook, matching Gen1. No wrapper is added to Game:update itself, so these scripted loops do not acquire extra dispatch.

Includes a generic pause/poll example, documentation and a dedicated ROM-free workflow pinned to unmodified Gen1Recomp 79ea62f45fb2ea8f65d081a109431e4eb1bbdb36.

Validation:

  • 1,208 focused checks pass: real love.update routing, original Game identity/delta, forwarding, pause/resume, argument replacement, nil-hole results, wrapper/native errors, cleanup and no-mod parity.
  • Routing matrix covers all 15 Gen2Recomped host versions in API 1, native/unified API 2 and API 3, including failed/completed drivers, boot reports, owner removal, rollback and teardown.
  • Both native loaders execute the exact same example entry chunk on Red, Gold, FireRed and Emerald. Native API 2, unified API 2 and API 3 pass at feature and combined integration heads: 48 isolated runs / 144 matching frame observations.
  • The cross-engine test invokes the actual main.lua love.update callback, including Gen1's profiler wrapper. Test-only upvalue injection supplies a Game:update spy and non-game owners; neither native routing nor PlatformHooks is replaced. Unrelated host housekeeping is isolated behind a counter.
  • Combined previous-PR integration: 137/137 engine suites, SDK 3/3, and B30 pass. The input, world/render and shader features remain integrated.
  • Feature: 83/93 engine suites, versus dependency Add portable mod.input tap, press and release controls #143's 81/91. The exact same 10 failing suites and 17 failed assertions remain; no new failures. SDK 3/3 and B30 pass. The existing baseline-fix PRs are included in the green integration.
  • Formatting, workflow lint and diff checks pass. The implementation cherry-picks onto the combined integration without conflicts.

ROM-dependent tiers were skipped without imported data. These tests verify dispatch and native routing with spies, not full-world simulation, GPU rendering or OS event delivery.

Hosted workflows currently require maintainer approval (action_required): API 3 contracts, portable input hook contract, ci, portable core.update contract, portable logical mod input contract. No hosted pass is claimed.

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