-
Notifications
You must be signed in to change notification settings - Fork 2
Guide Audio Authoring
Songs, sound effects, and cries are data. Every def is shape-dispatched
per record (src/core/Music.lua, src/core/Sound.lua), so one
file-backed song, one authored chiptune, and the whole vanilla chip
soundtrack coexist in a single dataset — there is no global "audio mode"
to flip and no way for one def to brick the rest.
| Registry | Target | Keyed by |
|---|---|---|
music |
Data.audio.songs |
song id (Music_...) |
sfx |
Data.audio.sfx |
effect id (Save, Trade_Machine, ...) |
cries |
Data.audio.cries |
species id |
map_songs |
Data.audio.mapSongs |
map id → music id |
(The v1 audio registry still works for whole-key swaps of Data.audio
but is deprecated in favor of these.)
-- rom chip reference (what the importer writes)
{ address = 0x822E, bank = 0x02 }
-- file-backed: file plays once as the intro, loopFile loops after
{ file = "mods/my_mod/assets/town.ogg",
loopFile = "mods/my_mod/assets/town_loop.ogg" }
-- authored chip program
ChipAsm.song({ tempo = 140, channels = { { program = { ... } } } })A def with only file loops that file; a missing loopFile degrades to
the intro alone. A def that fails to load is skipped with a logged,
mod-attributed error when its cue fires — the rest of the soundtrack
plays on.
mod.content.sfx:register("SFX_MOD_CHIME", { file = mod.assets:path("assets/chime.ogg") })
mod.content.cries:register("MODMON", { file = mod.assets:path("assets/cry.wav") })
mod.content.cries:patch("PIKACHU", { pitch = 200 }) -- retune a vanilla cryCry shapes: { file }, a { base = "<species>", pitch?, length? }
derivation borrowing another cry's header, a raw
{ header, pitch, length }, or a chip program via ChipAsm.sfx.
src.audio.ChipAsm (a supported require) assembles note-event Lua
tables into the same channel bytecode the ROM's own songs run on:
local ChipAsm = require("src.audio.ChipAsm")
local song = ChipAsm.song({
tempo = 140, -- rides the first channel
channels = {
{ program = { -- channel 1 (squares 1-2, wave 3, noise 4)
{ label = "top" },
{ notetype = { speed = 12, volume = 15, fade = 2 } },
{ octave = 4 },
{ note = "C", len = 4 }, { note = "E", len = 4 },
{ rest = 4 },
{ loop = { count = 0, to = "top" } },
} },
{ hw = 4, program = { -- drums live on channel 4
{ drum = 3, len = 8 },
{ loop = { count = 0, to = 1 } },
} },
},
})
mod.content.music:register("Music_ModSong", song)Event vocabulary (one key per event, src/audio/ChipAsm.lua): note
(+len 1–16), pitch (explicit 0–11), rest, octave (1–8),
notetype (speed, volume, fade; wave channel takes waveLevel/
waveInstrument), drum (channel 4 only), label / call / ret /
loop = { count, to } (count 0 = forever), vibrato, slide, duty,
dutyPattern, tempo, pan, perfectPitch, squareNote/noiseNote
(effect programs), pitchSweep. subroutines = { name = { rows } } on
a channel spec serves call. Assembly errors name the channel and event
index. ChipAsm.sfx builds effect programs the same way for the sfx
registry.
Render without booting the game:
python3 tools/modkit.py bounce Music_ModSong --seconds 30mod.content.map_songs:override("PALLET_TOWN", "Music_ModSong")
mod.hooks:wrap("music.select", function(next, song, ctx)
if ctx.reason == "battle" and ctx.trainerId == "OPP_BROCK" then
return "Music_ModSong"
end
return next(song, ctx)
end)Every song choice — map themes, battle themes, jingles, scenes — passes
through music.select (ctx.reason: "map", "battle", "victory",
"once", "direct"; plus mapId, mapSong, onBike, surfing,
kind, trainerId). music.started / music.stopped /
sound.played announce what actually played.
Worked path: Tutorial 09.
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