Skip to content
Ali Hussain edited this page Sep 29, 2023 · 5 revisions

Lua Managers

Lua Managers allow plugin developers to easily communicate with their plugin from within lua scripts. You can use Lua Managers to add more functionality to menus or do something specific when in an item/assist/boss.

There are two different "register" functions for lua managers, with one being for menus while the other for in-game scripts. The exported functions for both follow the same signature though, with the complete function looking something like this:

extern "C" fn my_function(state: &mut lua_state) -> i32 {
    0
}

We just need to export a C function that takes in a lua_state and returns a signed 32-bit integer. To pass arguments from the lua script to our rust code, we can use the following functions:

  • state.get_integer_arg(); -> u64
  • state.get_number_arg(); -> f32
  • state.get_string_arg(); -> String

Properly calling these functions require us to call it in the inverse order of which our arguments are sent. A function that takes in all three types would look something like this:

  • The call from the lua script
my_function("called from within lua!", 6.84, 402)
  • Our exported function getting the arguments
extern "C" fn my_function(state: &mut lua_state) -> i32 {
    let int = state.get_integer_arg(); // 402
    println!("int: {}", int);
    let float = state.get_number_arg(); // 6.84
    println!("float: {}", float);
    let msg = state.get_string_arg(); // called from within lua!
    println!("msg: {}", msg);
    0
}

With that, we have the function completely set up. Onwards to registering them for actual use!

Registering functions

Registering functions with the ARCropolis API is very simple. There are two different functions that can be used for registering, these being the following:

  • add_lua_menu_manager
  • add_lua_ingame_manager

add_lua_menu_manager only registers our functions for use on the menus (Main Menu, SSS, etc...) and add_lua_ingame_manager only registers our functions for use on the in-game stuff (Smash Mode (in the actual match), Training Mode, etc...)

The arguments for both functions are as follows:

  • name -> String
  • functions -> Vec

The name argument is going to be the name of your actual manager, while the functions argument is going to be the vector of all functions you want to assign to that manager.

An example of adding a new menu function that does stuff would look something like this:

extern "C" fn test_function(state: &mut lua_state) -> i32 {
    // ...
    0
}

#[skyline::main(name = "my_lua_plugin")]
pub fn main() {
    // This function adds the manager specifically for the menus
    add_lua_menu_manager("TestManager", 
        vec![
            luaL_Reg {
                name: "test_function".to_string(),
                func: Some(test_function),
            }
        ]
    );
}

in your menu lua script, you can now call your function simply by doing:

TestManager.test_function()

To register functions for the in-game modes, you can just replace add_lua_menu_manager with add_lua_ingame_manager.

  • Notes
    • You can register the same manager name on both (menu and in-game) with no issues (from my limited testing)
    • Normally for menus, the Vector needs a std::ptr::null and None at the end, but ARCropolis automatically appends it

Clone this wiki locally