-
Notifications
You must be signed in to change notification settings - Fork 2
Reference Registries
bryanthaboi edited this page Jul 19, 2026
·
1 revision
One section per registry: merge semantics, the Data table the merge
writes, and the value schema. Concepts and verbs:
Concepts: Registries.
- 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" |
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 })- semantics:
record - target:
Data.audio - deprecated -- use sfx / cries / map_songs / music
- value: any value
mod.content.audio:override("mapSongs", { ... })- 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 })- semantics:
record - target:
Data.battle_anims - value: {seq, source?} | {blocks, type?} | {height, path, source?, tiles, width}
mod.content.battle_anims:register("SHADOW_BALL", { seq = { ... } })- semantics:
record - target:
Data.commands - value: function | {blocking?, fn, foreground?}
mod.content.commands:register("shake_screen", function(ctx, frames) ... end)- 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)- semantics:
record - target:
Data.audio.cries - value: {header, length, pitch} | {file} | {base, length?, pitch?} | {chip, length?, pitch?}
mod.content.cries:patch("PIKACHU", { pitch = 200 })- 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 } })- semantics:
record - target:
Data.evolution_methods
| field | type | required |
|---|---|---|
check |
function | yes |
describe |
function | no |
mod.content.evolution_methods:register("FRIENDSHIP", { check = fn })- 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?} |
townMap |
{background?, cursorOrder?, gridPixelSize?, locations?, nest?} |
mod.content.field:patch("boot", { startMap = "SABLE_COVE" })- semantics:
record - target:
Data.font - value: {advance?, base, charmap?, glyphsPerRow?, image} | {code, seq}
mod.content.font:register("charmap:hiragana_a", { seq = "あ", code = 256 })- semantics:
record - target:
Data.growth_rates
| field | type | required |
|---|---|---|
expForLevel |
function | yes |
mod.content.growth_rates:register("ERRATIC", { expForLevel = fn })- semantics:
record - target:
Data.icons.bySpecies - value: string | {frames?, image}
mod.content.icons:register("MISSINGNO", { image = "glitch.png" })- 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 })- 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 })- semantics:
record - target:
Data.link_fields
| field | type | required |
|---|---|---|
pack |
function | no |
rev |
integer >= 0 | string |
unpack |
function | no |
mod.content.link_fields:register("held_item", { rev = 1, pack = fn, unpack = fn })- semantics:
compose - target:
Data.map_scripts - value: {onBoulderMoved?, onEnter?, onInteract?, onStep?, onVictory?, priority?, scripts?, snorlaxWake?, talk?}
mod.content.map_scripts:register("PALLET_TOWN", { talk = { ... } })- semantics:
record - target:
Data.audio.mapSongs - value: music id
mod.content.map_songs:override("PALLET_TOWN", "Music_Routes1")- 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" |
height |
integer >= 1 | yes |
id |
string | yes |
index |
integer >= 0 | no |
label |
string | no |
objects |
list of any value | no |
signs |
list of any value | no |
tileset |
tilesets id | yes |
warps |
list of {destMap, destWarp, x, y} | no |
width |
integer >= 1 | yes |
mod.content.maps:register("MY_CAVE", { tileset = "CAVERN", ... })- semantics:
compose - target: none
- value: {run, since}
mod.content.migrations:register("my_mod", { since = "1.0.0", run = fn })- semantics:
record - target:
Data.move_effects
| field | type | required |
|---|---|---|
accuracyChecked |
boolean | no |
kind |
one of "primary" | "secondary" |
run |
function | no |
mod.content.move_effects:register("DRAIN_PP_EFFECT", { kind = "primary", run = fn })- semantics:
record - target:
Data.moves
| field | type | required |
|---|---|---|
accuracy |
integer 0..100 | yes |
anim |
any value | no |
category |
one of "physical" | "special" |
chargeText |
string | no |
counterable |
boolean | no |
effect |
move_effects id | yes |
fixedDamage |
integer >= 1 | function |
highCrit |
boolean | no |
id |
string | yes |
index |
integer 0..255 | no |
multiHit |
integer >= 1 | list of integer >= 1 |
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 })- 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" })- semantics:
record - target:
Data.palettes.palettes - value: list of list of integer 0..255 | {colors}
mod.content.palettes:override("MEWMON", { {255,255,255}, ... })- semantics:
record - target:
Data.pokemon
| field | type | required |
|---|---|---|
baseExp |
integer 0..255 | yes |
baseStats |
{attack, defense, hp, special, speed} | yes |
catchRate |
integer 0..255 | yes |
cry |
cries id | no |
dex |
integer >= 1 | yes |
dexEntry |
{heightFt, heightIn, kind, text, weight} | no |
evolutions |
list of {item?, level?, method, species} | yes |
frontSize |
integer 1..7 | yes |
growthRate |
growth_rates id | yes |
icon |
string | {frames?, image} |
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 } })- semantics:
record - target:
Data.rulesets
| field | type | required |
|---|---|---|
name |
string | yes |
mod.content.rulesets:register("no_crits", { name = "no crits", critRate = 0 })- semantics:
record - target:
Data.screens - value: function | {new}
mod.content.screens:register("QuestLog", { new = function(game) ... end })- semantics:
record - target:
Data.audio.sfx - value: string | {address, bank, engine?} | {file} | {chip}
mod.content.sfx:register("SFX_MOD_CHIME", { file = "chime.ogg" })- semantics:
record - target:
Data.sprites
| field | type | required |
|---|---|---|
frames |
integer >= 1 | yes |
id |
string | no |
image |
file path | yes |
trueColor |
boolean | no |
walker |
boolean | no |
mod.content.sprites:register("SPRITE_HERO", { image = "...", frames = 6 })- 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 })- semantics:
record - target:
Data.text - value: string
mod.content.text:override("_PalletTownText1", "HELLO!")- 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" } })- 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 = { ... } })- semantics:
record - target:
Data.tokens - value: function
mod.content.tokens:register("CLOCK", function(game) return "12" end)- semantics:
record - target:
Data.trainers
| field | type | required |
|---|---|---|
aiClass |
ai_classes id | no |
aiMods |
any value | no |
baseMoney |
integer >= 0 | no |
battleTheme |
music id | no |
brain |
function | no |
id |
string | yes |
index |
integer 0..255 | no |
name |
string | yes |
parties |
list of list of {level, species} | yes |
pic |
file path | no |
mod.content.trainers:patch("OPP_BROCK", { baseMoney = 99 })- 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 })- semantics:
record - target:
Data.type_chart - value: {multiplier} | {category, index?, name?}
mod.content.type_chart:register("BUG>PSYCHIC_TYPE", { multiplier = 20 })| alias | canonical |
|---|---|
scripts |
map_scripts |
ui |
screens |
Engine 1.0.0 · mod API 2 · repository · Discord
This project ships no ROM data. All game content is decoded on the player's machine from their own verified Pokemon Red ROM; mods ship recipes and original assets, never extracted content.
Start here
Concepts
Tutorials
- The ladder
- 01 Sprite and Text Tweak
- 02 Balance Patch
- 03 New Species
- 04 New Item and Ball
- 05 New Move
- 06 NPC and Dialogue
- 07 New Map
- 08 Quest
- 09 Custom Music
- 10 New Mechanic
- 11 Custom UI Screen
- 12 Mini Total Conversion
Reference
Guides
Playing