-
Notifications
You must be signed in to change notification settings - Fork 16
Cookbook World And Scripting
Command vocabulary: Reference: Script Commands; worked paths: Tutorials 06–08.
mod.commands:register("mod_reward", function(ctx, amount)
ctx.save.money = math.min(999999, (ctx.save.money or 0) + (amount or 100))
end)Checkpoint: { "mod_reward", 500 } works in any script row. The handler
is fn(ctx, ...) — ctx.save, ctx.overworld, ctx.game are the
surface; return a label string to jump. The script.command hook sees
every dispatched row if you need to intercept instead.
mod.content.tokens:register("CLOCK", function(game, arg)
return tostring(math.floor((game.save.playSeconds or 0) / 3600))
end)Checkpoint: {CLOCK} in any text renders the value. Grammar is
{NAME} or {NAME:arg}, handler fn(game, arg) -> string | nil
(src/script/Tokens.lua); nil drops the token, a thrown error is logged
and drops it.
mod.content.map_scripts:register("PALLET_TOWN", {
talk = {
TEXT_PALLETTOWN_GIRL = {
{ "face_player" },
{ "show_text", "My line is\nmodded now!" },
},
},
})Checkpoint: the Pallet Town girl says your line; every other TEXT
constant on the map is untouched. Per TEXT constant the
highest-precedence contribution wins; false suppresses lower ones.
mod.events:on("map.entered", function(ev)
if ev.mapId == "PALLET_TOWN" then
mod.world:spawnNpc("PALLET_TOWN", {
index = 95, x = 10, y = 9, sprite = "SPRITE_FISHER",
movement = "WALK", range = "ANY_DIR", text = "TEXT_PALLETTOWN_GIRL",
})
end
end)Checkpoint: the NPC appears and wanders on every visit. Runtime objects
are not serialized — re-spawn on map.entered. For a permanent NPC,
patch the map record's objects with __append instead
(Tutorial 06).
mod.content.map_scripts:register("PALLET_TOWN", {
onStep = function(game, ow, x, y)
if x == 10 and y == 10 then
mod.log:info("stepped on the spot")
-- return true to consume the step
end
end,
})Checkpoint: stepping on (10,10) logs; the map's own onStep still runs.
Contributions chain first-truthy-return-consumes
(src/script/MapScripts.lua).
local W, H = 6, 5
local blocks = {}
for i = 1, W * H do blocks[i] = 10 end
mod.content.maps:register("MODROUTE", {
id = "MODROUTE", label = "ModRoute", index = 1000,
tileset = "OVERWORLD", width = W, height = H, blocks = blocks,
borderBlock = 10,
connections = { west = { map = "PALLET_TOWN", offset = 0 } },
})
mod.content.maps:patch("PALLET_TOWN", {
connections = { east = { map = "MODROUTE", offset = 0 } },
})Checkpoint: walking off Pallet Town's east edge enters MODROUTE and
back. Both directions are needed; blocks must count
width * height. Full treatment: Tutorial 07.
mod.hooks:wrap("movement.speed", function(next, frames, ctx)
frames = next(frames, ctx)
if not ctx.onBike and ctx.input and ctx.input:isDown("b") then
return math.max(1, math.floor(frames / 2))
end
return frames
end)Checkpoint: hold B on foot to move at bike cadence; the bicycle itself
is unchanged. ctx.surfing is also available if you want surf dash.
mod.hooks:wrap("world.tod", function(next, tod, ctx)
-- 512 steps ≈ a short day cycle for demos
local period = math.floor((ctx.steps or 0) / 512) % 2
return period == 0 and "DAY" or "NIGHT"
end)
mod.hooks:wrap("map.palette", function(next, name, map, ctx)
name = next(name, map, ctx)
if ctx and ctx.tod == "NIGHT" and name == "ROUTE" then
return "CAVE" -- stand-in night tint
end
return name
end)
mod.events:on("world.tod_changed", function(ev)
mod.log:info("time of day -> %s", ev.tod)
end)Checkpoint: after enough steps the overworld palette flips and
world.tod_changed fires. Heavier lighting / rain overlays belong on
render.zones or a render_pipelines present pass
(Rendering pipelines).
Warp fades already live in the transitions registry (warp_fade,
white_flash). Retiming them is a patch, not a new hook:
mod.content.transitions:patch("warp_fade", { frames = 30 }) -- slowerCheckpoint: door warps linger longer. Battle wipe styles use the same
registry via transition.style.
Engine 1.0.0 · mod API 2 · repository · Discord
This project ships no ROM data. All game content is decoded on the player's machine from their own verified Pokemon Red ROM; mods ship recipes and original assets, never extracted content.
Start here
Concepts
Tutorials
- The ladder
- 01 Sprite and Text Tweak
- 02 Balance Patch
- 03 New Species
- 04 New Item and Ball
- 05 New Move
- 06 NPC and Dialogue
- 07 New Map
- 08 Quest
- 09 Custom Music
- 10 New Mechanic
- 11 Custom UI Screen
- 12 Mini Total Conversion
Reference
Guides
- Art Pipeline
- Audio Authoring
- Translations
- Total Conversions
- Link Compatibility
- Publishing a Mod
- Docs Style Guide
Playing