Table of contents
- Registry reference
- Reading this reference
- ai_classes
- apricorns
- audio
- balls
- battle_anims
- battle_sprite_scales
- commands
- constants
- cries
- decorations
- encounters
- evolution_methods
- field
- font
- growth_rates
- held_items
- icons
- item_effects
- items
- landmarks
- link_fields
- map_scripts
- map_songs
- maps
- migrations
- move_effects
- moves
- music
- palettes
- phone_contacts
- pokemon
- radio_channels
- render_pipelines
- rom_text
- rulesets
- screens
- sfx
- sprites
- statuses
- strings
- text
- text_pointers
- tilesets
- tokens
- trainers
- transitions
- type_chart
- v1 aliases
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 such system, so there is no Gen 1 table to merge into and 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: the Gen 3 games have no counterpart, so 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: the Gen 3 games have no counterpart, so 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: the Gen 3 games have no counterpart, so 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: the Gen 3 games have no counterpart, so 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 })
decorations
- semantics:
record - target: none
Gen 2 only: Red, Blue and Yellow have no such system, so there is no Gen 1 table to merge into and 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?} |
mod.content.field:patch("boot", { startMap = "NEW_BARK_TOWN", startX = 6, startY = 8 })
Gold reads only boot: the New Game spawn (startMap, startX, startY, startFacing, replacing SPAWN_HOME), the starting money, the rival's starting name and the naming presets. 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: the Gen 3 games have no counterpart, so 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 such system, so there is no Gen 1 table to merge into and 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: the Gen 3 games have no counterpart, so 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 0..255 | no |
machine |
{kind, move, number} | no |
name |
string | yes |
needsTarget |
boolean | no |
price |
integer >= 0 | yes |
tossable |
boolean | no |
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 such system, so there is no Gen 1 table to merge into and 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 >= 0 | yes |
y |
integer >= 0 | 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: the Gen 3 games have no counterpart, so 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 })
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 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 |
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 such system, so there is no Gen 1 table to merge into and 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 | yes |
map |
maps id | no |
member |
string | no |
name |
string | no |
number |
integer 0..255 | no |
mod.content.phone_contacts:patch("PHONE_YOUNGSTER_JOEY", { map = "ROUTE_31" })
On Gold (Gen 2)
- semantics:
record - target:
Data.gen2PhoneContacts
On Gen 3
Not available on Gen 3: the Gen 3 games have no counterpart, so 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 0..255 | 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 } })
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 such system, so there is no Gen 1 table to merge into and 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: the Gen 3 games have no counterpart, so 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 such system, so there is no Gen 1 table to merge into and 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: the Gen 3 games have no counterpart, so 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
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: the Gen 3 games have no counterpart, so 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
On Gen 3
Not available on Gen 3: the Gen 3 games have no counterpart, so 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: the Gen 3 games have no counterpart, so 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 |
Start here
Playing
Tutorials
- Choose a tutorial
- 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
Creative guides
Concepts
Recipes and reference
Author and developer tools
Home · Start Playing · Glossary · Troubleshooting · Repository · Community
Game data is imported locally from a supported ROM supplied by the player. Shared mods contain original work or transform recipes, never extracted game content. Check each guide's target game before using its examples.