Tutorials:Ini to Lua
From SMTheming Wiki
If you already know how to theme for StepMania 3.9 and want to make themes for StepMania 4.0, there's a major difference in how BGAnimations and the like get made. In 3.9, you would use .ini files to define all the layers. In StepMania 4, this has been replaced with Lua.
Before continuing on, it is assumed that you have a basic knowledge of theming for 3.9. This guide will only list basic conversions; it will not talk about new layer types like Quad, etc.
Contents |
The Basics
File Structure
With Lua, the BGAnimation is structured a bit differently. Where you have [BGAnimation] in ini files, Lua requires a table to be returned. More often than not, this takes the form of a variable containing an ActorFrame (expressed in code as local t = Def.ActorFrame{ ... }, with the ... being the body of the ActorFrame).
Compare the basic setups:
Ini
[BGAnimation]Lua
local t = Def.ActorFrame{ }; return t;
These two examples are the bare minimum you need for a working BGAnimation. It should be noted that you don't have to name it t. You can name it whatever you wish, including overlay, meter, and so on. Just remember to change the return value as well.
Loading Files
The basic unit of a layer in the ini is [Layer#], where the # can be any number. There are many things you can throw in these layers, but the most common are files.
Ini
[Layer1] File=a.png
Lua
In Lua, you use LoadActor(name) to define a layer. There are other ways of defining a layer (as well as many other objects not normally callable in 3.9), but LoadActor is the most common.
First, a simple example, without any commands:
LoadActor("a");
Note that you must put the file name in quotation marks and that the extension is optional. Generally, these go into the main ActorFrame you set up at the beginning. In context, the entire file would look like:
local t = Def.ActorFrame{ LoadActor("a"); }; return t;
However, you'll often want to add commands, so you need to add a few lines:
LoadActor("a")..{ InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y); };
The main thing to take away here is that commands are normally wrapped within cmd(). They don't always have to be, but it's simpler this way.
InitCommand is just one of the few command types built in to StepMania. If you've worked with 3.9 before, you should be familiar with a few of these, mainly Command (unused in SM4), OnCommand, and OffCommand. With this command added, the entire file looks like this:
local t = Def.ActorFrame{ LoadActor("a")..{ InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y); }; }; return t;
Text
Usually, there were one of two ways you handled text in 3.9: .actor files and within the ini itself.
Ini
[Layer1] Text=Test Text File=Common normal OnCommand=x,320;y,264
Actor
[Actor] Text=Test Text File=Common normal OnCommand=x,320;y,264
Lua
With Lua, the setup has changed a little bit:
LoadFont("Common normal")..{ Text="Test Text"; OnCommand=cmd(x,320;y,264); };
There is also a settext command (settext,"Text Text") for use inside of commands, if you don't like using the Text attribute.
Positioning
In StepMania 4, positioning has become more flexible, due to the existence of various SCREEN_ aliases. If you used absolute positioning before, it's a better idea to use relative positioning, either using the center of the screen or any of the sides.
The below table of equivalent positions operates on the assumption that your theme is set to 640x480 (see [Common] ScreenWidth/Height in the metrics if you are not sure; if it doesn't exist in your theme, check the default.)
| Name | Equivalent Position |
|---|---|
| SCREEN_CENTER_X | 320 |
| SCREEN_CENTER_Y | 240 |
| SCREEN_WIDTH | 640 |
| SCREEN_HEIGHT | 480 |
| SCREEN_LEFT | 0 |
| SCREEN_RIGHT | 640 |
| SCREEN_TOP | 0 |
| SCREEN_BOTTOM | 480 |
Intermediate and Advanced Topics
CommandRepeatSeconds
A useful command in 3.9 BGAnimations is CommandRepeatSeconds, which will allow you to specify how often the command should repeat. There is no direct substitute for this using Lua, so you have you think outside the box.
queuecommand can take the place of CommandRepeatSeconds, assuming you time everything out. queuecommand takes in one parameter, a string that represents the command to be queued up. Say you have queuecommand,"Animate". This will queue up the matching AnimateCommand on the target object. Note how the word "Command" was added to the end of the command name.
By combining queuecommand with sleep, it's possible to get an equivalent effect to CommandRepeatSeconds.
Complete Conversion
Ini
[BGAnimation] [Layer1] File=a.png Command=x,320;y,240; [Layer2] Text=Test Text File=Common normal OnCommand=x,320;y,264 [Layer3] File=b.png OnCommand=shadowlength,0;x,136;y,300;zoom,0.5;horizalign,left;diffusealpha,0;accelerate,1;diffusealpha,1;sleep,5;decelerate,1;diffusealpha,0; OffCommand=linear,0.25;diffusealpha,0; CommandRepeatSeconds=30
Lua
local t = Def.ActorFrame{ --[Layer1] LoadActor("a")..{ InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y); }; --[Layer2] LoadFont("Common normal")..{ Text="Test Text"; OnCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y+24); }; --[Layer3] LoadActor("b")..{ InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y+60;shadowlength,0;zoom,0.5;horizalign,left;); OnCommand=cmd(diffusealpha,0;playcommand,"Animate"); AnimateCommand=cmd(accelerate,1;diffusealpha,1;sleep,5;decelerate,1;diffusealpha,0;sleep,23;queuecommand,"Animate"); }; }; return t;
SM Ini to Lua Converter
SM Ini to Lua Converter is a Windows .NET program by Daisuke Master. It can convert a BGAnimation.ini file to Lua with the following restrictions:
- Tile and Particle layer types are not supported.
- Conditionals are not converted to the StepMania 4 equivalents.

