Lua Scripting (IKEMEN Go)
Overview
IKEMEN Go extends MUGEN with a full Lua scripting system. Lua scripts power custom game modes, story mode narratives, arcade mode paths, custom menus, and advanced game logic that isn't possible with .cns state controllers alone.
Lua Script Locations
code
external/
├── mods/
│ ├── arcade.lua ; Custom arcade mode logic
│ ├── story.lua ; Story mode script
│ ├── survival.lua ; Survival mode
│ ├── bonus.lua ; Bonus stages
│ └── custom_mode.lua ; Custom game modes
└── modules/
└── helper_functions.lua ; Shared utility modules
IKEMEN Go Lua API
Core Functions
Character & Match Control:
lua
-- Start a match start.f_selectSimple(chars, stage, music, gamemode) -- Character selection selectChar(player, charpath) -- Select character for player selectStage(stagepath) -- Select stage selectMusic(musicpath) -- Override music -- Match result winner() -- Returns winning player/team matchOver() -- Check if match ended roundNo() -- Current round number matchNo() -- Current match number
Player Info:
lua
player(n) -- Get player n object player(n).name -- Character name player(n).life -- Current life player(n).lifeMax -- Maximum life player(n).power -- Current power meter player(n).powerMax -- Maximum power player(n).wins -- Win count player(n).losses -- Loss count player(n).drawgames -- Draw count
Screen & UI:
lua
-- Text display
txt = text:create({}) -- Create text object
txt:update({
text = "Hello World",
x = 320, y = 240,
font = "f-6x9.fnt",
align = 0, -- -1=left, 0=center, 1=right
r = 255, g = 255, b = 255 -- Color
})
txt:draw() -- Render text
-- Sprite display
spr = sprite:create({})
spr:update({
sff = "data/system.sff",
group = 0, index = 0,
x = 640, y = 360,
scale = {1, 1},
facing = 1,
alpha = {255, 0} -- Source, destination alpha
})
spr:draw()
-- Animation
anim = animation:create({})
anim:update({
sff = "data/fightfx.sff",
air = "data/fightfx.air",
action = 0,
x = 640, y = 360,
scale = {1, 1}
})
anim:draw()
Input:
lua
-- Button checks (returns true if pressed this frame) inputDown(player, "u") -- Up inputDown(player, "d") -- Down inputDown(player, "l") -- Left inputDown(player, "r") -- Right inputDown(player, "a") -- Button A (light punch) inputDown(player, "b") -- Button B (medium punch) inputDown(player, "c") -- Button C (heavy punch) inputDown(player, "x") -- Button X (light kick) inputDown(player, "y") -- Button Y (medium kick) inputDown(player, "z") -- Button Z (heavy kick) inputDown(player, "s") -- Start -- Held buttons inputHeld(player, "a") -- Button held down
Audio:
lua
-- Play sound effect
snd = sound:create("data/system.snd")
snd:play(group, index)
-- Play music
playBGM(filepath)
stopBGM()
setBGMVolume(volume) -- 0-100
Scene/Flow Control:
lua
-- Screen transitions fadeIn(time) -- Fade from black fadeOut(time) -- Fade to black wait(ticks) -- Wait N ticks -- Scene management enterScene(sceneName) -- Switch to named scene exitScene() -- Exit current scene
System:
lua
-- Game state gameMode() -- Current game mode string gameTime() -- Global game timer fps() -- Current FPS
Game Mode Architecture
Each game mode is a Lua module that follows this structure:
lua
-- mymode.lua
local mymode = {}
-- Called when mode is selected from menu
function mymode.f_start()
-- Initialize mode
local matchCount = 0
local maxMatches = 8
while matchCount < maxMatches do
-- Pre-match setup
mymode.f_selectOpponent(matchCount)
-- Run the match
start.f_selectSimple(...)
-- Post-match
if winner() == 1 then
matchCount = matchCount + 1
else
-- Game over
mymode.f_gameOver()
return
end
end
-- All matches won
mymode.f_ending()
end
-- Opponent selection logic
function mymode.f_selectOpponent(matchNum)
-- Select appropriate opponent based on progression
end
-- Game over screen
function mymode.f_gameOver()
fadeOut(30)
-- Show game over graphics
-- Return to title
end
-- Ending sequence
function mymode.f_ending()
fadeOut(30)
-- Play ending storyboard/cutscene
end
return mymode
Story Mode
Story mode uses Lua for narrative flow with cutscenes between fights:
lua
local story = {}
function story.f_start()
-- Prologue cutscene
story.f_cutscene("prologue")
-- Chapter 1: First fight
story.f_cutscene("chapter1_intro")
story.f_fight({
p1 = "chars/hero/hero.def",
p2 = "chars/rival/rival.def",
stage = "stages/dojo/dojo.def",
music = "sound/rival_theme.mp3",
rounds = 2
})
if winner() == 1 then
story.f_cutscene("chapter1_win")
else
story.f_cutscene("chapter1_lose")
return -- End story on loss
end
-- Chapter 2
story.f_cutscene("chapter2_intro")
story.f_fight({...})
-- ...continue story
end
function story.f_cutscene(name)
fadeOut(20)
fadeIn(20)
-- Display background
local bg = sprite:create({})
bg:update({
sff = "data/story.sff",
group = story.scenes[name].bg_group,
index = 0,
x = 640, y = 360
})
-- Display dialogue
local dialogue = story.dialogues[name]
for i, line in ipairs(dialogue) do
bg:draw()
story.f_showDialogue(line.speaker, line.text)
story.f_waitForInput()
end
fadeOut(20)
end
function story.f_fight(params)
selectChar(1, params.p1)
selectChar(2, params.p2)
selectStage(params.stage)
start.f_selectSimple(...)
end
return story
Arcade Mode Paths
Custom arcade paths define opponent order and conditions:
lua
local arcade = {}
arcade.path = {
{char = "chars/grunt1/grunt1.def", stage = "stages/street/street.def", order = 1},
{char = "chars/grunt2/grunt2.def", stage = "stages/alley/alley.def", order = 1},
{char = "chars/rival/rival.def", stage = "stages/dojo/dojo.def", order = 1},
-- Rival rematch (mid-boss)
{char = "chars/rival/rival.def", stage = "stages/temple/temple.def", order = 2,
intro = "story/rival_rematch.lua"},
-- Final boss
{char = "chars/boss/boss.def", stage = "stages/throne/throne.def", order = 3,
intro = "story/boss_intro.lua", ending = "story/ending.lua",
hidden = true, ai_level = 8},
}
return arcade
Custom Menus
IKEMEN Go allows Lua-driven custom menus:
lua
local menu = {}
menu.items = {
{name = "Arcade Mode", func = arcade.f_start},
{name = "Story Mode", func = story.f_start},
{name = "Versus Mode", func = versus.f_start},
{name = "Training", func = training.f_start},
{name = "Options", func = options.f_start},
{name = "Gallery", func = gallery.f_start}, -- Custom!
{name = "Exit", func = os.exit},
}
return menu
Tips
- •Always use
localfor variables to avoid global pollution - •Test scripts by launching IKEMEN Go with
-debugflag - •Use
print()for debug output (appears in console) - •Keep cutscene data separate from logic (data tables + rendering functions)
- •Handle both win and loss conditions in story mode
- •Use fadeIn/fadeOut for smooth scene transitions
- •IKEMEN Go Lua uses standard Lua 5.1 syntax
- •Check the engine's
external/folder for built-in script examples