From 90f7fce2b1051cd8dce5496b368c35f6fe745bbc Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Nov 2025 09:30:38 +0300 Subject: [PATCH 1/4] feat: pass pack environment to menu page script --- src/logic/scripting/lua/libs/libgui.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 6395dc5b..0f8ac2da 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -19,6 +19,8 @@ #include "graphics/ui/gui_util.hpp" #include "graphics/ui/markdown.hpp" #include "graphics/core/Font.hpp" +#include "content/Content.hpp" +#include "content/ContentPack.hpp" #include "items/Inventories.hpp" #include "util/stringutil.hpp" #include "world/Level.hpp" @@ -1026,13 +1028,17 @@ static int l_gui_load_document(lua::State* L) { io::path filename = lua::require_string(L, 1); auto alias = lua::require_string(L, 2); auto args = lua::tovalue(L, 3); - + auto prefix = filename.entryPoint(); + + auto env = scripting::get_root_environment(); + if (content) { + if (auto runtime = content->getPackRuntime(prefix)) { + env = runtime->getEnvironment(); + } + } + auto documentPtr = UiDocument::read( - engine->getGUI(), - scripting::get_root_environment(), - alias, - filename, - filename.string() + engine->getGUI(), std::move(env), alias, filename, filename.string() ); auto document = documentPtr.get(); engine->getAssets()->store(std::move(documentPtr), alias); From ca6096c397639f6f627e806eafa8ca0aa2f295d7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Nov 2025 11:53:48 +0300 Subject: [PATCH 2/4] minor refactor --- res/layouts/pages/scripts.xml.lua | 12 ++---------- res/scripts/stdlib.lua | 14 ++++++++++++++ src/engine/ServerMainloop.cpp | 3 +-- src/logic/scripting/scripting.cpp | 13 +++++++++++-- src/logic/scripting/scripting.hpp | 1 + 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/res/layouts/pages/scripts.xml.lua b/res/layouts/pages/scripts.xml.lua index dad0d1ff..72c3246f 100644 --- a/res/layouts/pages/scripts.xml.lua +++ b/res/layouts/pages/scripts.xml.lua @@ -1,18 +1,10 @@ function run_script(path) - debug.log("starting application script "..path) - - local code = file.read(path) - local chunk, err = loadstring(code, path) - if chunk == nil then - error(err) - end - setfenv(chunk, setmetatable({app=__vc_app}, {__index=_G})) - start_coroutine(chunk, path) + __vc_start_app_script(path) end function refresh() document.list:clear() - + local allpacks = table.merge(pack.get_available(), pack.get_installed()) local infos = pack.get_info(allpacks) for _, name in ipairs(allpacks) do diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 3f732e07..447f7dd4 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -186,6 +186,20 @@ events = require "core:internal/events" function pack.unload(prefix) events.remove_by_prefix(prefix) + __vc__pack_envs[prefix] = nil +end + +function __vc_start_app_script(path) + debug.log("starting application script "..path) + + local code = file.read(path) + local chunk, err = loadstring(code, path) + if chunk == nil then + error(err) + end + local script_env = setmetatable({app = app or __vc_app}, {__index=_G}) + setfenv(chunk, script_env) + return start_coroutine(chunk, path) end gui_util = require "core:internal/gui_util" diff --git a/src/engine/ServerMainloop.cpp b/src/engine/ServerMainloop.cpp index 2f446533..ab35ffbd 100644 --- a/src/engine/ServerMainloop.cpp +++ b/src/engine/ServerMainloop.cpp @@ -32,8 +32,7 @@ void ServerMainloop::run() { setLevel(std::move(level)); }); - logger.info() << "starting test " << coreParams.scriptFile.string(); - auto process = scripting::start_coroutine( + auto process = scripting::start_app_script( "script:" + coreParams.scriptFile.filename().u8string() ); diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 4d3672f1..c15f30aa 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -151,9 +151,10 @@ std::unique_ptr scripting::load_client_project_script( return std::make_unique(L, std::move(env)); } -std::unique_ptr scripting::start_coroutine(const io::path& script) { +static std::unique_ptr start_lua_coroutine( + const io::path& script, const std::string& method +) { auto L = lua::get_main_state(); - auto method = "__vc_start_coroutine"; if (lua::getglobal(L, method)) { auto source = io::read_string(script); lua::loadbuffer(L, 0, source, script.name()); @@ -167,6 +168,14 @@ std::unique_ptr scripting::start_coroutine(const io::path& script) { return nullptr; } +std::unique_ptr scripting::start_coroutine(const io::path& script) { + return start_lua_coroutine(script, "__vc_start_coroutine"); +} + +std::unique_ptr scripting::start_app_script(const io::path& script) { + return start_lua_coroutine(script, "__vc_start_app_script"); +} + [[nodiscard]] scriptenv scripting::get_root_environment() { return std::make_shared(0); } diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 5a86b81d..2f45ae60 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -77,6 +77,7 @@ namespace scripting { ); std::unique_ptr start_coroutine(const io::path& script); + std::unique_ptr start_app_script(const io::path& script); void on_world_load(LevelController* controller); void on_world_tick(int tps); From 9afe265094abf7fcc8535d6a58ec725d02df3847 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Nov 2025 11:59:58 +0300 Subject: [PATCH 3/4] update doc/*/scripting/builtins/libapp.md --- doc/en/scripting/builtins/libapp.md | 2 ++ doc/ru/scripting/builtins/libapp.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/doc/en/scripting/builtins/libapp.md b/doc/en/scripting/builtins/libapp.md index 69a472ee..45414ba1 100644 --- a/doc/en/scripting/builtins/libapp.md +++ b/doc/en/scripting/builtins/libapp.md @@ -7,6 +7,8 @@ The script/test name without the path and extension is available as `app.script` local filename = "script:"..app.script..".lua" ``` +Since the control script may not belong to any of the packs, it does not belongs to its own package and has its own global namespace in which all global functions and tables are available, as well as the `app` library. + ## Functions ```lua diff --git a/doc/ru/scripting/builtins/libapp.md b/doc/ru/scripting/builtins/libapp.md index 4e9493c4..d2ddec72 100644 --- a/doc/ru/scripting/builtins/libapp.md +++ b/doc/ru/scripting/builtins/libapp.md @@ -7,6 +7,8 @@ local filename = "script:"..app.script..".lua" ``` +Так как управляющий сценарий может не принадлежать ни одному из паков, он не относиться к своему паку и имеет собственное пространство имён, в котором доступны все глобальные функции и таблицы, а также библиотека `app`. + ## Функции ```lua From d163f12e6796379fcf4536e8ee2abe5413561260 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Nov 2025 12:13:55 +0300 Subject: [PATCH 4/4] fix --- res/scripts/stdlib.lua | 4 ++-- src/logic/scripting/scripting.cpp | 17 +++-------------- src/logic/scripting/scripting.hpp | 1 - 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 447f7dd4..4443eed3 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -198,8 +198,8 @@ function __vc_start_app_script(path) error(err) end local script_env = setmetatable({app = app or __vc_app}, {__index=_G}) - setfenv(chunk, script_env) - return start_coroutine(chunk, path) + chunk = setfenv(chunk, script_env) + return __vc_start_coroutine(chunk, path) end gui_util = require "core:internal/gui_util" diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index c15f30aa..586feeb8 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -151,13 +151,10 @@ std::unique_ptr scripting::load_client_project_script( return std::make_unique(L, std::move(env)); } -static std::unique_ptr start_lua_coroutine( - const io::path& script, const std::string& method -) { +std::unique_ptr scripting::start_app_script(const io::path& script) { auto L = lua::get_main_state(); - if (lua::getglobal(L, method)) { - auto source = io::read_string(script); - lua::loadbuffer(L, 0, source, script.name()); + if (lua::getglobal(L, "__vc_start_app_script")) { + lua::pushstring(L, script.string()); if (lua::call(L, 1)) { int id = lua::tointeger(L, -1); lua::pop(L, 1); @@ -168,14 +165,6 @@ static std::unique_ptr start_lua_coroutine( return nullptr; } -std::unique_ptr scripting::start_coroutine(const io::path& script) { - return start_lua_coroutine(script, "__vc_start_coroutine"); -} - -std::unique_ptr scripting::start_app_script(const io::path& script) { - return start_lua_coroutine(script, "__vc_start_app_script"); -} - [[nodiscard]] scriptenv scripting::get_root_environment() { return std::make_shared(0); } diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 2f45ae60..d9c7e614 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -76,7 +76,6 @@ namespace scripting { const io::path& script ); - std::unique_ptr start_coroutine(const io::path& script); std::unique_ptr start_app_script(const io::path& script); void on_world_load(LevelController* controller);