fix: improve Gen2 data loading and error handling to prevent crashes when cache modules are missing on android

This commit is contained in:
1jamie
2026-08-15 12:30:58 -05:00
parent b29b6fd7bd
commit e24410f0fb
4 changed files with 121 additions and 27 deletions
+36 -15
View File
@@ -14,6 +14,14 @@ local MODULES = {
-- Optional for compatibility with developer and stale caches.
local OPTIONAL = { "audio", "palettes", "icons" }
-- Gold's extractor never writes these Gen 1 tables (RomExtractorGen2 has
-- maps/text/pokemon/items, not text_pointers / trainer_headers / field).
-- Desktop can still `require` Red's copies from the source tree, so Gold
-- Edit appeared to work there; an Android APK has only the per-version
-- cache, so Data:load used to throw on the first Gold Edit and take the
-- activity down. Empty tables are enough for seedDefaults / the editor.
local GEN2_OPTIONAL = { text_pointers = true, trainer_headers = true, field = true }
-- Vanilla defaults for rules exposed through the constants registry. A
-- value has to exist before a mod can patch it; each one matches the
-- engine's no-mod behavior, so seeding them changes nothing on a vanilla
@@ -99,7 +107,11 @@ end
-- Fills only what the cache is missing, so an importer that learns to
-- stamp one of these keys silently takes over from the engine.
function Data:seedDefaults()
local constants = self.constants
local constants = self.constants or {}
self.constants = constants
self.field = self.field or {}
self.maps = self.maps or {}
self.pokemon = self.pokemon or {}
for key, value in pairs(CONSTANT_DEFAULTS) do
if constants[key] == nil then constants[key] = copy(value) end
end
@@ -108,7 +120,11 @@ function Data:seedDefaults()
if constants.dexSize == nil then
local highest = 0
for _, def in pairs(self.pokemon) do
if def.dex and def.dex > highest then highest = def.dex end
-- Gold's pokemon.lua also carries growthRates / tmhmMoves / generation
-- scalars beside species rows.
if type(def) == "table" and def.dex and def.dex > highest then
highest = def.dex
end
end
constants.dexSize = highest
end
@@ -212,36 +228,41 @@ local function loadModule(dir, name)
if not chunk then return false, err end
return pcall(chunk)
end
local ok, mod = pcall(require, "data.generated." .. name)
if ok then return true, mod end
-- Fused PhysFS / Blue|Yellow prefix: load bytes from the active version's
-- cache explicitly when require cannot see the mounted tree.
local CacheFs = require("src.import.CacheFs")
local GameVersion = require("src.core.GameVersion")
local path = "data/generated/" .. name .. ".lua"
local bytes = CacheFs.readActive(path)
if type(bytes) == "string" then
local chunk, err = loadstring(bytes, "@" .. GameVersion.cachePrefix() .. path)
if not chunk then return false, err or mod end
return pcall(chunk)
local chunk = loadstring(bytes, "@" .. GameVersion.cachePrefix() .. path)
if chunk then
local ok, res = pcall(chunk)
if ok then return true, res end
end
end
return false, mod
local ok, mod = pcall(require, "data.generated." .. name)
if ok then return true, mod end
return false, nil
end
function Data:load()
local dir = os.getenv("POKEPORT_DATA_DIR")
local gen2 = require("src.core.GameVersion").generation() == 2
for _, name in ipairs(MODULES) do
local ok, mod = loadModule(dir, name)
if not ok then
if dir then
if gen2 and GEN2_OPTIONAL[name] then
self[name] = {}
elseif dir then
error(("missing data module '%s/%s.lua' (POKEPORT_DATA_DIR).\n(%s)")
:format(dir, name, mod))
else
error(("missing generated data module 'data/generated/%s.lua'.\n" ..
"Import the ROM again or rebuild developer data.\n(%s)")
:format(name, mod))
end
error(("missing generated data module 'data/generated/%s.lua'.\n" ..
"Import the ROM again or rebuild developer data.\n(%s)")
:format(name, mod))
else
self[name] = mod
end
self[name] = mod
end
for _, name in ipairs(OPTIONAL) do
local ok, mod = loadModule(dir, name)