From c3875fd0cabf7f033d9cf4bc9df2b9e516f19066 Mon Sep 17 00:00:00 2001 From: Xzyer Date: Fri, 14 Aug 2026 00:25:03 -0600 Subject: [PATCH] Update hooks.lua to fix crash when leaving lobby MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a player leaves a multiplayer lobby (or an opponent disconnects), Entropy crashes with: [SMODS entr "lib/hooks.lua"]:1169: bad argument #1 to 'pairs' (table expected, got nil) The crash occurs during the transition from the multiplayer lobby state back to the main menu. SMODS.get_card_areas('jokers') returns a non-nil table of area objects, but those area objects have a nil .cards field because the jokers area has not been fully initialized yet during this game-state transition. Affected locations in lib/hooks.lua: - Line ~1169 — inside create_card function (the primary crash site) - Line ~2170 — inside add_tag function - Line ~3138 — inside interest calculation function All three iterate over _joker_areas = SMODS.get_card_areas('jokers') and then call pairs(a.cards) without checking if .cards is nil. Reproduction: 1. Join a multiplayer game lobby with Entropy installed 2. Leave the lobby (or have an opponent disconnect) 3. Game crashes on transition back to main menu Proposed fix: Add nil guards around a.cards in all three locations: Before: local _joker_areas = SMODS.get_card_areas('jokers') if _joker_areas then for i, a in pairs(_joker_areas) do for _, c in pairs(a.cards) do -- crashes if a.cards is nil After: local _joker_areas = SMODS.get_card_areas('jokers') if _joker_areas then for i, a in pairs(_joker_areas) do if a.cards then <-- guard added for _, c in pairs(a.cards) do This is safe because skipping the loop when .cards is nil has no functional impact — there are simply no jokers to process during this state transition. --- lib/hooks.lua | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/hooks.lua b/lib/hooks.lua index 4f395aec..bc4ba7dc 100644 --- a/lib/hooks.lua +++ b/lib/hooks.lua @@ -1163,8 +1163,11 @@ function create_card(_type, area, legendary, _rarity, skip_materialize, soulable end end if card and card.ability and card.ability.consumeable then - for i, a in pairs(SMODS.get_card_areas('jokers')) do - for _, c in pairs(a.cards) do + local _joker_areas = SMODS.get_card_areas('jokers') + if _joker_areas then + for i, a in pairs(_joker_areas) do + if a.cards then + for _, c in pairs(a.cards) do if c.config.center.calculate then local ret = c.config.center:calculate(c, { get_consumable_type = true, @@ -1183,8 +1186,10 @@ function create_card(_type, area, legendary, _rarity, skip_materialize, soulable break end end + end end end + end end if card and card.ability and card.ability.consumeable then SMODS.calculate_context{entr_consumable_created = true, other_card = card} @@ -2157,14 +2162,19 @@ local add_tagref = add_tag function add_tag(_tag, ...) if type(_tag) == "table" then if not _tag.ability.added_to_deck then - for i, v in pairs(SMODS.get_card_areas('jokers')) do - for a, card in pairs(v.cards) do + local _joker_areas = SMODS.get_card_areas('jokers') + if _joker_areas then + for i, v in pairs(_joker_areas) do + if v.cards then + for a, card in pairs(v.cards) do local res = card:calculate_joker({tag_create = true, tag = _tag}) if res and res.tag then _tag = res.tag end + end end end + end end add_tagref(_tag, ...) _tag.ability.added_to_deck = true @@ -3119,13 +3129,18 @@ function Cryptid.get_interest(add_rows) local rate = Cryptid.interest_rate() local interest = math.min(math.floor(G.GAME.dollars / rate), G.GAME.interest_cap / 5) interest = interest * G.GAME.interest_amount - for _, a in pairs(SMODS.get_card_areas("jokers")) do - for i, c in pairs(a.cards) do + local _joker_areas = SMODS.get_card_areas("jokers") + if _joker_areas then + for _, a in pairs(_joker_areas) do + if a.cards then + for i, c in pairs(a.cards) do if c.config.center.cry_calc_interest then interest = c.config.center:cry_calc_interest(c, interest) end + end end end + end G.GAME.interest_cap = cap return interest end @@ -3901,4 +3916,4 @@ function Spectrallib.card_eval_status_text_eq(card, eval_type, amt, percent, dir return end orig_ref(card, eval_type, amt, percent, dir, extra, pref, col, sound, vol, ta) -end \ No newline at end of file +end