52 KiB
Registry reference
One section per registry: merge semantics, the Data table the merge
writes, and the value schema. Where Gold differs -- a different table, a
different record, or no home at all -- the registry carries a Gen 2
subsection built from the same catalog entry. Concepts and verbs:
Concepts: Registries.
Reading this reference
Use the wiki's Choose-A-Registry guide when you know what you want
to make but not the registry name. This page is the precise schema
catalog once you have chosen one.
Type notation
string,number,boolean, andfunctionname the Lua value to supply. A function is code the engine calls later; see the linked concept/reference page for its arguments and return value.{ field, otherField? }is a record (a Lua table with named fields). A?means that field is optional.list of Tis an ordered Lua table of values shaped likeT;map of K -> Vmaps each key to a value shaped likeV.A | Bmeans either shape is accepted.moves id,items id, and similar phrases mean the internal id of a record in that registry, not its displayed name.
Example status
Every example below is shape only. Put an adapted call in your mod
entry file. Replace ... and names such as fn with real values, and
supply every field marked required when registering a new record.
ai_classes
- semantics:
record - target:
Data.ai_classes
| field | type | required |
|---|---|---|
brain |
function | no |
chance |
integer 0..256 | no |
choose |
function | no |
hpBelow |
integer >= 1 | no |
item |
items id | no |
kind |
one of "class" | "layer" | "brain" | no |
onStatus |
boolean | no |
score |
function | no |
switch |
boolean | no |
switchBelow |
integer >= 1 | no |
switchChance |
integer 0..256 | no |
uses |
integer >= 0 | no |
mod.content.ai_classes:patch("OPP_BROCK", { uses = 9 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2AiClasses
On Gen 3
- semantics:
record - target:
Data.gen3AiClasses
apricorns
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
| field | type | required |
|---|---|---|
apricorn |
items id | yes |
ball |
items id | yes |
event |
integer >= 0 | yes |
index |
integer >= 1 | yes |
mod.content.apricorns:override("RED_APRICORN", { apricorn = "RED_APRICORN", ball = "ULTRA_BALL", event = 600, index = 1 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Apricorns
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
audio
- semantics:
record - target:
Data.audio - deprecated -- use sfx / cries / map_songs / music
- value: any value
mod.content.audio:override("mapSongs", { ... })
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
balls
- semantics:
record - target:
Data.balls
| field | type | required |
|---|---|---|
attempt |
function | no |
autoCatch |
boolean | no |
flicker |
boolean | no |
hpFactor |
integer >= 1 | no |
randMax |
integer 0..255 | yes |
tossAnim |
string | no |
wobbleFactor |
integer >= 1 | no |
mod.content.balls:override("GREAT_BALL", { randMax = 180, hpFactor = 12 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Balls
On Gen 3
- semantics:
record - target:
Data.balls
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
autoCatch |
boolean | no |
multiplier |
integer 0..255 | no |
mod.content.balls:register("MOD_BALL", { multiplier = 25 })
battle_anims
- semantics:
record - target:
Data.battle_anims - value: {seq, source?} | {blocks, type?} | {height, path, source?, tiles, width}
mod.content.battle_anims:register("SHADOW_BALL", { seq = { ... } })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2BattleAnims
The record differs; the registry name, the verbs and the id space do not.
Id = a top-level key of the target table. Keys not listed here are accepted and merged as-is.
| key | type |
|---|---|
bank |
integer >= 0 |
framesets |
map of string -> list of list of any value |
generation |
integer >= 1 |
gfx |
map of string -> {image, tiles, wide} |
ids |
map of string -> string |
moves |
map of string -> string |
oamsets |
map of string -> {sprites, vtile} |
objects |
map of string -> {fixY?, flags?, frameset, func, gfx, palette} |
scriptOrder |
list of string |
scripts |
map of string -> list of list of any value |
source |
string |
mod.content.battle_anims:patch("moves", { SHADOW_BALL = "5e86" })
On Gen 3
- semantics:
record - target:
Data.gen3BattleAnims
The record differs; the registry name, the verbs and the id space do not.
- value: {seq, source?}
mod.content.battle_anims:register("SHADOW_BALL", { seq = { { op = "createvisualtask", task = "AnimTask_ShakeMon", priority = 2, args = { "target", 3, 0, 6, 1 } }, { op = "waitforvisualfinish" }, { op = "end" } } })
On Gen 3 the id is a move id and seq is the battle animation script the cart runs for it: rows of the same op vocabulary the ROM pack uses (createsprite, createvisualtask, delay, playsewithpan, waitforvisualfinish, end). A native move id replaces its animation. Gen 1 subanimation and tilesheet records do not exist on Gen 3.
battle_sprite_scales
- semantics:
record - target:
Data.battle_sprite_scales
| field | type | required |
|---|---|---|
path |
file path | yes |
scale |
number 0.25..4 | yes |
mod.content.battle_sprite_scales:register("abra_back", {
path = "assets/generated/battle/back/abrab.png",
scale = 1.5,
})
Scales one battle pic by its asset path, overriding the species-level
battleScaleFront/battleScaleBack (see pokemon) for that
image. The only way to scale a pic that is not species-keyed, like the
player's trainer back sprite. Resolution order at draw time:
image-level, then species-level, then the defaults (1x front, 2x back).
The pic stays grounded at any scale: player feet stay flush on the
text-box top, the enemy pic stays bottom-pinned in its slot, and the
scale composes with the send-out grow animation.
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
commands
- semantics:
record - target:
Data.commands - value: function | {blocking?, fn, foreground?}
mod.content.commands:register("shake_screen", function(ctx, frames) ... end)
constants
- semantics:
deep - target:
Data.constants
Id = a top-level key of the target table. Keys not listed here are accepted and merged as-is.
| key | type |
|---|---|
badges |
list of {icon?, id, item?, name?} |
bagSize |
integer >= 1 |
boxCount |
integer >= 1 |
boxSize |
integer >= 1 |
coinCap |
integer >= 0 |
dexDigits |
integer >= 1 |
dexSize |
integer >= 1 |
encounterBuckets |
list of integer 1..256 |
hmMoves |
list of moves id |
levelCap |
integer >= 1 |
moneyCap |
integer >= 0 |
moveMax |
integer >= 1 |
partyMax |
integer >= 1 |
mod.content.constants:patch("levelCap", 80)
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Constants
The record differs; the registry name, the verbs and the id space do not.
Id = a top-level key of the target table. Keys not listed here are accepted and merged as-is.
| key | type |
|---|---|
battleAnimBgPaletteOrder |
list of string |
battleAnimFramesetOrder |
list of string |
battleAnimFuncOrder |
list of string |
battleAnimGfxOrder |
list of string |
battleAnimOamsetOrder |
list of string |
battleAnimObPaletteOrder |
list of string |
battleAnimObjectOrder |
list of string |
battleBgEffectOrder |
list of string |
cmdQueueOrder |
list of string |
decoDescOrder |
list of string |
eggGroupOrder |
list of string |
environmentOrder |
list of string |
evolveMethodOrder |
list of string |
fishGroupOrder |
list of string |
floorOrder |
list of string |
generation |
integer >= 1 |
growthRateOrder |
list of string |
heldEffectOrder |
list of string |
iconOrder |
list of string |
itemMenuOrder |
list of string |
itemNameCount |
integer >= 0 |
itemOrder |
list of string |
landmarkOrder |
list of string |
mapCallbackOrder |
list of string |
mapGroups |
list of {group, height, map, name, width} |
mapOrder |
list of string |
moveEffectOrder |
list of string |
moveOrder |
list of string |
musicOrder |
list of string |
numOverworldSprites |
integer >= 0 |
paletteOrder |
list of string |
phoneContactOrder |
list of string |
pocketOrder |
list of string |
sfxOrder |
list of string |
source |
string |
spawnOrder |
list of string |
specialCallOrder |
list of string |
specialOrder |
list of string |
speciesOrder |
list of string |
spriteOrder |
list of string |
spritePokemon |
integer >= 0 |
stdScriptOrder |
list of string |
tilesetOrder |
list of string |
tradeDialogOrder |
list of string |
tradeGenderOrder |
list of string |
trainerClassMembers |
map of string -> list of string |
trainerClassOrder |
list of string |
trainerTypeOrder |
list of string |
treeMonSetOrder |
list of string |
types |
map of string -> integer >= 0 |
mod.content.constants:patch("speciesOrder", { [252] = "MODMON" })
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
cries
- semantics:
record - target:
Data.audio.cries - value: {header, length, pitch} | {file} | {base, length?, pitch?} | {chip, length?, pitch?}
mod.content.cries:patch("PIKACHU", { pitch = 200 })
On Gold (Gen 2)
- semantics:
record - target:
Data.audio.cries
The record differs; the registry name, the verbs and the id space do not.
- value: {header, length, pitch} | {file} | {base, length?, pitch?} | {chip, length?, pitch?}
decorations
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
| field | type | required |
|---|---|---|
action |
string | no |
flag |
integer >= 0 | yes |
name |
string | yes |
sprite |
integer 0..255 | yes |
type |
integer 1..6 | yes |
mod.content.decorations:patch("deco:2", { name = "COZY" })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Decorations
On Gen 3
- semantics:
record - target on
emerald,ruby,sapphire:Data.gen3Decorations
Not available on the other Gen 3 versions: a write there is dropped and reported.
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
category |
integer 0..7 | yes |
description |
string | yes |
id |
string | no |
index |
integer 1..255 | yes |
name |
string | yes |
permission |
integer 0..3 | yes |
price |
integer 0..65535 | yes |
shape |
integer 0..9 | yes |
tiles |
list of integer 0..1023 | yes |
mod.content.decorations:register("DECOR_MOD_DESK", { name = "MOD DESK", index = 130, permission = 0, shape = 0, category = 0, price = 500, description = "A desk.", tiles = { 640 } })
A Gen 3 decoration is a gDecorations row (Ruby, Sapphire and Emerald only). index is the decoration id the bag, the secret base save and scripts use; an id the cart already has replaces that row. permission is DECORPERM_SOLID_FLOOR..NA_WALL (0..3: sprite decorations are not moddable), shape DECORSHAPE_, category DECORCAT_, and tiles the metatile ids painted row by row.
encounters
- semantics:
record - target:
Data.encounters
| field | type | required |
|---|---|---|
grass |
{rate, slots} | no |
id |
string | no |
water |
{rate, slots} | no |
mod.content.encounters:patch("ROUTE_1", { grass = { rate = 30 } })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Encounters
The record differs; the registry name, the verbs and the id space do not.
Id = a top-level key of the target table. The set below is closed: an id that is not one of these is rejected rather than merged, because the engine reads this table by name and a key it does not name is a write nothing reads.
| key | type |
|---|---|
bugContest |
list of {chance, max, min, species} |
fishGroups |
map of string -> {chance, good, id?, index?, old, super} |
generation |
integer >= 1 |
grass |
map of string -> {map?, rates, slots} |
roamMaps |
list of {map, to} |
roamMons |
list of {level?, map?, mapGroup?, mapNumber?, species?} |
rocks |
map of string -> string |
source |
string |
swarmGrass |
map of string -> {map?, rates, slots} |
swarmWater |
map of string -> {map?, rate, slots} |
timeFishGroups |
map of string | integer 0..255 -> {day, nite} |
treeMonsAsleep |
{DAY, MORN, NITE} |
treeSets |
map of string -> {common, rare?} |
trees |
map of string -> string |
water |
map of string -> {map?, rate, slots} |
mod.content.encounters:patch("grass", { ROUTE_29 = { rates = { NITE = 40 } } })
Gold's encounter ids are a closed set: the kinds above are
the complete set of lookups the engine makes into Data.gen2Encounters, so an
id that is not one of them is a write nothing reads. An id outside the set is
rejected -- a Gen 1 mod ported unchanged passes the map where Gold wants the
kind, and that call is refused rather than silently dropped.
On Gen 3
- semantics:
record - target:
Data.gen3Encounters
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
fishing |
{rate, slots, ...} | no |
grass |
{rate, slots, ...} | no |
id |
string | no |
land |
{rate, slots, ...} | no |
mapGroup |
integer >= 0 | no |
mapNum |
integer >= 0 | no |
rocks |
{rate, slots, ...} | no |
water |
{rate, slots, ...} | no |
mod.content.encounters:patch("FR_ROUTE_1", { land = { rate = 30 } })
evolution_methods
- semantics:
record - target:
Data.evolution_methods
| field | type | required |
|---|---|---|
check |
function | yes |
describe |
function | no |
mod.content.evolution_methods:register("FRIENDSHIP", { check = fn })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2EvolutionMethods
field
- semantics:
deep - target:
Data.field
Id = a top-level key of the target table. Keys not listed here are accepted and merged as-is.
| key | type |
|---|---|
badgeGates |
map of string -> {badge?, coords?, failText?, guards?, passText?, passedFlag?, text?} |
boot |
{lastHeal?, namePresets?, playerName?, rivalName?, screens?, startFacing?, startMap?, startMoney?, startX?, startY?, starterScript?, title?} |
flyOrder |
list of string |
hiddenItems |
map of string -> list of {item, x, y} |
ledges |
list of {facing, input, ledgeTile, standingTile, tileset?} |
playerPics |
{back?, demoBack?, front?, oakBack?} |
townMap |
{background?, cursorOrder?, gridPixelSize?, locations?, nest?, upArrow?} |
mod.content.field:patch("boot", { startMap = "SABLE_COVE" })
On Gold (Gen 2)
- semantics:
deep - target:
Data.field
The record differs; the registry name, the verbs and the id space do not.
Id = a top-level key of the target table. The set below is closed: an id that is not one of these is rejected rather than merged, because the engine reads this table by name and a key it does not name is a write nothing reads.
| key | type |
|---|---|
boot |
{namePresets?, rivalName?, startFacing?, startMap?, startMoney?, startX?, startY?} |
emotes |
{bolt?, cutGrass?, fish?, fishing?, fishingFemale?, grassRustle?, happy?, heart?, jumpShadow?, order?, question?, sad?, shock?, sleep?} |
mod.content.field:patch("boot", { startMap = "NEW_BARK_TOWN", startX = 6, startY = 8 })
Gold reads boot and emotes. boot is the New Game spawn (startMap, startX, startY, startFacing, replacing SPAWN_HOME), the starting money, the rival's starting name and the naming presets. emotes is the overworld emote art, one image path per sheet: the showemote bubbles listed in order, grassRustle, jumpShadow, cutGrass, the fishing pose fishing and Crystal's fishingFemale; a patched path is the sheet the overworld draws. Every other Gen 1 key has no Gold consumer: ledges (Gold's ledges are tile collision types), hiddenItems (bg events in maps), badgeGates, townMap (landmarks), flyOrder (the flypoint table), playerPics, and boot.lastHeal, boot.screens, boot.starterScript, boot.title, boot.playerName.
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
font
- semantics:
record - target:
Data.font - value: {advance?, base, charmap?, glyphsPerRow?, image} | {code, seq} | {bold?, file?, size?, spacing?, tiles?, yOffset?}
mod.content.font:register("charmap:hiragana_a", { seq = "あ", code = 256 })
On Gen 3
- semantics:
record - target:
Data.gen3Font
growth_rates
- semantics:
record - target:
Data.growth_rates
| field | type | required |
|---|---|---|
expForLevel |
function | yes |
mod.content.growth_rates:register("ERRATIC", { expForLevel = fn })
held_items
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
| field | type | required |
|---|---|---|
heldEffect |
string | yes |
heldParameter |
integer 0..255 | no |
mod.content.held_items:override("LEFTOVERS", { heldEffect = "HELD_LEFTOVERS", heldParameter = 0 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2HeldItems
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
icons
- semantics:
record - target:
Data.icons.bySpecies - value: string | {frames?, image, trueColor?}
mod.content.icons:register("MODMON", "QUADRUPED") -- a built-in name, or { image = mod.assets:path("icon.png"), frames = 2 }
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Icons
The record differs; the registry name, the verbs and the id space do not.
- value: string | {frames, height, id?, image, index?, trueColor?, width}
mod.content.icons:override("TOTODILE", "ICON_MONSTER")
item_effects
- semantics:
record - target:
Data.item_effects
| field | type | required |
|---|---|---|
battle |
boolean | no |
field |
boolean | no |
needsTarget |
boolean | no |
use |
function | yes |
mod.content.item_effects:register("MOON_FLUTE", { use = fn, field = true })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2ItemEffects
items
- semantics:
record - target:
Data.items
| field | type | required |
|---|---|---|
ball |
balls id | no |
effect |
item_effects id | no |
id |
string | yes |
index |
integer 0..255 | no |
machine |
{kind, move, number} | no |
name |
string | yes |
needsTarget |
boolean | no |
price |
integer >= 0 | yes |
tossable |
boolean | no |
mod.content.items:patch("POTION", { price = 100 })
On Gold (Gen 2)
- semantics:
record - target:
Data.items
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
ball |
balls id | no |
effect |
item_effects id | no |
id |
string | yes |
index |
integer 1..65535 | no |
machine |
{kind, move, number} | no |
name |
string | no |
needsTarget |
boolean | no |
price |
integer >= 0 | yes |
tossable |
boolean | no |
New records receive an unused script index above the native range, up to 65535. Existing indices cannot change; collisions and reserved species 253, move 255 and item 255 are rejected. Cartridge save export refuses named records whose index exceeds one byte.
On Gen 3
- semantics:
record - target:
Data.gen3Items
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
battleUsage |
integer 0..255 | no |
description |
string | no |
effect |
item_effects id | list of integer 0..255 | no |
fieldUse |
string | no |
holdEffect |
integer 0..255 | no |
holdEffectParam |
integer 0..255 | no |
id |
string | yes |
importance |
integer 0..255 | no |
index |
integer 1..65535 | no |
name |
string | yes |
pocket |
string | no |
price |
integer >= 0 | yes |
registrability |
integer 0..255 | no |
secondaryId |
integer >= 0 | no |
landmarks
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
| field | type | required |
|---|---|---|
id |
string | no |
index |
integer >= 0 | yes |
name |
string | yes |
x |
integer -8..247 | yes |
y |
integer -16..239 | yes |
mod.content.landmarks:patch("LANDMARK_ROUTE_29", { x = 12 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Landmarks.landmarks
On Gen 3
- semantics:
record - target:
Data.gen3Landmarks
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
height |
integer >= 1 | no |
id |
string | no |
index |
integer 0..255 | yes |
name |
string | yes |
region |
integer 0..3 | no |
theme |
one of "wood" | "marble" | "stone" | "brick" | "underwater" | "stone2" | no |
width |
integer >= 1 | no |
x |
integer >= 0 | no |
y |
integer >= 0 | no |
mod.content.landmarks:register("MAPSEC_MOD_COVE", { name = "MOD COVE", index = 230, theme = "wood", x = 4, y = 6 })
A Gen 3 landmark is a map section (the byte a map header carries as regionMapSectionId). index names the section: an index the cart already uses renames and re-themes it, a free one adds a new section. x/y (and width/height, default 1) are zero-based region map cells the cursor resolves to this section; region picks the FireRed region layout (0 Kanto, 1..3 Sevii) and Ruby/Sapphire/Emerald ignore it. The pretty tilemap art is not redrawn.
link_fields
- semantics:
record - target:
Data.link_fields
Cart protocol only: this registry does not make a freely enabled loose mod eligible for player link play. Player links are set up in the launcher with a vanilla cart or a sealed custom cart.
| field | type | required |
|---|---|---|
pack |
function | no |
rev |
integer >= 0 | string | yes |
unpack |
function | no |
mod.content.link_fields:register("held_item", { rev = 1, pack = fn, unpack = fn })
On Gold (Gen 2)
No Gen 2 home: Gold reimplements this system without reading the
registry, so a write here is dropped and reported on a Gold boot.
docs/mod-api-gen2-compat.md in the engine repo lists what is left
to do for each one.
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
map_scripts
- semantics:
compose - target:
Data.map_scripts - value: {onBoulderMoved?, onEnter?, onInteract?, onStep?, onVictory?, priority?, scripts?, snorlaxWake?, talk?}
mod.content.map_scripts:register("PALLET_TOWN", { talk = { ... } })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Scripts
The record differs; the registry name, the verbs and the id space do not.
- value: list of any value
mod.content.map_scripts:register("MYMOD_TALK", { { op = "jumptextfaceplayer", text = "MYMOD_HELLO" } })
On Gen 3
- semantics:
record - target:
Data.gen3Scripts
The record differs; the registry name, the verbs and the id space do not.
- value: list of any value
mod.content.map_scripts:override("EventScript_BufferItemsPocket", { { op = "return" } })
map_songs
- semantics:
record - target:
Data.audio.mapSongs - value: music id
mod.content.map_songs:override("PALLET_TOWN", "Music_Routes1")
maps
- semantics:
record - target:
Data.maps
| field | type | required |
|---|---|---|
blocks |
list of integer 0..255 | yes |
borderBlock |
integer 0..255 | no |
connections |
map of one of "north" | "south" | "east" | "west" -> any value | no |
height |
integer >= 1 | yes |
id |
string | yes |
index |
integer >= 0 | no |
label |
string | no |
objects |
list of {pokemon?, ...} | no |
outdoor |
boolean | no |
palette |
string | no |
signs |
list of any value | no |
tileset |
tilesets id | yes |
warps |
list of {destGroup?, destMap, destMapNum?, destWarp, x, y} | no |
width |
integer >= 1 | yes |
mod.content.maps:register("MY_CAVE", { tileset = "CAVERN", ... })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Maps
On Gen 3
- semantics:
record - target:
Data.maps
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
connections |
any value | no |
height |
integer >= 0 | no |
id |
string | no |
name |
string | no |
objects |
list of any value | no |
tileset |
any value | no |
warps |
list of any value | no |
width |
integer >= 0 | no |
mod.content.maps:patch("FR_PALLET_TOWN", { weather = 2 })
marts
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
Id = a top-level key of the target table. The set below is closed: an id that is not one of these is rejected rather than merged, because the engine reads this table by name and a key it does not name is a write nothing reads.
| key | type |
|---|---|
0 |
list of items id |
1 |
list of items id |
10 |
list of items id |
11 |
list of items id |
12 |
list of items id |
13 |
list of items id |
14 |
list of items id |
15 |
list of items id |
16 |
list of items id |
17 |
list of items id |
18 |
list of items id |
19 |
list of items id |
2 |
list of items id |
20 |
list of items id |
21 |
list of items id |
22 |
list of items id |
23 |
list of items id |
24 |
list of items id |
25 |
list of items id |
26 |
list of items id |
27 |
list of items id |
28 |
list of items id |
29 |
list of items id |
3 |
list of items id |
30 |
list of items id |
31 |
list of items id |
32 |
list of items id |
33 |
list of items id |
4 |
list of items id |
5 |
list of items id |
6 |
list of items id |
7 |
list of items id |
8 |
list of items id |
9 |
list of items id |
bargain |
list of {item, price} |
mod.content.marts:patch("0", { "ULTRA_BALL" })
Gen 2 only. Ids "0".."33" are the script mart numbers, not MART_* names. The "bargain" id takes ordered { item, price } rows. Patches replace the whole list, including an empty list; remove leaves an empty shelf. Append and prepend wrappers are not accepted. Ordinary prices come from items.
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Marts
The record differs; the registry name, the verbs and the id space do not.
Id = a top-level key of the target table. The set below is closed: an id that is not one of these is rejected rather than merged, because the engine reads this table by name and a key it does not name is a write nothing reads.
| key | type |
|---|---|
0 |
list of items id |
1 |
list of items id |
10 |
list of items id |
11 |
list of items id |
12 |
list of items id |
13 |
list of items id |
14 |
list of items id |
15 |
list of items id |
16 |
list of items id |
17 |
list of items id |
18 |
list of items id |
19 |
list of items id |
2 |
list of items id |
20 |
list of items id |
21 |
list of items id |
22 |
list of items id |
23 |
list of items id |
24 |
list of items id |
25 |
list of items id |
26 |
list of items id |
27 |
list of items id |
28 |
list of items id |
29 |
list of items id |
3 |
list of items id |
30 |
list of items id |
31 |
list of items id |
32 |
list of items id |
33 |
list of items id |
4 |
list of items id |
5 |
list of items id |
6 |
list of items id |
7 |
list of items id |
8 |
list of items id |
9 |
list of items id |
bargain |
list of {item, price} |
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
migrations
- semantics:
compose - target: none
- value: {run, since}
mod.content.migrations:register("my_mod", { since = "1.0.0", run = fn })
move_effects
- semantics:
record - target:
Data.move_effects
| field | type | required |
|---|---|---|
accuracyChecked |
boolean | no |
kind |
one of "primary" | "secondary" | "full" | yes |
missText |
one of "didntAffect" | "butItFailed" | "evadedAttack" | no |
run |
function | no |
mod.content.move_effects:register("DRAIN_PP_EFFECT", { kind = "primary", run = fn })
A "primary" handler returns its messages as an array. Set failed = true on that table when the effect did not land ("But, it failed!", "Nothing happened!", a target already asleep): the battle suppresses the move's success animation on that flag, the way the cart prints those refusals with no animation.
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2MoveEffects
On Gen 3
- semantics:
record - target:
Data.gen3MoveEffects
moves
- semantics:
record - target:
Data.moves
| field | type | required |
|---|---|---|
accuracy |
integer 0..100 | yes |
anim |
any value | no |
category |
one of "physical" | "special" | "status" | no |
chargeText |
string | no |
counterable |
boolean | no |
effect |
move_effects id | yes |
fixedDamage |
integer >= 1 | function | no |
highCrit |
boolean | no |
id |
string | yes |
index |
integer 0..255 | no |
multiHit |
integer >= 1 | list of integer >= 1 | no |
name |
string | yes |
power |
integer 0..255 | yes |
pp |
integer 0..64 | yes |
priority |
integer -7..7 | no |
semiInvulnerable |
boolean | no |
type |
type_chart id | yes |
mod.content.moves:patch("BLIZZARD", { accuracy = 70 })
On Gold (Gen 2)
- semantics:
record - target:
Data.moves
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
accuracy |
integer 0..100 | yes |
anim |
any value | no |
category |
one of "physical" | "special" | "status" | no |
chargeText |
string | no |
counterable |
boolean | no |
effect |
move_effects id | yes |
fixedDamage |
integer >= 1 | function | no |
highCrit |
boolean | no |
id |
string | yes |
index |
integer 1..65535 | no |
multiHit |
integer >= 1 | list of integer >= 1 | no |
name |
string | yes |
power |
integer 0..255 | yes |
pp |
integer 0..64 | yes |
priority |
integer -7..7 | no |
semiInvulnerable |
boolean | no |
type |
type_chart id | yes |
New records receive an unused script index above the native range, up to 65535. Existing indices cannot change; collisions and reserved species 253, move 255 and item 255 are rejected. Cartridge save export refuses named records whose index exceeds one byte.
On Gen 3
- semantics:
record - target:
Data.gen3Moves
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
accuracy |
integer 0..100 | yes |
category |
one of "physical" | "special" | "status" | no |
effect |
integer 0..255 | no |
flags |
integer 0..255 | no |
id |
string | yes |
index |
integer 1..65535 | no |
name |
string | yes |
power |
integer 0..255 | yes |
pp |
integer 0..64 | yes |
priority |
integer -7..7 | no |
secondaryChance |
integer 0..100 | no |
target |
integer 0..255 | no |
type |
type_chart id | yes |
music
- semantics:
record - target:
Data.audio.songs - value: {address, bank, engine?} | {file, intro?, loopFile?, loopSeconds?, seconds?} | {channels, drums?, program, waves?} | {chip}
mod.content.music:register("MOD_SONG", { file = "song.ogg" })
palettes
- semantics:
record - target:
Data.palettes.palettes - value: list of list of integer 0..255 | {colors}
mod.content.palettes:override("MEWMON", { {255,255,255}, ... })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Palettes
The record differs; the registry name, the verbs and the id space do not.
Id = a top-level key of the target table. Keys not listed here are accepted and merged as-is.
| key | type |
|---|---|
battleObjects |
map of string -> list of list of integer 0..255 |
bg |
list of list of list of integer 0..255 |
daytimes |
list of string |
environments |
map of string -> map of one of "MORN" | "DAY" | "NITE" | "DARK" -> list of integer >= 0 |
expBar |
list of list of integer 0..255 |
generation |
integer >= 1 |
hpBar |
map of one of "green" | "yellow" | "red" | "blue" -> list of list of integer 0..255 |
objects |
map of one of "MORN" | "DAY" | "NITE" | "DARK" -> list of list of list of integer 0..255 |
partyMenu |
list of list of list of integer 0..255 |
pokemon |
map of string -> {normal, shiny} |
roofSlot |
integer 0..7 |
roofs |
map of integer >= 0 -> {mornDay, nite} |
slotNames |
list of string |
source |
string |
trainers |
map of string -> list of list of integer 0..255 |
mod.content.palettes:patch("pokemon", { TOTODILE = { shiny = { {255,255,255}, {255,0,0} } } })
On Gen 3
- semantics:
record - target:
Data.gen3Palettes
phone_contacts
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
| field | type | required |
|---|---|---|
callee |
string | no |
calleeKey |
string | no |
calleeTime |
integer 0..7 | no |
caller |
string | no |
callerKey |
string | no |
callerTime |
integer 0..7 | no |
class |
string | no |
index |
integer 0..255 | no |
map |
maps id | no |
member |
string | no |
name |
string | no |
number |
integer 0..255 | no |
rematchEvent |
integer 0..2047 | no |
mod.content.phone_contacts:patch("PHONE_YOUNGSTER_JOEY", { map = "ROUTE_31" })
New contacts may omit index to append after the mounted game's native book. Indices are 1..255; native rows and holes are reserved and existing indices cannot change. Supply a name or trainer class/member, and callerKey/calleeKey map_scripts keys for enabled time masks. rematchEvent is a numeric event bit. The saved book keeps ten numeric slots; use explicit indices for stability when changing the enabled mod set.
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2PhoneContacts
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
pokemon
- semantics:
record - target:
Data.pokemon
| field | type | required |
|---|---|---|
baseExp |
integer 0..255 | yes |
baseStats |
{attack, defense, hp, special, speed} | yes |
battleScaleBack |
number 0.25..4 | no |
battleScaleFront |
number 0.25..4 | no |
battleTheme |
music id | no |
catchRate |
integer 0..255 | yes |
cry |
cries id | no |
dex |
integer >= 1 | yes |
dexEntry |
{heightFt, heightIn, heightM?, kind, text, text2?, weight, weightKg?} | no |
evolutions |
list of {item?, level?, method, species} | yes |
frontSize |
integer 1..7 | yes |
growthRate |
growth_rates id | yes |
icon |
string | {frames?, image} | no |
id |
string | yes |
index |
integer 0..255 | no |
learnset |
list of {level, move} | yes |
level1Moves |
list of moves id | yes |
name |
string | yes |
palette |
palettes id | no |
spriteBack |
file path | yes |
spriteFront |
file path | yes |
tmhm |
list of moves id | no |
trueColor |
boolean | no |
types |
list of type_chart id | yes |
mod.content.pokemon:patch("MEW", { baseStats = { attack = 120 } })
On Gold (Gen 2)
- semantics:
record - target:
Data.pokemon
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
baseExp |
integer 0..255 | yes |
baseStats |
{attack, defense, hp, specialAttack, specialDefense, speed} | yes |
battleScaleBack |
number 0.25..4 | no |
battleScaleFront |
number 0.25..4 | no |
battleTheme |
music id | no |
catchRate |
integer 0..255 | yes |
cry |
cries id | no |
dex |
integer >= 1 | yes |
dexEntry |
{height?, heightM?, kind?, text?, text2?, weight?, weightKg?} | no |
eggGroups |
list of string | no |
eggGroupsRaw |
integer 0..255 | no |
eggMoves |
list of moves id | no |
eggSteps |
integer >= 0 | no |
evolutions |
list of {comparison?, into, item?, level?, method, time?} | yes |
genderRatio |
integer 0..255 | no |
growthRate |
growth_rates id | yes |
growthRateId |
integer 0..255 | no |
id |
string | yes |
index |
integer 1..65535 | no |
items |
list of items id | no |
levelMoves |
list of {level, move} | yes |
name |
string | yes |
picSize |
integer 1..7 | yes |
source |
string | no |
spriteBack |
file path | yes |
spriteFront |
file path | yes |
tmhm |
list of moves id | no |
tmhmRaw |
list of integer 0..255 | no |
trueColor |
boolean | no |
types |
list of type_chart id | yes |
mod.content.pokemon:patch("TOTODILE", { baseStats = { specialAttack = 80 } })
New records receive an unused script index above the native range, up to 65535. Existing indices cannot change; collisions and reserved species 253, move 255 and item 255 are rejected. Cartridge save export refuses named records whose index exceeds one byte.
On Gen 3
- semantics:
record - target:
Data.gen3Pokemon
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
abilities |
list of string | integer 0..255 | no |
baseExp |
integer 0..255 | yes |
baseStats |
{attack, defense, hp, specialAttack, specialDefense, speed} | yes |
catchRate |
integer 0..255 | yes |
dex |
integer >= 1 | no |
dexEntry |
{height, heightM?, kind, weight, weightKg?} | no |
eggCycles |
integer 0..255 | no |
eggGroups |
list of integer 0..255 | no |
eggMoves |
list of moves id | no |
evolutions |
list of {item?, level?, method, param?, species} | yes |
friendship |
integer 0..255 | no |
genderRatio |
integer 0..255 | no |
growthRate |
growth_rates id | yes |
id |
string | yes |
index |
integer 1..65535 | no |
itemCommon |
items id | no |
itemRare |
items id | no |
learnset |
list of {level, move} | yes |
name |
string | yes |
spriteBack |
file path | yes |
spriteFront |
file path | yes |
tmhm |
list of moves id | no |
trueColor |
boolean | no |
types |
list of type_chart id | yes |
mod.content.pokemon:patch("MEW", { baseStats = { specialAttack = 120 } })
radio_channels
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
| field | type | required |
|---|---|---|
channel |
integer 0..255 | no |
name |
string | no |
mod.content.radio_channels:register("PIRATE_RADIO", { channel = 9, name = "PIRATE RADIO" })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2RadioChannels
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
render_pipelines
- semantics:
record - target:
Data.render_pipelines
| field | type | required |
|---|---|---|
available |
function | no |
drawWorld |
function | no |
gate |
function | no |
hotkey |
string | no |
invalidate |
function | no |
label |
string | yes |
levels |
list of string | no |
present |
function | no |
priority |
number | no |
update |
function | no |
worldPresent |
function | no |
mod.content.render_pipelines:register("voxel", { label = "VOXEL", levels = { "OFF", "15", "35", "50" }, drawWorld = fn })
rom_text
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no native target for this registry. A write here on a Gen 1 boot is dropped and reported. See the Gold subsection below for where it does land.
- value: string
mod.content.rom_text:override("_WokeUpText", "%s se réveille !")
On Gold (Gen 2)
- semantics:
record - target:
Data.text
On Gen 3
- semantics:
record - target:
Data.gen3RomText
The record differs; the registry name, the verbs and the id space do not.
- value: string | list of any value
rulesets
- semantics:
record - target:
Data.rulesets
| field | type | required |
|---|---|---|
name |
string | yes |
mod.content.rulesets:register("no_crits", { name = "no crits", critRate = 0 })
On Gold (Gen 2)
No Gen 2 home: Gold reimplements this system without reading the
registry, so a write here is dropped and reported on a Gold boot.
docs/mod-api-gen2-compat.md in the engine repo lists what is left
to do for each one.
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
screens
- semantics:
record - target:
Data.screens - value: function | {new}
mod.content.screens:register("QuestLog", { new = function(game) ... end })
sfx
- semantics:
record - target:
Data.audio.sfx - value: string | {address, bank, engine?} | {file} | {chip}
mod.content.sfx:register("SFX_MOD_CHIME", { file = "chime.ogg" })
sprites
- semantics:
record - target:
Data.sprites
| field | type | required |
|---|---|---|
anchorX |
number | no |
anchorY |
number | no |
cellColumns |
integer >= 1 | no |
cellHeight |
integer >= 1 | no |
cellWidth |
integer >= 1 | no |
cells |
list of list of {dx?, dy?, flipX?, flipY?, tile} | no |
frameColumns |
integer >= 1 | no |
frameHeight |
integer >= 1 | no |
frameOffset |
integer >= 0 | no |
frameWidth |
integer >= 1 | no |
frames |
integer >= 1 | yes |
id |
string | no |
image |
file path | yes |
paletteSource |
string | no |
trueColor |
boolean | no |
walker |
boolean | no |
mod.content.sprites:register("SPRITE_HERO", { image = "...", frames = 6 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Sprites
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
frames |
integer >= 1 | yes |
icon |
string | no |
id |
string | no |
image |
file path | yes |
palette |
string | no |
paletteId |
integer 0..7 | no |
paletteSource |
string | no |
source |
string | no |
species |
pokemon id | no |
spriteType |
one of "WALKING_SPRITE" | "STANDING_SPRITE" | "STILL_SPRITE" | "POKEMON_SPRITE" | no |
trueColor |
boolean | no |
walker |
boolean | no |
mod.content.sprites:patch("SPRITE_BEAUTY", { palette = "PAL_OW_RED", paletteId = 0 })
statuses
- semantics:
record - target:
Data.statuses
| field | type | required |
|---|---|---|
beforeMove |
function | no |
beforeMovePriority |
integer >= 0 | no |
canInflict |
function | no |
catchBonus |
integer 0..255 | no |
cureOnSwitch |
boolean | no |
hudLabel |
string | no |
id |
string | no |
label |
string | yes |
onInflict |
function | no |
residual |
function | no |
shakeBonus |
integer 0..255 | no |
statPenalty |
{div, stat} | no |
mod.content.statuses:patch("BRN", { catchBonus = 12 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Statuses
On Gen 3
- semantics:
record - target:
Data.gen3Statuses
strings
- semantics:
record - target:
Data.strings - value: string
mod.content.strings:override("But, it failed!", "Echec !")
text
- semantics:
record - target:
Data.text - value: string
mod.content.text:override("_PalletTownText1", "HELLO!")
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Text
The record differs; the registry name, the verbs and the id space do not.
- value: string
On Gen 3
- semantics:
record - target:
Data.gen3Text
The record differs; the registry name, the verbs and the id space do not.
- value: string | list of any value
text_pointers
- semantics:
deep - target:
Data.text_pointers
Id = a top-level key of the target table; every key carries the same shape.
- value: map of string -> {asm?, cableClub?, label?, mart?, nurse?, pc?, text?}
mod.content.text_pointers:patch("PalletTown", { TEXT_PALLETTOWN_SIGN = { text = "_MySign" } })
On Gold (Gen 2)
No Gen 2 home: Gold reimplements this system without reading the
registry, so a write here is dropped and reported on a Gold boot.
docs/mod-api-gen2-compat.md in the engine repo lists what is left
to do for each one.
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
tilesets
- semantics:
record - target:
Data.tilesets
| field | type | required |
|---|---|---|
animation |
string | no |
blocks |
list of any value | yes |
counterTiles |
any value | no |
doorTiles |
any value | no |
id |
string | no |
image |
file path | yes |
imageHeight |
integer >= 1 | no |
imageWidth |
integer >= 1 | no |
tilesPerRow |
integer >= 1 | no |
trueColor |
boolean | no |
walkable |
any value | no |
warpTiles |
any value | no |
mod.content.tilesets:register("MY_TILES", { image = "...", blocks = { ... } })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Tilesets
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
animation |
string | no |
blocks |
list of any value | yes |
counterTiles |
any value | no |
doorTiles |
any value | no |
id |
string | no |
image |
file path | yes |
imageHeight |
integer >= 1 | no |
imageWidth |
integer >= 1 | no |
tilesPerRow |
integer >= 1 | no |
trueColor |
boolean | no |
walkable |
any value | no |
warpTiles |
any value | no |
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
tokens
- semantics:
record - target:
Data.tokens - value: function
mod.content.tokens:register("CLOCK", function(game) return "12" end)
trainers
- semantics:
record - target:
Data.trainers
| field | type | required |
|---|---|---|
aiClass |
ai_classes id | no |
aiMods |
any value | no |
baseMoney |
integer >= 0 | no |
basePic |
trainers id | no |
battleTheme |
music id | no |
brain |
function | no |
id |
string | yes |
index |
integer 0..255 | no |
name |
string | yes |
palette |
palettes id | no |
paletteSource |
string | no |
parties |
list of list of {level, moves?, species} | yes |
partyNames |
map of integer >= 1 -> string | no |
pic |
file path | no |
trueColor |
boolean | no |
mod.content.trainers:patch("OPP_BROCK", { baseMoney = 99 })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2Trainers
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
attributes |
list of integer 0..255 | no |
baseMoney |
integer >= 0 | no |
battleTheme |
music id | no |
encounterMusic |
music id | no |
id |
string | no |
index |
integer 0..255 | no |
items |
list of items id | no |
name |
string | yes |
pic |
file path | no |
trainers |
list of {id?, index?, name, party, trainerType?} | yes |
trueColor |
boolean | no |
mod.content.trainers:patch("BEAUTY", { baseMoney = 99 })
On Gen 3
- semantics:
record - target:
Data.gen3Trainers
The record differs; the registry name, the verbs and the id space do not.
| field | type | required |
|---|---|---|
aiClass |
ai_classes id | no |
aiFlags |
integer >= 0 | no |
aiMods |
list of ai_classes id | no |
baseMoney |
integer >= 0 | no |
class |
integer 0..255 | no |
className |
string | no |
dialogs |
any value | no |
doubleBattle |
boolean | no |
gender |
integer 0..255 | no |
id |
string | no |
items |
list of integer >= 0 | no |
name |
string | yes |
party |
list of {heldItem?, level, moves?, species, ...} | yes |
pic |
integer 0..255 | file path | no |
mod.content.trainers:patch("326", { party = { { species = "MEW", level = 5 } } })
transitions
- semantics:
record - target:
Data.transitions
| field | type | required |
|---|---|---|
draw |
function | no |
flash |
boolean | no |
frames |
integer >= 1 | yes |
sound |
string | no |
mod.content.transitions:register("dissolve", { frames = 30, draw = fn })
On Gen 3
Not available on Gen 3: there is no native target for this registry. A write here is dropped and reported on a Gen 3 boot.
type_chart
- semantics:
record - target:
Data.type_chart - value: {multiplier} | {category, index?, name?}
mod.content.type_chart:register("BUG>PSYCHIC_TYPE", { multiplier = 20 })
v1 aliases
| alias | canonical |
|---|---|
scripts |
map_scripts |
ui |
screens |