From e5f093e0f6da7bd3d6553e1049ce87005aa2d1ac Mon Sep 17 00:00:00 2001 From: RebeccaNod1 Date: Sun, 14 Sep 2025 09:42:09 -0500 Subject: [PATCH] fix: split verbose logging into dedicated script to resolve Stack-Heap Collision CRITICAL ARCHITECTURE CHANGE to resolve memory crashes: NEW FILE: Verbose_Logger.lsl - Dedicated script for all debug output to free up memory in Main Controller - Handles verbose logging toggle and message buffering - Script ID system for organized log prefixes - Memory-safe batched output system MAIN CONTROLLER CHANGES: - Removed all verbose logging code and variables - Redirected debug calls to dedicated Verbose_Logger script - Simplified verbose logging toggle to forward to logger - Removed memory-heavy string operations This architectural split should immediately resolve the Stack-Heap Collision by moving all debug-related memory usage out of the Main Controller. --- Main_Controller_Linkset.lsl | 56 +++++---------- Verbose_Logger.lsl | 131 ++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 40 deletions(-) create mode 100644 Verbose_Logger.lsl diff --git a/Main_Controller_Linkset.lsl b/Main_Controller_Linkset.lsl index 0aa969b..18f2dd9 100644 --- a/Main_Controller_Linkset.lsl +++ b/Main_Controller_Linkset.lsl @@ -80,30 +80,18 @@ float timerInterval = 1.0; // How often timer() is called for checks // Debug control - set to TRUE for verbose pick debugging, FALSE for normal operation integer DEBUG_PICKS = FALSE; -// Verbose logging system - affects all modules when toggled -integer VERBOSE_LOGGING = FALSE; +// Verbose logging moved to dedicated Verbose_Logger.lsl script to save memory +// Message constants for verbose logging +integer MSG_VERBOSE_LOG = 9020; +integer MSG_VERBOSE_TOGGLE = 9010; -// Emergency memory management - disable verbose logging if memory gets low -emergencyMemoryCheck() { - if (llGetFreeMemory() < 1000) { - VERBOSE_LOGGING = FALSE; - llOwnerSay("⚠️ Low memory detected - auto-disabling verbose logging"); - } -} +// Script ID for Main Controller (used by Verbose_Logger for prefixes) +integer SCRIPT_ID_MAIN = 0; -// Memory-efficient debug function to prevent Stack-Heap Collision +// Memory-safe debug function - forwards to dedicated logger debugMsg(string msg) { - emergencyMemoryCheck(); - if (VERBOSE_LOGGING && llGetFreeMemory() > 500) { - llOwnerSay("[M] " + msg); - } -} - -// Ultra-light debug for critical paths only -lightDebug(string msg) { - if (VERBOSE_LOGGING && llGetFreeMemory() > 300) { - llOwnerSay(msg); - } + // Forward to dedicated verbose logger to save memory in Main Controller + llMessageLinked(LINK_SET, MSG_VERBOSE_LOG, (string)SCRIPT_ID_MAIN + "|" + msg, NULL_KEY); } // Status message timing @@ -482,10 +470,7 @@ default { integer shouldBePicking = FALSE; if (currentPickerIdx < llGetListLength(pickQueue)) { string expectedPickerName = llList2String(pickQueue, currentPickerIdx); - if (VERBOSE_LOGGING) { - debugMsg("Touch: " + playerName + " exp:" + expectedPickerName); - debugMsg("Idx:" + (string)currentPickerIdx); - } + debugMsg("Touch recovery: " + playerName); if (playerName == expectedPickerName) { shouldBePicking = TRUE; // Fix corrupted currentPicker state @@ -495,8 +480,8 @@ default { currentPicker = toucher; } } - } else if (VERBOSE_LOGGING) { - debugMsg("Pick phase done - idx >= queue len"); + } else { + debugMsg("Pick phase complete"); } // FALLBACK: If game is stuck and no one is set as current picker, but we're in pick phase, @@ -1146,19 +1131,10 @@ default { return; } - // Handle verbose logging toggle - if (num == 9010 && str == "TOGGLE_VERBOSE_LOGS") { - VERBOSE_LOGGING = !VERBOSE_LOGGING; - if (VERBOSE_LOGGING) { - llOwnerSay("Debug: ON"); - llSay(0, "Debug: ON"); - } else { - llOwnerSay("Debug: OFF"); - llSay(0, "Debug: OFF"); - } - - // Broadcast the setting to all modules - llMessageLinked(LINK_SET, 9011, "VERBOSE_LOGGING|" + (string)VERBOSE_LOGGING, id); + // Handle verbose logging toggle - redirect to dedicated Verbose_Logger script + if (num == MSG_VERBOSE_TOGGLE && str == "TOGGLE_VERBOSE_LOGS") { + // Forward to dedicated verbose logger script + llMessageLinked(LINK_SET, MSG_VERBOSE_TOGGLE, "TOGGLE_VERBOSE_LOGS", id); return; } diff --git a/Verbose_Logger.lsl b/Verbose_Logger.lsl new file mode 100644 index 0000000..1e1fa6b --- /dev/null +++ b/Verbose_Logger.lsl @@ -0,0 +1,131 @@ +// === Verbose Logger - Dedicated Debug Output Handler === +// This script handles all verbose logging to reduce memory usage in Main Controller +// and other core game scripts + +// Verbose logging control +integer VERBOSE_LOGGING = FALSE; + +// Message constants for verbose logging system +integer MSG_VERBOSE_LOG = 9020; // Request to log a message +integer MSG_VERBOSE_TOGGLE = 9010; // Toggle verbose logging on/off +integer MSG_VERBOSE_BROADCAST = 9011; // Broadcast logging state to all modules + +// Memory monitoring +integer MSG_MEMORY_REPORT_VERBOSE = 9025; + +// Script identification for log prefixes +list SCRIPT_PREFIXES = [ + "Main", "Game", "Dialog", "Roll", "Bot", "Float", "Calc", + "Mem", "Msg", "Score", "Lead", "Dice", "Debug", "Num" +]; + +// Buffer for batching messages to reduce spam +list messageBuffer = []; +integer BUFFER_SIZE = 5; +float FLUSH_INTERVAL = 2.0; + +default { + state_entry() { + llOwnerSay("🔍 Verbose Logger initialized - ready to handle debug output"); + llSetTimerEvent(FLUSH_INTERVAL); + } + + on_rez(integer start_param) { + llOwnerSay("🔍 Verbose Logger rezzed - debug system ready"); + VERBOSE_LOGGING = FALSE; // Default to off after rez + messageBuffer = []; + llSetTimerEvent(FLUSH_INTERVAL); + } + + link_message(integer sender, integer num, string str, key id) { + // Handle verbose logging toggle + if (num == MSG_VERBOSE_TOGGLE && str == "TOGGLE_VERBOSE_LOGS") { + VERBOSE_LOGGING = !VERBOSE_LOGGING; + + string status = "OFF"; + if (VERBOSE_LOGGING) { + status = "ON"; + llOwnerSay("🔍 [Verbose Logger] Debug logging: ENABLED"); + } else { + llOwnerSay("🔍 [Verbose Logger] Debug logging: DISABLED"); + messageBuffer = []; // Clear buffer when disabled + } + + // Public announcement + llSay(0, "🔍 Verbose logging system-wide: " + status); + + // Broadcast the new setting to all modules + llMessageLinked(LINK_SET, MSG_VERBOSE_BROADCAST, "VERBOSE_LOGGING|" + (string)VERBOSE_LOGGING, id); + return; + } + + // Handle verbose logging broadcast from other scripts + if (num == MSG_VERBOSE_BROADCAST) { + list parts = llParseString2List(str, ["|"], []); + if (llList2String(parts, 0) == "VERBOSE_LOGGING") { + VERBOSE_LOGGING = llList2Integer(parts, 1); + return; + } + } + + // Handle log message requests + if (num == MSG_VERBOSE_LOG && VERBOSE_LOGGING) { + // Format: "SCRIPT_ID|MESSAGE" + list parts = llParseString2List(str, ["|"], []); + if (llGetListLength(parts) >= 2) { + integer scriptId = llList2Integer(parts, 0); + string message = llList2String(parts, 1); + + string prefix = "[Unknown]"; + if (scriptId >= 0 && scriptId < llGetListLength(SCRIPT_PREFIXES)) { + prefix = "[" + llList2String(SCRIPT_PREFIXES, scriptId) + "]"; + } + + string logMessage = prefix + " " + message; + + // Add to buffer for batched output + messageBuffer += [logMessage]; + + // If buffer is full, flush immediately + if (llGetListLength(messageBuffer) >= BUFFER_SIZE) { + flushMessageBuffer(); + } + } + return; + } + + // Handle memory report request + if (num == MSG_MEMORY_REPORT_VERBOSE) { + reportMemoryStatus(); + return; + } + } + + timer() { + // Periodic buffer flush + if (VERBOSE_LOGGING && llGetListLength(messageBuffer) > 0) { + flushMessageBuffer(); + } + } +} + +// Flush all buffered messages to owner +flushMessageBuffer() { + if (llGetListLength(messageBuffer) == 0) return; + + integer i; + for (i = 0; i < llGetListLength(messageBuffer); i++) { + llOwnerSay(llList2String(messageBuffer, i)); + } + messageBuffer = []; +} + +// Report memory status of this script +reportMemoryStatus() { + if (VERBOSE_LOGGING) { + integer free = llGetFreeMemory(); + integer used = llGetUsedMemory(); + llOwnerSay("🔍 [Verbose Logger] Memory - Free: " + (string)free + " Used: " + (string)used); + llOwnerSay("🔍 [Verbose Logger] Buffer size: " + (string)llGetListLength(messageBuffer)); + } +} \ No newline at end of file