rfc: guard the new seams and write RFC 0014

Route B in CONTRIBUTING-mods.md asks an event/hook change for five things.
This adds the two that were missing and fixes what the third turned up.

link.battle_ended built its payload unconditionally. Route B is explicit
that a new event must not allocate when nothing wants it, and every other
emit in the engine already guards -- Runtime.wants now gates this one too,
so an unsubscribed build runs the branch exactly as it did.

world.talk was handing Runtime.call a closure built fresh on every A press,
purely to have a fallthrough to pass. It is a file-local now, so an unhooked
press allocates nothing it did not allocate before.

The RFC covers motivation, the API delta with call sites, migration (nothing
changes for existing mods), and verification. The backward-compatibility
statement is in it: every item is a new name or a new optional argument, and
example_mew_starter -- api 1, category = "GAMEPLAY", whole-species copy --
still loads, which run_modkit proves on every run.

No registry or schema field is added, so gen_registry_docs has nothing to
emit for this change. Running it does show pre-existing drift in
docs/modding/reference/registries.md (timeFishGroups, an objects refinement)
from earlier Schemas.lua edits that were never regenerated; that is not this
branch's to carry, so it is left alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
DESKTOP-8SRFDDM\cam95
2026-08-23 10:35:12 -05:00
parent 01c5eb2189
commit b550db3abb
4 changed files with 168 additions and 3 deletions
+5 -2
View File
@@ -1964,6 +1964,10 @@ function OverworldState:pushableAtCell(cx, cy)
return nil
end
-- world.talk's fallthrough, hoisted so the A press does not build a closure
-- on every press just to have one to hand a hook nobody may have wrapped
local function vanillaTalk(ow, target) ow:talkTo(target) end
-- what the A press resolved to, for world.interacted's listeners
local function interacted(self, fx, fy, kind, target)
Runtime.emit("world.interacted", { mapId = self.map.id, x = fx, y = fy,
@@ -1998,8 +2002,7 @@ function OverworldState:interact()
-- no TEXT_* id, so the vanilla path has nothing to say for it; a mod
-- that owns the object wraps this and simply does not call next().
-- Everything else falls straight through to talkTo as before.
Runtime.call("world.talk", function(ow, target) ow:talkTo(target) end,
self, npc)
Runtime.call("world.talk", vanillaTalk, self, npc)
end
interacted(self, fx, fy, "npc", npc)
return