Add core.update/core.quit_to_launcher platform lifecycle hooks (RFC 0006)

A platform-specific launcher wrapper (a native shell embedding this engine,
owning its own UI around the game window) needs to pause the simulation
while its own UI is on top, live-reload options it wrote outside any Lua
UI, and veto main.lua's "closing the window returns to the Lua launcher"
behavior when it owns that job itself. Implementing this by hand-patching
main.lua's love.update/love.quit directly ties every such integration to
editing the one file every other engine change also touches, guaranteeing
merge conflicts. No existing hook covers "should the per-frame simulation
step run" or "should closing the window return to the Lua launcher."

Adds two generic, additive hooks (src/core/PlatformHooks.lua): core.update
and core.quit_to_launcher, replacing what would otherwise be inline
main.lua special-casing. Also adds Manifest.force_enable_env, letting a
mod that cannot function disabled on the one build where its env var is
set (a platform-bridge mod bundled only with that build) re-enable itself
regardless of a saved disable.

RFC 0006 status: Proposed.
This commit is contained in:
david
2026-08-09 20:05:06 -07:00
parent 943ba5dcbf
commit e79107c644
9 changed files with 312 additions and 3 deletions
+16 -3
View File
@@ -13,6 +13,7 @@ local editorMode = os.getenv("POKEPORT_EDITOR") == "1" or POKEPORT_EDITOR_MODE =
local SwitchDiagnostics = require("src.debug.SwitchDiagnostics")
local LaunchOptions = require("src.core.LaunchOptions")
local NxDisplay = require("src.core.NxDisplay")
local PlatformHooks = require("src.core.PlatformHooks")
-- Lua errors: persist a redacted trace in the save dir and surface a hint.
do
@@ -426,7 +427,11 @@ function love.update(dt)
end
return
end
Game:update(dt)
-- Mods may wrap or veto the per-frame simulation step (pause it, react
-- to external platform state, etc.) -- see docs/modding.md's core.update
-- entry. Vanilla behavior (used when no mod claims the hook) is just
-- Game:update(dt), unconditionally, exactly as before this hook existed.
PlatformHooks.update(Game, dt)
end
function love.draw()
@@ -819,8 +824,16 @@ function love.quit()
or os.getenv("POKEPORT_IMPORT_ONLY") == "1" or os.getenv("POKEPORT_IMPORT_ROM")
-- #887: a shortcut session (--game / POKEPORT_GAME) has no launcher to go
-- back to and the restart would re-read the shortcut, so it exits instead.
if Game and not Importer and not quitToLauncher and not scripted
and not launchedIntoGame then
--
-- A platform launcher that owns "return to launcher" itself (see
-- docs/modding.md's core.quit_to_launcher entry) may veto returning to
-- this Lua launcher via that hook. Vanilla behavior (used when no mod
-- claims the hook) is exactly the condition below.
local wouldReturnToLauncher = PlatformHooks.quitToLauncher(function()
return Game and not Importer and not quitToLauncher and not scripted
and not launchedIntoGame
end)
if wouldReturnToLauncher then
quitToLauncher = true
-- Tell the fresh boot to ignore any boot-straight-into-a-game option this
-- once, so the restart really does land in the launcher (#887). A failed