-
Notifications
You must be signed in to change notification settings - Fork 2
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.
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
Playing