-
Notifications
You must be signed in to change notification settings - Fork 2
Tutorial 02 Balance Patch
Goal. Rebalance a move, a species' stats, and a boss party in one mod, gated behind a mod option the manager renders automatically.
Prerequisites. Tutorial 01; Concepts: Registries (the three merge semantics).
Files created.
mods/tutorial_02_balance/
├── manifest.json
└── main.lua
-
Scaffold as in tutorial 01, then patch a move in
main.lua:return function(mod) mod.content.moves:patch("TACKLE", { power = 50, accuracy = 100 }) end
patchdeep-merges a partial record — every field you do not name keeps its vanilla value. Outcome: Tackle hits noticeably harder in the first rival fight. -
Patch a stat sub-table.
mod.content.pokemon:patch("PIDGEY", { baseStats = { speed = 71 } })
The
baseStatssub-table merges — hp, attack, defense, and special stay vanilla. This is whypatchexists: the old copy-every-field idiom silently dropped whatever you forgot. Outcome: wild Pidgey outspeed your starter. -
Rewrite a boss party.
mod.content.trainers:patch("OPP_BROCK", { parties = { { { species = "ONIX", level = 14 }, { species = "GEODUDE", level = 12 } } }, })
partiesis a list of parties, each a list of{ species, level }slots. Arrays replace wholesale in a record registry — element-wise merging of a party is ambiguous — so state the whole party. Outcome: Brock leads Onix. -
Gate it behind an option.
return function(mod) mod.options:define({ { key = "hard_mode", type = "toggle", label = "HARD MODE", default = true }, }) if mod.options:get("hard_mode") then mod.content.moves:patch("TACKLE", { power = 50, accuracy = 100 }) mod.content.pokemon:patch("PIDGEY", { baseStats = { speed = 71 } }) mod.content.trainers:patch("OPP_BROCK", { parties = { { { species = "ONIX", level = 14 }, { species = "GEODUDE", level = 12 } } }, }) end end
Outcome: the mod's entry in the manager grows a HARD MODE toggle. Content is merged at boot, so toggling it takes effect on the next launch.
With the option on, Tackle deals more damage than vanilla; with it off
(or the mod disabled), damage is vanilla to the point. modkit validate tutorial_02_balance stays green.
-
Expecting an array field to deep-merge. Lists replace; to extend
instead, wrap:
{ learnset = { __append = { { level = 20, move = "FLY" } } } }(Concepts: Registries). -
Typos in stat names.
baseStats = { spd = 71 }is rejected underapi = 2— nested records are strict, and near-miss keys get adid you meansuggestion. -
Two mods patching the same record. Patches stack in load order
(
priorityascending, ties by id). If your rebalance must land after another mod's, raise your manifestpriorityor declare a dependency.
Next: Tutorial 03 — New Species.
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