Cookbook: items and balls
An item record identifies what is in the bag. A shop entry makes it purchasable; an effect or ball record supplies behavior.
Setup: a working mod from Getting Started. Examples target Red/local single-player unless a recipe explicitly says otherwise. Use Modding Basics for syntax and Glossary for unfamiliar terms. Save and restart after content edits. A validation pass and an in-game checkpoint are different checks.
Where code goes: insert Lua fragments inside your existing
return function(mod) ... end in main.lua. A complete-file label or named
other file overrides that default. Do not paste a second entry function
inside the first. Read the recipe's requirements before copying its code.
For output, use Read log output; for IDs,
use Find internal IDs.
Mechanism: Concepts: Registries; worked path: Tutorial 04.
R08 - Add a Mart item
Basic Lua. Before you paste: Use a Red save with money and access to Viridian Mart. This recipe both defines an item and puts it in a shop. R09 adds its use behavior.
Complete walkthrough / required concept.
Insert in main.lua inside the entry function (unless a filename is shown).
mod.content.items:register("MODBERRY", {
id = "MODBERRY", name = "MODBERRY", price = 250, tossable = true,
})
mod.content.text_pointers:patch("ViridianMart", {
TEXT_VIRIDIANMART_CLERK = { mart = { __append = { "MODBERRY" } } },
})
Checkpoint: the Viridian clerk sells MODBERRY. Each shop clerk has a mart list of items to sell.
__append keeps the existing shelf and adds your item. This is a deep
registry, so a plain list also appends; do not use it expecting to erase
the existing inventory.
Gen 2 / Gen 3: items:register works on both (an api 3 mod uses this
same record and Gen 3 allocates a free item slot). text_pointers has no
Gen 2 or Gen 3 target, so the shop half is dropped and reported there.
R09 - Define an item use effect
A complete R08 + R09 mod is stored in examples/cookbook/berry/: download
its manifest
and main.lua,
or follow the two recipe insertions below/above in your own mod.
Basic Lua. Before you paste: First install R08 in the same mod so MODBERRY exists and can be purchased. This adds a field-use healing effect; use it on a living, injured party member.
Complete walkthrough / required concept.
Insert after R08 inside the same main.lua entry function.
mod.content.item_effects:register("MODBERRY_EFFECT", {
use = function(ctx)
local mon = ctx.target
local max = mon and (mon.maxHp or mon.stats.hp)
if not mon or mon.hp <= 0 or mon.hp >= max then
return "failed", { "It had no effect." }
end
mon.hp = math.min(max, mon.hp + 10)
return "consumed", { "Restored 10 HP!" }
end,
field = true, battle = false, needsTarget = true,
})
mod.content.items:patch("MODBERRY", { effect = "MODBERRY_EFFECT" })
Checkpoint: outside battle, use a purchased MODBERRY on a living party Pokemon missing HP. It restores up to 10 HP and uses one berry. At full HP or on a fainted Pokemon it reports no effect and keeps the berry.
ctx.target is the chosen Pokemon. mon.hp is current HP and mon.stats.hp
is its maximum on Red. math.min prevents healing above the maximum. The first
return value tells the bag whether to consume the item; the second is a
list of messages. battle = false deliberately keeps this first effect out
of the battle menu. See src/inventory/ItemEffects.lua for other results
such as "kept", "ball", and "learn".
Gen 3: this record runs through the native item flow
(src/core/game3/item_use.lua), honouring field, battle and
needsTarget. ctx.target is the native party record, whose maximum is
mon.maxHp; the mon.maxHp or mon.stats.hp read above covers both. Gen 3
accepts only "consumed", "kept" and "failed".
Gen 2: Gold's item_effects (gen2ItemEffects) are keyed by item id and
called as use(ctx) with ctx.mon, returning { used, text }
(src/core/gen2/ItemEffects.lua), so this record does not run there as is.
R10 - Add a new Poke Ball
Basic Lua. Before you paste: This defines the ball but does not put it in the bag or a shop. Use Tutorial04's complete shop example, adding MODBALL to its stocked items.
Complete walkthrough / required concept.
Insert in main.lua inside the entry function (unless a filename is shown).
mod.content.items:register("MODBALL", {
id = "MODBALL", name = "MODBALL", price = 500, ball = "MODBALL",
})
mod.content.balls:register("MODBALL", {
randMax = 120, hpFactor = 10, wobbleFactor = 120,
tossAnim = "ULTRATOSS_ANIM", flicker = true,
})
Checkpoint: thrown in battle, MODBALL catches better than an Ultra Ball
(randMax 150). The fields are the real Gen 1 math
(src/battle/Catching.lua); autoCatch = true is the Master Ball
behavior, and attempt = fn replaces the roll outright.
Gen 2 / Gen 3: Gold routes balls to its own table (gen2Balls). Gen 3
takes a different record, { multiplier, autoCatch }, where multiplier is
the ball bonus times 10 (Ultra Ball is 20), keyed by an item id that exists:
mod.content.balls:register("MODBALL", { multiplier = 25 })
An api 3 mod writes this native record too: mod:supports("content", "balls")
is true on Gen 3, and the record passes through as shown. Claim gen3 in
games (or branch on mod.generation) so the Gen 1 ball shape is not sent here.
Start here
Playing
Tutorials
- Choose a tutorial
- 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
Creative guides
Concepts
Recipes and reference
Author and developer tools
Home · Start Playing · Glossary · Troubleshooting · Repository · Community
Game data is imported locally from a supported ROM supplied by the player. Shared mods contain original work or transform recipes, never extracted game content. Check each guide's target game before using its examples.