<!-- Generated by tools/gen_registry_docs.lua from src/mods/Schemas.lua.
     Do not edit by hand; regenerate after any schema change. -->

# 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](Concepts-Registries).

## 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 |

```lua
mod.content.ai_classes:patch("OPP_BROCK", { uses = 9 })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2AiClasses`

## 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 |

```lua
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`

## audio

- semantics: `record`
- target: `Data.audio`
- **deprecated** -- use sfx / cries / map_songs / music
- value: any value

```lua
mod.content.audio:override("mapSongs", { ... })
```

## 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 |

```lua
mod.content.balls:override("GREAT_BALL", { randMax = 180, hpFactor = 12 })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2Balls`

## battle_anims

- semantics: `record`
- target: `Data.battle_anims`
- value: {seq, source?} | {blocks, type?} | {height, path, source?, tiles, width}

```lua
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 |

```lua
mod.content.battle_anims:patch("moves", { SHADOW_BALL = "5e86" })
```

## battle_sprite_scales

- semantics: `record`
- target: `Data.battle_sprite_scales`

| field | type | required |
|---|---|---|
| `path` | file path | yes |
| `scale` | number 0.25..4 | yes |

```lua
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](#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.

## commands

- semantics: `record`
- target: `Data.commands`
- value: function | {blocking?, fn, foreground?}

```lua
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 |

```lua
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 |

```lua
mod.content.constants:patch("speciesOrder", { [252] = "MODMON" })
```

## cries

- semantics: `record`
- target: `Data.audio.cries`
- value: {header, length, pitch} | {file} | {base, length?, pitch?} | {chip, length?, pitch?}

```lua
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 |

```lua
mod.content.decorations:patch("deco:2", { name = "COZY" })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2Decorations`

## encounters

- semantics: `record`
- target: `Data.encounters`

| field | type | required |
|---|---|---|
| `grass` | {rate, slots} | no |
| `id` | string | no |
| `water` | {rate, slots} | no |

```lua
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. Keys not listed here are
accepted and merged as-is.

| 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} |
| `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} |
| `treeSets` | map of string -> {common, rare} |
| `trees` | map of string -> string |
| `water` | map of string -> {map?, rate, slots} |

```lua
mod.content.encounters:patch("grass", { ROUTE_29 = { rates = { NITE = 40 } } })
```

## evolution_methods

- semantics: `record`
- target: `Data.evolution_methods`

| field | type | required |
|---|---|---|
| `check` | function | yes |
| `describe` | function | no |

```lua
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?} |

```lua
mod.content.field:patch("boot", { startMap = "SABLE_COVE" })
```

### 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.

## font

- semantics: `record`
- target: `Data.font`
- value: {advance?, base, charmap?, glyphsPerRow?, image} | {code, seq} | {bold?, file?, size?, spacing?, tiles?, yOffset?}

```lua
mod.content.font:register("charmap:hiragana_a", { seq = "あ", code = 256 })
```

## growth_rates

- semantics: `record`
- target: `Data.growth_rates`

| field | type | required |
|---|---|---|
| `expForLevel` | function | yes |

```lua
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 |

```lua
mod.content.held_items:override("LEFTOVERS", { heldEffect = "HELD_LEFTOVERS", heldParameter = 0 })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2HeldItems`

## icons

- semantics: `record`
- target: `Data.icons.bySpecies`
- value: string | {frames?, image}

```lua
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?, width}

```lua
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 |

```lua
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 |

```lua
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 |

## 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 |

```lua
mod.content.landmarks:patch("LANDMARK_ROUTE_29", { x = 12 })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2Landmarks.landmarks`

## link_fields

- semantics: `record`
- target: `Data.link_fields`

| field | type | required |
|---|---|---|
| `pack` | function | no |
| `rev` | integer >= 0 | string | yes |
| `unpack` | function | no |

```lua
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.

## map_scripts

- semantics: `compose`
- target: `Data.map_scripts`
- value: {onBoulderMoved?, onEnter?, onInteract?, onStep?, onVictory?, priority?, scripts?, snorlaxWake?, talk?}

```lua
mod.content.map_scripts:register("PALLET_TOWN", { talk = { ... } })
```

### 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.

## map_songs

- semantics: `record`
- target: `Data.audio.mapSongs`
- value: music id

```lua
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 |
| `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 |

```lua
mod.content.maps:register("MY_CAVE", { tileset = "CAVERN", ... })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2Maps`

## migrations

- semantics: `compose`
- target: none
- value: {run, since}

```lua
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 |
| `run` | function | no |

```lua
mod.content.move_effects:register("DRAIN_PP_EFFECT", { kind = "primary", run = fn })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2MoveEffects`

## 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 |

```lua
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 |

## music

- semantics: `record`
- target: `Data.audio.songs`
- value: {address, bank, engine?} | {file, intro?, loopFile?, loopSeconds?, seconds?} | {channels, drums?, program, waves?} | {chip}

```lua
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}

```lua
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 |

```lua
mod.content.palettes:patch("pokemon", { TOTODILE = { shiny = { {255,255,255}, {255,0,0} } } })
```

## 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 |
| `number` | integer 0..255 | no |

```lua
mod.content.phone_contacts:patch("PHONE_YOUNGSTER_JOEY", { map = "ROUTE_31" })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2PhoneContacts`

## 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 |
| `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 |

```lua
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 |
| `catchRate` | integer 0..255 | yes |
| `cry` | cries id | no |
| `dex` | integer >= 1 | yes |
| `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 |

```lua
mod.content.pokemon:patch("TOTODILE", { baseStats = { specialAttack = 80 } })
```

## 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 | yes |
| `name` | string | no |

```lua
mod.content.radio_channels:register("PIRATE_RADIO", { channel = 9, name = "PIRATE RADIO" })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2RadioChannels`

## 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 |

```lua
mod.content.render_pipelines:register("voxel", { label = "VOXEL", levels = { "OFF", "15", "35", "50" }, drawWorld = fn })
```

## rulesets

- semantics: `record`
- target: `Data.rulesets`

| field | type | required |
|---|---|---|
| `name` | string | yes |

```lua
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.

## screens

- semantics: `record`
- target: `Data.screens`
- value: function | {new}

```lua
mod.content.screens:register("QuestLog", { new = function(game) ... end })
```

## sfx

- semantics: `record`
- target: `Data.audio.sfx`
- value: string | {address, bank, engine?} | {file} | {chip}

```lua
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 |
| `frameHeight` | integer >= 1 | 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 |

```lua
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 |

```lua
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 |

```lua
mod.content.statuses:patch("BRN", { catchBonus = 12 })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2Statuses`

## strings

- semantics: `record`
- target: `Data.strings`
- value: string

```lua
mod.content.strings:override("But, it failed!", "Echec !")
```

## text

- semantics: `record`
- target: `Data.text`
- value: string

```lua
mod.content.text:override("_PalletTownText1", "HELLO!")
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2Text`

## 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?}

```lua
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.

## 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 |

```lua
mod.content.tilesets:register("MY_TILES", { image = "...", blocks = { ... } })
```

### On Gold (Gen 2)

- semantics: `record`
- target: `Data.gen2Tilesets`

## tokens

- semantics: `record`
- target: `Data.tokens`
- value: function

```lua
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 |
| `paletteSource` | string | no |
| `parties` | list of list of {level, species} | yes |
| `pic` | file path | no |
| `trueColor` | boolean | no |

```lua
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 |
| `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 |

```lua
mod.content.trainers:patch("BEAUTY", { baseMoney = 99 })
```

## transitions

- semantics: `record`
- target: `Data.transitions`

| field | type | required |
|---|---|---|
| `draw` | function | no |
| `flash` | boolean | no |
| `frames` | integer >= 1 | yes |
| `sound` | string | no |

```lua
mod.content.transitions:register("dissolve", { frames = 30, draw = 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.

## type_chart

- semantics: `record`
- target: `Data.type_chart`
- value: {multiplier} | {category, index?, name?}

```lua
mod.content.type_chart:register("BUG>PSYCHIC_TYPE", { multiplier = 20 })
```

## v1 aliases

| alias | canonical |
|---|---|
| `scripts` | `map_scripts` |
| `ui` | `screens` |
