Files
gen1recomp/docs/modding/reference/registries.md
T

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, and function name 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 T is an ordered Lua table of values shaped like T; map of K -> V maps each key to a value shaped like V.
  • A | B means 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.

  • 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