Skip to content

3. Custom functions

AsynchronousAI edited this page Sep 3, 2025 · 5 revisions

Situation.

There are situations when you would like to access Luau functions in your low-level-language, this is very much possible!

We want to make a C program that every second will alternate our FOV between 70 and 110.

Writing C bindings.

First we need to write bindings for our functions in C.

void setCameraFOV(int x);
void task_wait(int time);

now we can complete our program:

int printf(const char *, ...);
void setCameraFOV(int fov);
void task_wait(int time);

int main(){
    int state = 0;
    while (task_wait(1)){
        state = !state;
        setCameraFOV(state == 0 ? 70 : 90);
        printf("State: %d\n", state);
    }
    return 0;
}

Compiling as a module.

In order to do this, we will need to compile our assembly file as a module to be imported by a parent module who will expose these functions.

The CLI provides such an option!

reasm main.s -o module.luau --mode module

Now if you look at the end of the compiled module you can see exposed methods:

-- comments added for wiki
return setmetatable({
	init = init, -- this will load all strings, and other static data into memory. should be called everytime before main()
	main = main, -- this is the main function for the C code.
	memory = memory, -- a buffer which represents the memory your C code is using.
	functions = functions, -- the magic where we add our own functions.
	util = { -- utilities which will help us with our custom function
            ...
	},
	registers = registers, -- CPU registers are represented as a table for quick access
	data = data, -- pointers to static data in memory
        ...
}, {__call = function() init(); main() end})

main.luau

We can start by just importing and using the module:

local module = require("./module")

module()

but we will only be greeted by an error in the output

./module.luau:187: No bindings for functions 'task_wait'
stacktrace:
[C] function error
./module.luau:187 function main
./module.luau:293 function __call
./main.luau:3

Providing our custom functions.

task_wait:

We can provide a task_wait function by adding the following code:

local module = require("./module")

module.functions["task_wait"] = function()
    local args = module.util.get_args()

    task.wait(args[1])
end

module()

We use module.util.extract_args() to return a table of (max 7) arguments which are all integers. Lucky for us, integers are a simple situation as arguments! String arguments are more complicated since they are derived from pointers.

setCameraFOV:

This is relatively similar, we can just use:

local module = require("./module")

module.functions["task_wait"] = function()
    local time = module.util.get_args()

    task.wait(time)
end

module.functions["setCameraFOV"] = function()
    local FOV = module.util.get_args()

    workspace.CurrentCamera.FieldOfView = FOV
end

module()

Screen.Recording.2025-08-31.at.9.22.16.PM.mov

Clone this wiki locally