-
Notifications
You must be signed in to change notification settings - Fork 6
Lua Scripting
Lua scripts live in Scripts/ and control dynamic behaviour such as the game background. The engine loads scripts from subdirectories: a folder named background containing background.lua becomes the background script.
Scripts/
└── background/
├── background.lua (entry point, required name matches folder)
└── bg_objects/
├── donbg.lua
├── bg_normal.lua
├── bg_fever.lua
└── ...
The engine calls fixed methods on the returned script object. For the background script, the expected interface is:
Background = {}
Background.__index = Background
function Background.new(player_num, bpm, scene_preset)
local self = setmetatable({}, Background)
-- initialise
return self
end
function Background:update(current_ms, bpm) end
function Background:handle_good(player_num) end
function Background:handle_ok(player_num) end
function Background:handle_bad(player_num) end
function Background:handle_drumroll(player_num) end
function Background:handle_balloon(player_num) end
function Background:handle_gauge(player_num, progress, is_clear, is_rainbow) end
function Background:draw_back() end
function Background:draw_fore() end
function Background:destroy() endThe tex table provides access to textures and the skin configuration.
tex.load_animations("background")
tex.load_folder("background", "bg_normal/bg_0")
tex.unload_folder("background", "bg_normal/bg_0")tex.draw_texture("background", "bg_normal/bg_0/background", {
x = 0,
y = 0,
scale = 1.0,
rotation = 0.0,
fade = 1.0,
frame = 0,
index = 0,
center = false,
color = {255, 255, 255, 255},
mirror = "horizontal", -- "horizontal" or "vertical"
origin = {0, 0},
src = { x = 0, y = 0, width = 100, height = 100 },
x2 = nil,
y2 = nil,
})You can also draw by numeric ID for performance:
local id = tex.get_id("background", "bg_normal/bg_0/background")
tex.draw_id(id, { x = 0, y = 0 })local info = tex.get_texture_info("background", "bg_normal/bg_0/background")
-- info.x, info.y, info.width, info.height, info.name, info.frame_count
local keys = tex.get_texture_keys("background/bg_normal/bg_0")
-- returns an array of texture name stringslocal w = tex.get_screen_width()
local h = tex.get_screen_height()
local s = tex.get_screen_scale()local cfg = tex.get_skin_config("game_2p_offset")
if cfg then
local y_offset = cfg.y
end
-- Returns table with x, y, width, height, font_size, or nil if not found.The anim table creates animation objects. Animations defined in animation.json can be retrieved and copied; animations can also be created inline in Lua.
local move_anim = tex.get_animation(0) -- shared instance
local move_copy = tex.get_animation(0, true) -- independent copylocal fade = anim.fade(150, {
initial_opacity = 0.0,
final_opacity = 1.0,
loop = false,
delay = 0.0,
ease_in = "quadratic",
ease_out = "quadratic",
reverse_delay = 0,
})
local move = anim.move(3000, {
total_distance = -328,
start_position = 0,
loop = true,
})
local tc = anim.texture_change(600, {
{0, 100, 0},
{100, 200, 1},
{200, 300, 2},
}, { loop = true })
local resize = anim.texture_resize(200, {
initial_size = 1.0,
final_size = 0.0,
})
local stretch = anim.text_stretch(300, { loop = false })All animation objects share these methods:
| Method | Description |
|---|---|
anim:update(ms) |
Advance the animation by ms milliseconds; returns the current attribute value |
anim:start() |
Start the animation |
anim:restart() |
Restart from the beginning |
anim:pause() |
Pause |
anim:unpause() |
Resume |
anim:reset() |
Reset to initial state without starting |
anim.attribute |
Current value (opacity, position, scale, etc.) |
anim.duration |
Total duration in ms |
anim:is_finished() |
Returns true when the animation has completed |
anim:is_started() |
Returns true if the animation has begun |
The text table creates outlined text objects that can be drawn with tex.draw_texture-style parameters.
local label = text.create_text(
"free_play", -- skin_config.json key (provides text string and font_size)
{255, 255, 255, 255}, -- text color RGBA
{0, 0, 0, 255}, -- outline color RGBA
false, -- is_vertical
2, -- outline thickness
0.0 -- letter spacing
)
if label.is_ready and not label.upload_pending then
label:finish()
label:draw({ x = 100, y = 200 })
endOutlinedText exposes width, height, is_ready, and upload_pending properties.
Songs can specify a scene_preset that routes the background to a collab implementation. Built-in collab keys are:
PRACTICE, TUTORIAL, A3, ANIMAL, BUTTOBURST, DAN, FUNASSYI, IMAS, IMAS_CG, IMAS_ML, IMAS_SIDEM, OSHIRI
Collab scripts are placed in Scripts/background/bg_collabs/ and loaded via require. Each collab that needs unique graphics specifies a path under Graphics/background/collab/<name>/.
Building
libs
- animation
- audio
- config
- filesystem
- global_data
- input
- logging
- ray
- scores
- screen
- script
- song_parser
- text
- texture
- video
- webcam
libs/parsers
objects
objects/game
- player
- background
- gauge
- judgment
- combo
- branch_indicator
- ending_animations
- gogo_time
- fireworks
- song_info
- transition
- result_transition
- judge_counter
- score_counter
- score_counter_animation
- balloon_counter
- drumroll_counter
- kusudama_counter
- drum_hit_effect
- lane_hit_effect
- gauge_hit_effect
- combo_announce
- note_arc
objects/global
objects/title
objects/entry
objects/settings
objects/result
objects/song_select
- player
- navigator
- box_base
- box_song
- box_folder
- neiro
- modifier
- ura_switch
- diff_sort
- search_box
- dan_transition
- genre_bg
- score_history
- song_select_script
scenes