Skip to content

Autorun Script #62

@vurvdev

Description

@vurvdev

A custom scripting language which uses the Lua C Api to interact with the client state.

Why

  • Running Lua in the client state is a losing battle due to
    • Debug hooks
    • Jit hooks (recently disabled)
    • Memory usage tracking
    • Stack level usage

Purely interacting via the C Api is ideal.

Why not use another state

The alternative would be to simply run lua in a separate state, ie the menu state, and serialize values / pass custom functions to interact with the other state. Problems:

  • It's incredibly confusing to explain to people.
    • You're in one state but you're not allowed to do something like _G.foo = {} ? What is the other state? What is a state?
  • Its not simple, and values couldn't easily be moved or shared across states.

Why a custom language

Currently the mockup I have looks identical to lua, and I'll try to keep it that way, but it might be confusing that way too, as they might think it is pure lua. Depending on how compatible with actual lua I can get it to be, it can be fine.

Pros:

  • Could extend the language with autorun specific syntax
  • Can be compiled directly to C instead of interpreted

Current MVP

local function test(a, b, c)
    return a + b * c
end

function main()
    local x = 10.213 .. "foo"
    local y = _G.foo
    _G.bar.baz = 24
    _G.foo(1, 2, 3)

    local f = {
        a = 1,
        b = 2,
        c = 3,
        4,
        5
    }

    if true then
        _G.qux()
    elseif false then
        return nil
    else
        return x + y
    end

    while not false do
        local z = 2
    end
end

Compiles to

int test(void* state) {
	Value a = tovalue(state, 1);
	Value b = tovalue(state, 2);
	Value c = tovalue(state, 3);
	pushvalue(state, add(state, a, mul(state, b, c)));
	return 1;
}
int main(void* state) {
	Value x = concat(state, NUMBER(10.213), STRING("foo"));
	Value y = indexget(state, globals(state), "foo");
	indexset(state, indexget(state, globals(state), "bar"), "baz", NUMBER(24));
	call(state, indexget(state, globals(state), "foo"), 3, NUMBER(1), NUMBER(2), NUMBER(3));
	Value f = table(state, 5, STRING("a"), NUMBER(1), STRING("b"), NUMBER(2), STRING("c"), NUMBER(3), NUMBER(1), NUMBER(4), NUMBER(2), NUMBER(5));
	if (truthy(state, BOOLEAN(1))) {
		call(state, indexget(state, globals(state), "qux"), 0);
	} else if (truthy(state, BOOLEAN(0))) {
		pushvalue(state, NIL);
		return 1;
	} else {
		pushvalue(state, add(state, x, y));
		return 1;
	}
	while (truthy(state, not(state, BOOLEAN(0)))) {
		Value z = NUMBER(2);
	}
}
int _entry(void* state) {
	register_function(state, "main", main);
	return main(state);
}

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions