diff --git a/Game_Manager.lsl b/Game_Manager.lsl index ce93b0d..82bebde 100644 --- a/Game_Manager.lsl +++ b/Game_Manager.lsl @@ -777,12 +777,13 @@ default { // IMMEDIATE FLOATER UPDATE: Update this player's floater right after their pick is saved // First sync the picks data so Floater Manager has the latest picks, then update the floater - llOwnerSay("🔄 [Game Manager] Syncing picks and updating floater immediately for " + playerName + " with new picks"); - // Send just the updated picks data to Floater Manager (lightweight sync) - string picksDataStr = llDumpList2String(picksData, "^"); - string lightSync = llList2CSV(lives) + "~" + picksDataStr + "~" + perilPlayer + "~" + llList2CSV(names); - llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, lightSync, NULL_KEY); + // MEMORY OPTIMIZED: Direct sync message construction + llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, + llList2CSV(lives) + "~" + + llDumpList2String(picksData, "^") + "~" + + perilPlayer + "~" + + llList2CSV(names), NULL_KEY); // Brief delay to ensure sync reaches Floater Manager before update request llSleep(0.1); @@ -790,7 +791,6 @@ default { // Now update the floater llMessageLinked(LINK_SET, MSG_UPDATE_FLOAT, playerName, llList2Key(players, idx)); - // Don't do full sync to Main here - it creates loops, but targeted floater update is safe llSleep(HUMAN_PICK_DELAY); // Move to next picker @@ -926,12 +926,13 @@ default { // IMMEDIATE FLOATER UPDATE: Update this bot's floater right after their pick is saved // First sync the picks data so Floater Manager has the latest picks, then update the floater - llOwnerSay("🔄 [Game Manager] Syncing picks and updating floater immediately for " + playerName + " (bot) with new picks"); - // Send just the updated picks data to Floater Manager (lightweight sync) - string picksDataStr = llDumpList2String(picksData, "^"); - string lightSync = llList2CSV(lives) + "~" + picksDataStr + "~" + perilPlayer + "~" + llList2CSV(names); - llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, lightSync, NULL_KEY); + // MEMORY OPTIMIZED: Direct sync message construction + llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, + llList2CSV(lives) + "~" + + llDumpList2String(picksData, "^") + "~" + + perilPlayer + "~" + + llList2CSV(names), NULL_KEY); // Brief delay to ensure sync reaches Floater Manager before update request llSleep(0.1); diff --git a/Main_Controller_Linkset.lsl b/Main_Controller_Linkset.lsl index b9a6c81..d34a21c 100644 --- a/Main_Controller_Linkset.lsl +++ b/Main_Controller_Linkset.lsl @@ -658,18 +658,13 @@ default { } } - // CRITICAL: Send sync message with 0 lives so floater shows elimination state - // Build sync message BEFORE any list modifications to prevent corruption - string livesStr = llList2CSV(lives); - string picksStr = llDumpList2String(picksData, "^"); - if (picksStr == "") picksStr = "EMPTY"; // Prevent empty string - string perilStr = perilPlayer; - if (perilStr == "") perilStr = "NONE"; // Prevent empty string - string namesStr = llList2CSV(names); - string playersStr = llList2CSV(players); - - string eliminationSync = livesStr + "~" + picksStr + "~" + perilStr + "~" + namesStr + "~" + playersStr; - llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, eliminationSync, NULL_KEY); + // Build sync message WITHOUT redundant player keys (5th part) to save memory + // Combined into single message to avoid multiple temporary string allocations + llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, + llList2CSV(lives) + "~" + + (string)llDumpList2String(picksData, "^") + "~" + + (string)llList2String([perilPlayer, "NONE"], (perilPlayer == "")) + "~" + + llList2CSV(names), NULL_KEY); // Direct floater update to ensure eliminated status is displayed llMessageLinked(LINK_SET, MSG_UPDATE_FLOAT, eliminatedPlayer, llList2Key(players, idx)); @@ -786,10 +781,10 @@ default { // CRITICAL: After elimination, sync state and continue game with new peril player if (perilPlayer != "" && perilPlayer != "NONE") { - // Sync the updated game state to all modules (5-part format) - string picksDataStr = "EMPTY"; // Empty picks for new round - string gameSync = llList2CSV(lives) + "~" + picksDataStr + "~" + perilPlayer + "~" + llList2CSV(names) + "~" + llList2CSV(players); - llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, gameSync, NULL_KEY); + // Sync the updated game state to all modules (4-part format) + // Optimized to avoid large temporary string variables + llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, + llList2CSV(lives) + "~EMPTY~" + perilPlayer + "~" + llList2CSV(names), NULL_KEY); llSleep(0.5); // Give sync time to propagate // Continue the game with the new peril player - delegate to Game Manager @@ -1246,6 +1241,11 @@ default { } gameStarting = TRUE; + + // MEMORY OPTIMIZED: Clear stale lists as soon as game enters active phase + readyPlayers = []; + pendingRegistrations = []; + llSay(0, "⚡ ALL PARTICIPANTS READY! THE DEADLY PERIL DICE GAME BEGINS! ⚡"); integer actualPlayerCount = llGetListLength(names); diff --git a/Roll_ConfettiModule.lsl b/Roll_ConfettiModule.lsl index 5aacf5c..b5a820a 100644 --- a/Roll_ConfettiModule.lsl +++ b/Roll_ConfettiModule.lsl @@ -497,27 +497,19 @@ default { // Note: Win condition checking is handled by Main Controller after elimination - // IMPORTANT: After processing a roll, preserve the actual picks data that was used for validation - // These picks will be used by Game Manager for building complete avoidance lists - list encodedPicksData = []; - integer k; - for (k = 0; k < llGetListLength(picksData); k++) { - string entry = llList2String(picksData, k); - // Preserve the actual picks data that was used for validation - encodedPicksData += [entry]; - } // Validate perilPlayer is not empty before syncing string perilForSync = perilPlayer; if (perilForSync == "") { perilForSync = "NONE"; - llOwnerSay("⚠️ Roll Module: perilPlayer is empty, using NONE placeholder"); } - string gameSync = llList2CSV(lives) + "~" + llDumpList2String(encodedPicksData, "^") + "~" + perilForSync + "~" + llList2CSV(names); - llOwnerSay("📤 Roll module sending sync with peril player: " + perilForSync); - llOwnerSay("🔍 DEBUG - encodedPicksData: " + llDumpList2String(encodedPicksData, " | ")); - llOwnerSay("🔍 DEBUG - gameSync: " + gameSync); - llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, gameSync, NULL_KEY); + // MEMORY OPTIMIZED: Direct sync message construction to avoid temporary string allocations + // Uses 4-part format to remain compatible with Game Manager + llMessageLinked(LINK_SET, MSG_SYNC_GAME_STATE, + llList2CSV(lives) + "~" + + llDumpList2String(picksData, "^") + "~" + + perilForSync + "~" + + llList2CSV(names), NULL_KEY); llSleep(0.2); // Additional floater updates to ensure correct peril player display