Files
bo3-js/js/instances/Script.js

64 lines
1.8 KiB
JavaScript
Raw Normal View History

2025-10-23 20:58:19 +02:00
import { lua, lauxlib, lualib, to_luastring } from "fengari";
import { ScriptSchedulerService } from "./ScriptSchedulerService.js";
import { Instance } from "./Instance.js"; // your engine's instance class
// Import interop from fengari-interop
import { push, luaopen_js } from "fengari-interop";
export class Script extends Instance {
constructor(sourceCode) {
super("Script");
this.Source = sourceCode;
this.LuaState = null;
}
Run() {
const L = lauxlib.luaL_newstate();
luaopen_js(L);
lualib.luaL_openlibs(L);
// Bridge all engine APIs
this._registerGlobals(L);
// Compile the source
const status = lauxlib.luaL_loadstring(L, to_luastring(this.Source));
if (status !== lua.LUA_OK) {
const err = lua.lua_tojsstring(L, -1);
throw new Error("Lua load error: " + err);
}
// Create a coroutine thread
const thread = lua.lua_newthread(L);
// Schedule with scheduler
this._getScheduler().scheduleFengariCoroutine(thread, L);
this.LuaState = L;
}
_registerGlobals(L) {
// game global
push(L, globalThis.game);
lua.lua_setglobal(L, to_luastring("game"));
// task + wait bridge
lua.lua_pushjsfunction(L, () => {
const secs = lua.lua_isnumber(L, 1) ? lua.lua_tonumber(L, 1) : 0;
const yieldVal = JSON.stringify({ wait: secs });
lua.lua_pushstring(L, to_luastring(yieldVal));
return lua.lua_yield(L, 1);
});
lua.lua_setglobal(L, to_luastring("task_wait"));
// Lua API helpers
lua.lua_pushjsfunction(L, () => {
const inst = new Instance("Part"); // example
return inst.LuaBridge(); // converts to Lua table/proxy
});
lua.lua_setglobal(L, to_luastring("Instance_new"));
}
_getScheduler() {
return game.GetService("ScriptSchedulerService");
}
}