From cb2d3428027e3fcf1499c5ed6585980bff262177 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Sat, 22 Nov 2025 00:46:55 +0000 Subject: [PATCH] Fix Array into String conversion error in track_npc_encounters Changes: - Add player_state type checking before accessing encounteredNPCs - Reset player_state to empty hash if not a Hash type - Add comprehensive logging for type mismatches - Change from concat to array addition (+) to avoid in-place mutation issues - Wrap entire method in try-catch to prevent NPC tracking from breaking room loading - Add detailed error logging with stack traces Fixes: - TypeError: no implicit conversion of Array into String - Handles legacy data where player_state might be malformed - Room loading continues even if NPC tracking fails --- .../break_escape/games_controller.rb | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/app/controllers/break_escape/games_controller.rb b/app/controllers/break_escape/games_controller.rb index b6bd6ef..db86f31 100644 --- a/app/controllers/break_escape/games_controller.rb +++ b/app/controllers/break_escape/games_controller.rb @@ -317,23 +317,35 @@ module BreakEscape def track_npc_encounters(room_id, room_data) return unless room_data['npcs'].present? - npc_ids = room_data['npcs'].map { |npc| npc['id'] } + begin + npc_ids = room_data['npcs'].map { |npc| npc['id'] } - # Ensure encounteredNPCs is an array - @game.player_state['encounteredNPCs'] ||= [] + # Ensure player_state is a hash + unless @game.player_state.is_a?(Hash) + Rails.logger.error "[BreakEscape] player_state is not a Hash: #{@game.player_state.class}" + @game.player_state = {} + end - # Handle case where encounteredNPCs might be a string (legacy data) - unless @game.player_state['encounteredNPCs'].is_a?(Array) - @game.player_state['encounteredNPCs'] = [] + # Ensure encounteredNPCs is an array + @game.player_state['encounteredNPCs'] ||= [] + + # Handle case where encounteredNPCs might not be an array (legacy data) + unless @game.player_state['encounteredNPCs'].is_a?(Array) + Rails.logger.warn "[BreakEscape] encounteredNPCs is not an Array: #{@game.player_state['encounteredNPCs'].class}, resetting" + @game.player_state['encounteredNPCs'] = [] + end + + new_npcs = npc_ids - @game.player_state['encounteredNPCs'] + return if new_npcs.empty? + + @game.player_state['encounteredNPCs'] = (@game.player_state['encounteredNPCs'] + new_npcs).uniq + @game.save! + + Rails.logger.debug "[BreakEscape] Tracked NPC encounters: #{new_npcs.join(', ')}" + rescue => e + Rails.logger.error "[BreakEscape] Error tracking NPC encounters: #{e.message}\n#{e.backtrace.first(5).join("\n")}" + # Continue without tracking to avoid breaking room loading end - - new_npcs = npc_ids - @game.player_state['encounteredNPCs'] - return if new_npcs.empty? - - @game.player_state['encounteredNPCs'].concat(new_npcs) - @game.save! - - Rails.logger.debug "[BreakEscape] Tracked NPC encounters: #{new_npcs.join(', ')}" end def find_container_in_scenario(container_id)