Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data-canary/lib/core/load.lua
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
dofile(DATA_DIRECTORY .. "/lib/core/storages.lua")
require("data-canary.lib.core.quests")
dofile(DATA_DIRECTORY .. "/lib/core/quests.lua")
2 changes: 1 addition & 1 deletion data-canary/lib/core/quests.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
return require("data.lib.core.quests.loader").load(DATA_DIRECTORY)
return dofile(CORE_DIRECTORY .. "/lib/core/quests/loader.lua").load(DATA_DIRECTORY)
4 changes: 3 additions & 1 deletion data-canary/lib/core/quests/catalog/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ local questModules = {
}

local catalog = dofile(CORE_DIRECTORY .. "/lib/core/quests/catalog.lua")
local dirSep = package.config:sub(1, 1)
local catalogDirectory = table.concat({ DATA_DIRECTORY, "lib", "core", "quests", "catalog" }, dirSep)

return catalog.build(DATA_DIRECTORY .. ".lib.core.quests.catalog", questModules)
return catalog.build(DATA_DIRECTORY .. ".lib.core.quests.catalog", questModules, catalogDirectory)
2 changes: 1 addition & 1 deletion data-otservbr-global/lib/core/load.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
dofile(DATA_DIRECTORY .. "/lib/core/storages.lua")
dofile(DATA_DIRECTORY .. "/lib/core/constants.lua")
require("data-otservbr-global.lib.core.quests")
dofile(DATA_DIRECTORY .. "/lib/core/quests.lua")
2 changes: 1 addition & 1 deletion data-otservbr-global/lib/core/quests.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
return require("data.lib.core.quests.loader").load(DATA_DIRECTORY)
return dofile(CORE_DIRECTORY .. "/lib/core/quests/loader.lua").load(DATA_DIRECTORY)
4 changes: 3 additions & 1 deletion data-otservbr-global/lib/core/quests/catalog/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,7 @@ local questModules = {
}

local catalog = dofile(CORE_DIRECTORY .. "/lib/core/quests/catalog.lua")
local dirSep = package.config:sub(1, 1)
local catalogDirectory = table.concat({ DATA_DIRECTORY, "lib", "core", "quests", "catalog" }, dirSep)

return catalog.build(DATA_DIRECTORY .. ".lib.core.quests.catalog", questModules)
return catalog.build(DATA_DIRECTORY .. ".lib.core.quests.catalog", questModules, catalogDirectory)
8 changes: 8 additions & 0 deletions data/core.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
DATA_DIRECTORY = configManager.getString(configKeys.DATA_DIRECTORY)
CORE_DIRECTORY = configManager.getString(configKeys.CORE_DIRECTORY)

-- Extend package.path so that require() can find modules under the libs
-- directory (e.g. gamestore.*). The base path is kept minimal (set in C++)
-- to avoid the heavy string processing that LuaJIT's package.searchpath
-- performs on every require() call when running in interpreter-only mode
-- (macOS ARM64).
local sep = package.config:sub(1, 1)
package.path = package.path .. ";" .. CORE_DIRECTORY .. sep .. "libs" .. sep .. "?.lua" .. ";" .. CORE_DIRECTORY .. sep .. "libs" .. sep .. "?" .. sep .. "init.lua"

dofile(CORE_DIRECTORY .. "/global.lua")
dofile(CORE_DIRECTORY .. "/libs/libs.lua")
dofile(CORE_DIRECTORY .. "/stages.lua")
15 changes: 13 additions & 2 deletions data/lib/core/quests/catalog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,24 @@ local function validateStartStorage(quest, questName, owners)
owners[storage] = questName
end

local function buildCatalog(namespace, questModules)
local function buildCatalog(namespace, questModules, catalogDirectory)
local quests = {}
local missionOwners = {}
local storageOwners = {}
local dirSep = package.config:sub(1, 1)

for index, moduleName in ipairs(questModules) do
local quest = require(namespace .. "." .. moduleName)
local quest
if catalogDirectory then
local filePath = catalogDirectory .. dirSep .. moduleName .. ".lua"
local loader, errMsg = loadfile(filePath)
if not loader then
error(string.format("Quest module %s failed to load: %s", moduleName, errMsg))
end
quest = loader()
else
quest = require(namespace .. "." .. moduleName)
end
if type(quest) ~= "table" then
error(string.format("Quest module %s did not return a table", moduleName))
end
Expand Down
50 changes: 11 additions & 39 deletions data/lib/core/quests/loader.lua
Original file line number Diff line number Diff line change
@@ -1,49 +1,21 @@
local currentNamespace

local function ensureQuestCatalogLoader(namespace, catalogDirectory)
local searchers = package.searchers or package.loaders
local loaderRegistryName = namespace .. ".loader"
if package.loaded[loaderRegistryName] then
return
end

local dirSeparator = package.config:sub(1, 1)
local prefix = namespace .. "."

local function questCatalogLoader(moduleName)
if moduleName ~= namespace and moduleName:sub(1, #prefix) ~= prefix then
return nil
end
local filePath
if moduleName == namespace then
filePath = catalogDirectory .. dirSeparator .. "init.lua"
else
local relative = moduleName:sub(#prefix + 1):gsub("%.", dirSeparator)
filePath = catalogDirectory .. dirSeparator .. relative .. ".lua"
end
local loader, errorMessage = loadfile(filePath)
if not loader then
return "\n\t" .. errorMessage
end
return loader, filePath
end

table.insert(searchers, 1, questCatalogLoader)
package.loaded[loaderRegistryName] = true
end

local function loadQuestCatalog(dataDirectory)
local dirSeparator = package.config:sub(1, 1)
local namespace = dataDirectory .. ".lib.core.quests.catalog"
if Quests and currentNamespace == namespace then
-- Guard against redundant reloads. Since this file is loaded via dofile
-- (no require caching), use a global to track whether quests are already
-- loaded for the given namespace.
if Quests and _G._questCatalogNamespace == namespace then
return Quests
end
local catalogDirectory = table.concat({ dataDirectory, "lib", "core", "quests", "catalog" }, dirSeparator)

ensureQuestCatalogLoader(namespace, catalogDirectory)

Quests = require(namespace)
currentNamespace = namespace
-- Load init.lua directly via dofile instead of going through require's
-- package.searchpath machinery. On macOS ARM64 where LuaJIT runs in
-- interpreter-only mode, the string operations in searchpath across many
-- nested require calls cause severe startup delays.
local initPath = catalogDirectory .. dirSeparator .. "init.lua"
Quests = dofile(initPath)
_G._questCatalogNamespace = namespace
return Quests
end

Expand Down
4 changes: 3 additions & 1 deletion data/libs/functions/quests.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
require("data-otservbr-global.lib.core.quests")
-- Load quest catalog via dofile instead of require to avoid package.searchpath
-- overhead in LuaJIT interpreter mode (macOS ARM64).
dofile(DATA_DIRECTORY .. "/lib/core/quests.lua")

if not LastQuestlogUpdate then
LastQuestlogUpdate = {}
Expand Down
16 changes: 16 additions & 0 deletions src/lua/functions/lua_functions_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ void Lua::load(lua_State* L) {

luaL_openlibs(L);

// Set a minimal package.path so that require() only searches the working
// directory. The default path compiled into LuaJIT (plus whatever LUA_PATH
// adds) can contain many entries, and package.searchpath iterates through
// every one of them doing string operations for each require() call.
// On macOS ARM64 where LuaJIT runs in interpreter-only mode (JIT disabled),
// the cumulative cost of those string operations across 50+ nested require
// calls during startup causes the server to hang for minutes.
lua_getglobal(L, "package");
if (lua_istable(L, -1)) {
lua_pushliteral(L, "./?.lua;./?/init.lua");
lua_setfield(L, -2, "path");
lua_pushliteral(L, "");
lua_setfield(L, -2, "cpath");
}
lua_pop(L, 1);

CoreFunctions::init(L);
CreatureFunctions::init(L);
EventFunctions::init(L);
Expand Down
2 changes: 1 addition & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
]
}
},
"builtin-baseline": "66c0373dc7fca549e5803087b9487edfe3aca0a1"
"builtin-baseline": "c3867e714dd3a51c272826eea77267876517ed99"
}