docs: Write docs outlining the JSON schema for other commonly-edited files

This commit is contained in:
Rachel
2026-05-23 23:52:59 -07:00
parent 4804af4ca1
commit eb2dcc9cd8
5 changed files with 825 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
# In-Game Trade Data File Format
This document describes the file format for in-game trade data consumed by the
`npctradeproc` build tool. Each NPC trade in the ROM is represented by a JSON
file `res/npc_trades/<name>.json`, which contains metadata for the in-game trade
event and the received Pokémon. The fields from each of these files are mapped
onto the `NPCTradeMon` struct from `include/overlay006/npc_trade.h`.
## Schema
| Field | Type | Description |
| -------------------- | ------------------------- | --------------------------------------------------------------- |
| `name` | `string` | The Pokémon's nickname after the trade. |
| `otName` | `string` | The Original Trainer's name (max 7 characters). |
| `species` | `enum Species` | The species of the Pokémon being offered. |
| `hpIV` | `u8` (031) | HP Individual Value (stored in 5 bits). |
| `atkIV` | `u8` (031) | Attack Individual Value (stored in 5 bits). |
| `defIV` | `u8` (031) | Defense Individual Value (stored in 5 bits). |
| `speedIV` | `u8` (031) | Speed Individual Value (stored in 5 bits). |
| `spAtkIV` | `u8` (031) | Special Attack Individual Value (stored in 5 bits). |
| `spDefIV` | `u8` (031) | Special Defense Individual Value (stored in 5 bits). |
| `unused1` | `u32` | Unused field. Present in the retail ROM. |
| `otID` | `u32` | The Original Trainer's ID number. |
| `cool` | `u32` | Cool contest condition value. |
| `beauty` | `u32` | Beauty contest condition value. |
| `cute` | `u32` | Cute contest condition value. |
| `smart` | `u32` | Smart contest condition value. |
| `tough` | `u32` | Tough contest condition value. |
| `personality` | `u32` | Personality value, which determines gender, ability, and nature.|
| `heldItem` | `enum Item` | The item held by the Pokémon. |
| `otGender` | `enum Gender` | The gender of the Original Trainer. |
| `unused2` | `u32` | Unused field. Present in the retail ROM. |
| `language` | `enum Language` | The language of the Original Trainer. |
| `requestedSpecies` | `enum Species` | The species required in exchange for the trade. |
## Example
```json
{
"name": "Kazza",
"otName": "Hilary",
"species": "SPECIES_ABRA",
"hpIV": 15,
"atkIV": 15,
"defIV": 15,
"speedIV": 20,
"spAtkIV": 25,
"spDefIV": 25,
"unused1": 28,
"otID": 25643,
"cool": 0,
"beauty": 0,
"cute": 0,
"smart": 0,
"tough": 0,
"personality": 142,
"heldItem": "ITEM_ORAN_BERRY",
"otGender": "GENDER_FEMALE",
"unused2": 0,
"language": "LANGUAGE_ENGLISH",
"requestedSpecies": "SPECIES_MACHOP"
}
```

166
docs/datafiles/items.md Normal file
View File

@@ -0,0 +1,166 @@
# Item Data File Format
This document describes the file format for item data consumed by the `itemproc`
build tool. Each item in the ROM is represented by a JSON file
`res/items/data/<name>.json`. Fields from each of these files are mapped onto
the `ItemData` struct from `include/item.h` and the `BerryData` struct from
`include/berry_data.h`.
Bogus items in the retail ROM—those with the `ITEM_UNUSED_` prefix—do not have
corresponding JSON files. They are assigned placeholder text in the output, but
they do not produce a data entry.
## Schema
| Field | Type | Description |
| -------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------- |
| `name` | `string` | The item's display name (singular). |
| `plural` | `string` | The item's display name (plural). |
| `article` | `string` | Indefinite article (e.g. "a", "an") for in-game text. |
| `description` | `string[]` | The item's description, as an array of lines. |
| `icon` | `object` | References to the item's icon graphics. See below. |
| `gbaID` | `string` | The corresponding Gen-III item identifier, or `GBA_ITEM_NONE` for Gen-IV items. |
| `price` | `u16` | Base price in Pokédollars paid when purchasing from a shop. `0` means the item cannot be sold. |
| `effectParam` | `u8` | Generic parameter; semantics vary by item type (e.g., heal amount). |
| `holdEffect` | `enum ItemHoldEffect` | Effect when held by a Pokémon. |
| `pluckEffect` | `define PLUCK_EFFECT` | Effect when consumed by Bug Bite / Pluck. |
| `flingEffect` | `define FLING_EFFECT` | Effect when used with Fling. |
| `flingPower` | `u8` | Base power of Fling when this item is flung. |
| `naturalGiftPower` | `u8` | Base power of Natural Gift when this item is held. 0 if not a berry. |
| `naturalGiftType` | `enum PokemonType` or `null` | Type of Natural Gift when this item is held. `null` if not a berry. |
| `preventToss` | `bool` | If `true`, then the item cannot be tossed or sold. |
| `canRegister` | `bool` | If `true`, then the item can be registered to the `Y` button. |
| `fieldPocket` | `define POCKET` | The Bag pocket the item belongs to (Items, Medicine, etc.). |
| `battlePocket` | `define BATTLE_POCKET_MASK` | The battle pocket mask for use during battle. |
| `fieldUseFunc` | `define ITEM_USE_FUNC` | The field-use function invoked from the overworld. |
| `battleUseFunc` | `u8` | The battle-use function invoked from the battle menu. |
| `itemUseParams` | `object` or `null` | Detailed usage parameters. See below. |
| `teachesMove` | `enum Move` | The move taught by this TM or HM (only for TMs/HMs). |
| `berryData` | `object` | Berry growth and flavor data (only for berries). See below. |
### The `icon` Object
| Field | Type | Description |
| --------- | -------- | ---------------------------------------------------- |
| `sprite` | `string` | Name of the NCGR sprite resource for the item icon. |
| `palette` | `string` | Name of the NCLR palette resource for the item icon. |
These fields map to the in-game files produced from the inputs in
`res/items/icons`.
### The `itemUseParams` Object
This object defines the parameters for items that act on a Pokémon in the party
or in battle. All fields are optional and default to `0` or `false`.
| Field | Type | Description |
| ------------------- | ------- | ---------------------------------------------------------------- |
| `healSleep` | `bool` | Cures sleep. |
| `healPoison` | `bool` | Cures poison. |
| `healBurn` | `bool` | Cures burn. |
| `healFreeze` | `bool` | Cures freeze. |
| `healParalysis` | `bool` | Cures paralysis. |
| `healConfusion` | `bool` | Cures confusion. |
| `healAttract` | `bool` | Cures infatuation. |
| `guardSpec` | `bool` | Temporarily protects from stat reduction. |
| `revive` | `bool` | Revives a fainted Pokémon. |
| `reviveAll` | `bool` | Revives all fainted Pokémon. |
| `levelUp` | `bool` | Increases the Pokémon's level by one. |
| `ppUp` | `bool` | Increases a move's PP. |
| `ppMax` | `bool` | Maximizes a move's PP. |
| `restorePPAllMoves` | `bool` | Restores PP to all moves. |
| `atkStages` | `u8` | Attack stage change (04). |
| `defStages` | `u8` | Defense stage change (04). |
| `spatkStages` | `u8` | Special Attack stage change (04). |
| `spdefStages` | `u8` | Special Defense stage change (04). |
| `speedStages` | `u8` | Speed stage change (04). |
| `accStages` | `u8` | Accuracy stage change (04). |
| `critStages` | `u8` | Critical-hit ratio stage change (02). |
| `hpRestored` | `s8` | HP restored. Use `-1` for 100%, `-2` for 50%, or `-3` for 25%. |
| `ppRestored` | `s8` | PP restored. Use `-1` for 100%. |
| `hpEVs` | `s8` | HP EVs gained. |
| `atkEVs` | `s8` | Attack EVs gained. |
| `defEVs` | `s8` | Defense EVs gained. |
| `speedEVs` | `s8` | Speed EVs gained. |
| `spatkEVs` | `s8` | Special Attack EVs gained. |
| `spdefEVs` | `s8` | Special Defense EVs gained. |
| `friendshipLow` | `s8` | Friendship change when friendship < 100. |
| `friendshipMed` | `s8` | Friendship change when 100 friendship < 200. |
| `friendshipHigh` | `s8` | Friendship change when friendship 200. |
When `fieldUseFunc` is set to `ITEM_USE_FUNC_BERRY`, `ITEM_USE_FUNC_EVO_STONE`,
`ITEM_USE_FUNC_HEALING`, or any other use function that acts on a party Pokémon,
this object is optional but will be used if present.
### The `berryData` Object
| Field | Type | Description |
| ------------------- | ---------------------- | ------------------------------------------------------ |
| `size` | `u16` | Size of the berry in millimeters. |
| `firmness` | `define FIRMNESS` | Firmness category (Very Soft through Super Hard). |
| `baseYield` | `u8` | Base yield per plant. |
| `stageDuration` | `u8` | Number of stages to grow. |
| `moistureDrainRate` | `u8` | How quickly moisture drains. |
| `spiciness` | `u8` | Spicy flavor value. |
| `dryness` | `u8` | Dry flavor value. |
| `sweetness` | `u8` | Sweet flavor value. |
| `bitterness` | `u8` | Bitter flavor value. |
| `sourness` | `u8` | Sour flavor value. |
| `smoothness` | `u8` | Smoothness for Poffin cooking. |
This field is only recognized when `fieldUseFunc` is `ITEM_USE_FUNC_BERRY`.
## Outputs
The tool produces the following outputs:
| Output | Description |
| ------------------------------- | -------------------------------------------------------------------- |
| `pl_item_data.narc` | `ItemData` entries for every item, packed by index ID. |
| `item_id_map.h` | Maps item IDs to data index, icon resource, palette, and Gen-III ID. |
| `item_tm_move_map.h` | Maps TM indices to the move they teach. |
| `item_berry_list.h` | Lists all berry items by their berry index. |
| `item_mail_list.h` | Lists all mail items by their mail type index. |
| `item_names.json` | Text bank for singular item names. |
| `item_names_plural.json` | Text bank for plural item names. |
| `item_names_with_articles.json` | Text bank for item names with their indefinite article. |
| `item_descriptions.json` | Text bank for item descriptions. |
| `hidden_item_scripts.h` | Generated header mapping hidden item script IDs to script entries. |
| `nuts_data.narc` | `BerryData` entries for each in-game berry. |
## Example
```json
{
"name": "Potion",
"plural": "Potions",
"article": "a",
"description": [
"A spray-type medicine for wounds.\n",
"It restores the HP of one Pokémon by\n",
"just 20 points."
],
"icon": {
"sprite": "potion_NCGR",
"palette": "potion_NCLR"
},
"gbaID": "GBA_ITEM_POTION",
"price": 300,
"effectParam": 20,
"holdEffect": "HOLD_EFFECT_NONE",
"pluckEffect": "PLUCK_EFFECT_NONE",
"flingEffect": "FLING_EFFECT_NONE",
"flingPower": 30,
"naturalGiftPower": 0,
"naturalGiftType": null,
"preventToss": false,
"canRegister": false,
"fieldPocket": "POCKET_MEDICINE",
"battlePocket": "BATTLE_POCKET_MASK_RECOVER_HP",
"fieldUseFunc": "ITEM_USE_FUNC_HEALING",
"battleUseFunc": 2,
"itemUseParams": {
"hpRestored": 20
}
}
```

361
docs/datafiles/pokemon.md Normal file
View File

@@ -0,0 +1,361 @@
# Pokémon Data File Format
This document describes the file format for Pokémon species data consumed by the
`speciesproc` build tool. Each species in the ROM is represented by a directory
`res/pokemon/<species>` which must contain the following files:
| File | Purpose |
| ------------------ | -------------------------------------------------------------- |
| `data.json` | Internal metadata (stats, types, learnsets, evolutions, etc.) |
| `sprite_data.json` | Sprite offset, shadow, and animation data (National Dex only) |
Some alternate forms have their own input data due to differing base stats,
types, or abilities. In the retail ROM, this includes forms for:
1. Deoxys
2. Wormadam
3. Shaymin
4. Giratina
5. Rotom
Each such form has a corresponding subdirectory under their species parent, e.g.
`giratina/forms/origin`. These forms have a similar `data.json` file, but they
do not have a `sprite_data.json` file.
## `data.json` — Internal Metadata
The JSON fields from this file map onto the `SpeciesData`, `SpeciesEvolution`,
`SpeciesLearnset`, and `SpeciesPalPark` structs from
`include/struct_defs/species.h`.
### Schema
| Field | Type | Description |
| ------------------- | -------------------- | ----------------------------------------------------------------------------------------------- |
| `base_stats` | `object` | Base stat values (HP, Attack, Defense, Speed, Sp. Atk, Sp. Def). |
| `types` | `enum PokemonType[]` | The species' primary and secondary types (2 elements). |
| `catch_rate` | `u8` | Catch rate (0255). |
| `base_exp_reward` | `u8` | Base experience yield on defeat. |
| `ev_yields` | `object` | EV yield values (2-bit each) for each stat. |
| `held_items.common` | `enum Item` | The common wild held item (20%). |
| `held_items.rare` | `enum Item` | The rare wild held item (5%). |
| `gender_ratio` | `enum GenderRatio` | Gender ratio of the species. |
| `hatch_cycles` | `u8` | Number of hatch cycles (255 x cycle length). |
| `base_friendship` | `u8` | Base friendship level. |
| `exp_rate` | `enum ExpRate` | Level-up experience curve. |
| `egg_groups` | `enum EggGroup[]` | Egg groups for breeding (2 elements). |
| `abilities` | `enum Ability[]` | Slot 1 and slot 2 abilities (2 elements). |
| `safari_flee_rate` | `u8` | Safari Zone flee rate. |
| `body_color` | `enum PokemonColor` | Pokédex body color. |
| `flip_sprite` | `bool` | Whether the in-battle sprite should be flipped horizontally in menus (like the summary screen). |
| `icon_palette` | `u8` or `array` | Icon palette index; array of `[form_name, index]` tuples for species with per-form palettes. |
| `learnset` | `object` | Learnset data (level-up, TM/HM, tutor, egg moves). See below. |
| `evolutions` | `array` | Evolution methods and targets. |
| `offspring` | `enum Species` | The species produced when breeding (usually self). |
| `footprint` | `object` | Footprint data for the Pokédex. |
| `pokedex_data` | `object` | Pokédex entry text, height, weight, body shape, and sprite scales/positions. |
| `catching_show` | `object` | Pal Park encounter data. |
#### The `learnset` Object
| Field | Type | Description |
| ---------- | ------------- | ------------------------------------------------------------------------- |
| `by_level` | `array` | Level-up learnset: array of `[level, move]` tuples. |
| `by_tm` | `string[]` | TM/HM compatibility: array of TM or HM markers (e.g. `"TM01"`, `"HM04"`). |
| `by_tutor` | `enum Move[]` | Moves teachable by move tutors. |
| `egg_moves`| `enum Move[]` | Moves available as egg moves (optional). |
If a move listed in the `by_tutor` array is not teachable by any move tutor in
the game, then a warning will be emitted, and that move will be skipped.
No validation is performed against `egg_moves` due to the potential cost of
analyzing every other member of each egg group.
#### The `evolutions` Array
Each element is a tuple describing one evolution path:
| Index | Type | Description |
| ----- | ---------------------- | ---------------------------------------------------------------------- |
| 0 | `enum EvolutionMethod` | The evolution method (level, trade, item, etc.) |
| 1 | varies | The parameter for the method (level, item, move, species, or nothing). |
| 2 | `enum Species` | The target species to evolve into. |
The parameter type depends on the method:
- For `EVO_LEVEL`, `EVO_LEVEL_ATK_GT_DEF`, etc., it is the level at which the
evolution should trigger.
- For `EVO_USE_ITEM`, `EVO_TRADE_WITH_HELD_ITEM`, etc., it is the `enum Item`
required to be held or used to trigger the evolution.
- For `EVO_LEVEL_KNOW_MOVE`, it is an `enum Move` which must be known for the
next level-up to trigger the evolution.
- For `EVO_LEVEL_SPECIES_IN_PARTY`, it is an `enum Species` which must be
present in the party for the next level-up to trigger the evolution.
- For `EVO_NONE`, `EVO_LEVEL_HAPPINESS`, `EVO_TRADE`, there is no listed
parameter, and the evolution only has two elements: `[method, species]`.
#### The `footprint` Object
| Field | Type | Description |
| ------ | ----------------------- | --------------------------------------------------- |
| `has` | `bool` | Whether the species has a footprint in the Pokédex. |
| `size` | `enum FootprintSize` | The relative size of the footprint. |
| `type` | `define FOOTPRINT_TYPE` | The footprint type (e.g. Cute, Scary, etc.). |
#### The `pokedex_data` Object
Height and weight may be specified in either metric or imperial units, but not
both.
| Field | Type | Description |
| ------------------ | ----------------------- | -------------------------------------------------------- |
| `height_meters` | `float` | Height in meters (alternative to `height_inches`). |
| `height_inches` | `u32` | Height in inches (alternative to `height_meters`). |
| `weight_kilograms` | `float` | Weight in kilograms (alternative to `weight_pounds`). |
| `weight_pounds` | `float` | Weight in pounds (alternative to `weight_kilograms`). |
| `body_shape` | `enum PokemonBodyShape` | Pokédex body shape category. |
| `trainer_scale_f` | `u16` | Trainer back-sprite scale (female). |
| `pokemon_scale_f` | `u16` | Pokémon front-sprite scale (female). |
| `trainer_scale_m` | `u16` | Trainer back-sprite scale (male). |
| `pokemon_scale_m` | `u16` | Pokémon front-sprite scale (male). |
| `trainer_pos_f` | `u16` | Trainer back-sprite Y-position offset (female). |
| `pokemon_pos_f` | `u16` | Pokémon front-sprite Y-position offset (female). |
| `trainer_pos_m` | `u16` | Trainer back-sprite Y-position offset (male). |
| `pokemon_pos_m` | `u16` | Pokémon front-sprite Y-position offset (male). |
| `origin_forme` | `object` | Alternate-forme Pokédex data (Giratina only). See below. |
| `en`, `fr`, `etc.` | `object` | Localized Pokédex data. See below. |
The `origin_forme` sub-object uses the same schema as the top-level
`pokedex_data` (height, weight, body shape, scales, and positions) and is only
present for Giratina to support its Origin Forme.
Each language sub-object has the following fields:
| Field | Type | Description |
| ------------ | ---------- | --------------------------------------------- |
| `name` | `string` | The species name in that language. |
| `category` | `string` | The species category (e.g. "Lizard Pokémon"). |
| `entry_text` | `string[]` | The Pokédex entry text, as an array of lines. |
#### The `catching_show` Object
| Field | Type | Description |
| --------------------- | ----------------------- | ---------------------------------------- |
| `pal_park_land_area` | `enum PalParkLandArea` | Pal Park land area assignment. |
| `pal_park_water_area` | `enum PalParkWaterArea` | Pal Park water area assignment. |
| `catching_points` | `u8` | Catching show points awarded. |
| `rarity` | `u8` | Rarity score for the catching show. |
| `unused` | `u16` | Unused field. Present in the retail ROM. |
## `sprite_data.json` — Sprite Offsets and Animation Data
This file is only processed for species present in the National Pokédex (that
is, those with an ID less than `SPECIES_EGG`) and defines the battle sprite
layout and some animation parameters.
| Field | Type | Description |
| -------- | -------- | ---------------------------------------------- |
| `front` | `object` | Front-face sprite animation and Y-offset data. |
| `back` | `object` | Back-face sprite animation and Y-offset data. |
| `shadow` | `object` | Shadow sprite position and size. |
### The `front` and `back` Objects
| Field | Type | Description |
| --------------- | ---------- | -------------------------------------------------------- |
| `y_offset` | `object` | Per-gender Y-offsets for the sprite (`male` / `female`). |
| `addl_y_offset` | `s8` | Additional Y-offset (front only). |
| `animation` | `u8` | Pre-programmed animation sequence ID. |
| `cry_delay` | `u8` | Frames to wait before playing the cry. |
| `start_delay` | `u8` | Frames to wait before starting the animation. |
| `frames` | `object[]` | Array of animation frame definitions (up to 10 frames). |
#### The `frame` Objects
| Field | Type | Description |
| -------------- | ---- | ------------------------------------- |
| `sprite_frame` | `s8` | Sprite frame index (`-1` = no frame). |
| `frame_delay` | `u8` | Duration of this frame in ticks. |
| `x_shift` | `s8` | Horizontal shift for this frame. |
| `y_shift` | `s8` | Vertical shift for this frame. |
### The `shadow` Object
| Field | Type | Description |
| ---------- | ----------------- | --------------------------------------- |
| `x_offset` | `s8` | Horizontal offset of the shadow sprite. |
| `size` | `enum ShadowSize` | Size category of the shadow sprite. |
### Outputs
The tool produces the following outputs:
| Output | Description |
| ---------------------------------------- | ----------------------------------------------------------------- |
| `pl_personal.narc` | `SpeciesData` entries for every species and alternate form. |
| `evo.narc` | `SpeciesEvolution` entries. |
| `wotbl.narc` | Level-up learnset entries for every species. |
| `height.narc` | Per-gender sprite Y-offsets (4 files per National Dex species). |
| `pl_poke_data.narc` | `SpeciesSpriteData` for all National Dex species. |
| `ppark.narc` | `SpeciesPalPark` data for all National Dex species. |
| `pms.narc` | Offspring species map (breeding species resolution). |
| `zukan_data(_gira).narc` | Data for the sorted Pokédex indices (by height, by weight, etc.). |
| `tutorable_moves.h` | Move tutor definitions and costs. |
| `species_learnsets_by_tutor.h` | Bitmask of tutorable moves per species. |
| `species_egg_moves.h` | Egg move lists per species. |
| `species_footprint_sizes.h` | Footprint size per species. |
| `species_footprint_types.h` | Footprint type per species. |
| `species_icon_palettes.h` | Icon palette index per species. |
| `species_name.json` | Text bank for species names. |
| `species_name_with_articles.json` | Text bank for species names with indefinite articles. |
| `species_pokedex_entry_*.json` | Text banks for Pokédex entries in 6 languages. |
| `species_name_with_natdex_number_*.json` | Text banks for species names with National Dex numbers. |
| `species_category*.json` | Text banks for species categories. |
| `species_weight*.json` | Text banks for Pokédex weight display. |
| `species_height*.json` | Text banks for Pokédex height display. |
### Example
```json
{
"base_stats": {
"hp": 39,
"attack": 52,
"defense": 43,
"speed": 65,
"special_attack": 60,
"special_defense": 50
},
"types": [ "TYPE_FIRE", "TYPE_FIRE" ],
"catch_rate": 45,
"base_exp_reward": 65,
"ev_yields": {
"hp": 0,
"attack": 0,
"defense": 0,
"speed": 1,
"special_attack": 0,
"special_defense": 0
},
"held_items": {
"common": "ITEM_NONE",
"rare": "ITEM_NONE"
},
"gender_ratio": "GENDER_RATIO_FEMALE_12_5",
"hatch_cycles": 20,
"base_friendship": 70,
"exp_rate": "EXP_RATE_MEDIUM_SLOW",
"egg_groups": [ "EGG_GROUP_MONSTER", "EGG_GROUP_DRAGON" ],
"abilities": [ "ABILITY_BLAZE", "ABILITY_NONE" ],
"safari_flee_rate": 0,
"body_color": "MON_COLOR_RED",
"flip_sprite": false,
"icon_palette": 0,
"learnset": {
"by_level": [
[ 1, "MOVE_SCRATCH" ],
[ 1, "MOVE_GROWL" ],
[ 7, "MOVE_EMBER" ],
[ 10, "MOVE_SMOKE_SCREEN" ],
[ 16, "MOVE_DRAGON_RAGE" ]
],
"by_tm": [
"TM01", "TM02", "TM06", "TM10",
"HM01", "HM04", "HM06"
],
"by_tutor": [
"MOVE_MUD_SLAP",
"MOVE_FIRE_PUNCH",
"MOVE_SNORE"
],
"egg_moves": [
"MOVE_BELLY_DRUM",
"MOVE_OUTRAGE",
"MOVE_DRAGON_DANCE"
]
},
"evolutions": [
[ "EVO_LEVEL", 16, "SPECIES_CHARMELEON" ]
],
"offspring": "SPECIES_CHARMANDER",
"footprint": {
"has": true,
"size": "FOOTPRINT_MEDIUM",
"type": "FOOTPRINT_TYPE_CUTE"
},
"pokedex_data": {
"height_inches": 24,
"weight_pounds": 18.7,
"body_shape": "SHAPE_BIPEDAL_TAILED",
"trainer_scale_f": 272,
"pokemon_scale_f": 384,
"trainer_scale_m": 256,
"pokemon_scale_m": 384,
"trainer_pos_f": 8,
"pokemon_pos_f": 23,
"trainer_pos_m": 9,
"pokemon_pos_m": 23,
"en": {
"name": "CHARMANDER",
"category": "Lizard Pokémon",
"entry_text": [
"The fire on the tip of its tail is a\n",
"measure of its life. If healthy,\n",
"its tail burns intensely."
]
},
"fr": {
"name": "SALAMECHE",
"category": "Pokémon Lézard",
"entry_text": [
"La flamme de sa queue symbolise sa\n",
"vitalité. Elle est intense quand il\n",
"est en bonne santé."
]
},
"de": {
"name": "GLUMANDA",
"category": "Echse",
"entry_text": [
"Lodert die Flamme auf seiner\n",
"Schweifspitze hell, ist GLUMANDA\n",
"gesund."
]
},
"it": {
"name": "CHARMANDER",
"category": "Pokémon Lucertola",
"entry_text": [
"La fiamma sulla punta della coda\n",
"indica la sua vitalità. Se sta bene,\n",
"la fiamma è più ardente."
]
},
"es": {
"name": "CHARMANDER",
"category": "Pokémon Lagartija",
"entry_text": [
"La llama de la punta de su cola\n",
"indica su salud. Si CHARMANDER\n",
"está sano, arderá con más fuerza."
]
},
"jp": {
"name": "ヒトカゲ",
"category": "とかげポケモン",
"entry_text": [
"ヒトカゲの しっぽの ほのおは\n",
"いのちの ともしび。げんきな ときは\n",
"ほのおも ちからづよく もえあがる。"
]
}
},
"catching_show": {
"pal_park_land_area": "PAL_PARK_AREA_LAND_SOUTH_WEST",
"pal_park_water_area": "PAL_PARK_AREA_WATER_NONE",
"catching_points": 50,
"rarity": 30,
"unused": 514
}
}
```

231
docs/datafiles/trainers.md Normal file
View File

@@ -0,0 +1,231 @@
# Trainer Data File Format
This document describes the file format for trainer data consumed by the
`trainerproc` build tool. Each trainer in the ROM is represented by a JSON file
`res/trainers/data/<name>.json`, which contains metadata for the trainer and
their party. The fields from each of these files are mapped onto the structs
defined in `include/struct_defs/trainer_data.h`.
## Top-Level Schema
| Field | Type | Description |
| --------------- | ----------------------------- | ---------------------------------------------------------------- |
| `name` | `string` | The trainer's display name. |
| `class` | `enum TrainerClass` | The trainer class, e.g. Youngster, Ace Trainer, Gym Leader. |
| `items` | `enum Item[]` | Items usable by the trainer in battle (up to 4). May be empty. |
| `ai_flags` | `enum AIFlag[]` | AI behavior flags for battle scripts. May be empty. |
| `double_battle` | `bool` | Whether this is a double battle. |
| `party` | `object[]` | The trainer's party of Pokémon. See below for the member schema. |
| `messages` | `object[]` | Dialogue messages. See the Messages section below. |
## Party Member Schema
Each element of the `party` array represents a Pokémon owned by the trainer.
| Field | Type | Description |
| ------------ | ----------------------- | ----------------------------------------------------------------- |
| `species` | `enum Species` | The species of the Pokémon. |
| `form` | `u8` | Form index, packed into the high bits of the species field. |
| `level` | `u16` | The level of the Pokémon. |
| `item` | `enum Item` or `null` | The held item, or `null` for none. |
| `moves` | `enum Move[]` or `null` | Known moves (up to 4), or `null` for default level-up moves. |
| `iv_scale` | `u16` | IV scaling factor (0255). |
| `ball_seal` | `u16` | Ball seal / capsule decoration index. |
The presence of the `item` and `moves` fields determines the exact structure of
the output data, which affects the trainer's party in-game. If any Pokémon in
the party specifies that it can have a held item or a custom move-set, then all
other Pokémon in the party must *also* specify as much.
To illustrate, this party is valid:
```json
{
"party": [
{
"species": "SPECIES_STARLY",
"form": 0,
"level": 7,
"item": null,
"moves": [
"MOVE_QUICK_ATTACK",
"MOVE_GROWL"
],
"iv_scale": 30,
"ball_seal": 0
},
{
"species": "SPECIES_CHIMCHAR",
"form": 0,
"level": 9,
"item": null,
"moves": [
"MOVE_SCRATCH",
"MOVE_LEER"
],
"iv_scale": 30,
"ball_seal": 0
}
]
}
```
However, this party is *not* valid, as Chimchar specifies that it has data for
its held-item, while Starly does not:
```json
{
"party": [
{
"species": "SPECIES_STARLY",
"form": 0,
"level": 7,
"item": null,
"moves": [
"MOVE_QUICK_ATTACK",
"MOVE_GROWL"
],
"iv_scale": 30,
"ball_seal": 0
},
{
"species": "SPECIES_CHIMCHAR",
"form": 0,
"level": 9,
"item": "ITEM_ORAN_BERRY",
"moves": [
"MOVE_SCRATCH",
"MOVE_LEER"
],
"iv_scale": 30,
"ball_seal": 0
}
],
}
```
Similarly, this party would also be invalid, as Starly declares that it should
derive its move-set from the moves that it learns by level-up, while Chimchar
declares that it has a custom move-set:
```json
{
"party": [
{
"species": "SPECIES_STARLY",
"form": 0,
"level": 7,
"item": null,
"moves": null,
"iv_scale": 30,
"ball_seal": 0
},
{
"species": "SPECIES_CHIMCHAR",
"form": 0,
"level": 9,
"item": null,
"moves": [
"MOVE_SCRATCH",
"MOVE_LEER"
],
"iv_scale": 30,
"ball_seal": 0
}
],
}
```
## Messages
The `messages` array defines dialogue that the trainer may speak at various
points during a battle. Each entry has a `type` field drawn from
`enum TrainerMessageType` (e.g. `TRMSG_PRE_BATTLE`, `TRMSG_DEFEAT`,
`TRMSG_POST_BATTLE`, `TRMSG_REMATCH`) and an `en_US` field containing the
message text. As with the text-files stored in `res/text`, the content may be
a single string or an array of strings as a convenience for multi-line messages.
Entries with the `garbage` key in place of `en_US` represent padding present in
the retail ROM.
## Outputs
The tool produces the following outputs:
| Output | Description |
| --------------------------- | -------------------------------------------------------------- |
| `trdata.narc` | `TrainerHeader` entries for every trainer, packed by index ID. |
| `trpoke.narc` | Party data for every trainer, packed by index ID. |
| `trainer_scripts.h` | Generated header mapping trainer IDs to `ScriptEntry` macros. |
| `npc_trainer_names.json` | Text bank for trainer display names. |
| `npc_trainer_messages.json` | Text bank for in-battle trainer dialogue. |
| `trtbl.narc` | Message lookup table mapping `(trainerID, messageType)` pairs. |
| `trtblofs.narc` | Offset table into `trtbl.narc` for each trainer index. |
## Example
```json
{
"name": "Catherine",
"class": "TRAINER_CLASS_ACE_TRAINER_FEMALE",
"items": [],
"ai_flags": [
"AI_FLAG_BASIC",
"AI_FLAG_EVAL_ATTACK",
"AI_FLAG_EXPERT"
],
"double_battle": false,
"party": [
{
"species": "SPECIES_HAUNTER",
"form": 0,
"level": 23,
"item": null,
"moves": [
"MOVE_NIGHT_SHADE",
"MOVE_CONFUSE_RAY",
"MOVE_SUCKER_PUNCH",
"MOVE_CURSE"
],
"iv_scale": 60,
"ball_seal": 0
},
{
"species": "SPECIES_MISDREAVUS",
"form": 0,
"level": 24,
"item": null,
"moves": [
"MOVE_PSYBEAM",
"MOVE_PAIN_SPLIT",
"MOVE_CONFUSE_RAY",
"MOVE_SPITE"
],
"iv_scale": 60,
"ball_seal": 0
}
],
"messages": [
{
"type": "TRMSG_PRE_BATTLE",
"en_US": [
"What does it feel like, taking one step\n",
"after another into darkness?\r"
]
},
{
"type": "TRMSG_DEFEAT",
"en_US": [
"Youre the kind of person who can keep\n",
"going forward even into the unknown.\n"
]
},
{
"type": "TRMSG_POST_BATTLE",
"en_US": [
"I think, sometimes, one has to make\n",
"mistakes to learn what is right.\n"
]
}
]
}
```

View File

@@ -15,6 +15,10 @@ For more detailed information about the project as a whole, please refer to its
## Working with Files for Various Data Types
- [Overview of the Processing Tools](datafiles/overview.md)
- [Pokémon Species](datafiles/pokemon.md)
- [In-Game Trainers](datafiles/trainers.md)
- [In-Game Trades](datafiles/trainers.md)
- [Items](datafiles/items.md)
- [Moves](datafiles/moves.md)
## Subsystems