6.9 KiB
Game Stats Panel Preservation - Implementation Guide
Problem
Interactive tasks that modify the sidebar can destroy the game stats panel, causing stats (XP, level, session time) to disappear during gameplay.
Root Cause
Tasks that use sidebar.innerHTML = ... or container.innerHTML = ... to inject UI elements destroy all existing sidebar children, including the game stats panel.
Solution Pattern
NEVER replace sidebar innerHTML. Always use specific elements for task UI.
Step-by-Step Fix for Any Interactive Task
1. Identify the Task Type
Check src/features/tasks/interactiveTaskManager.js for the task handler (e.g., createEdgeTask, createRhythmTask, createVideoStartTask, etc.)
2. Check for Sidebar Replacement
Look for patterns like:
// ❌ BAD - Destroys game stats panel
sidebar.innerHTML = `<div>...</div>`;
container.innerHTML = `<div class="sidebar-content">...</div>`;
3. Use Sidebar Timer Elements Instead
The campaign sidebar has these persistent elements:
#sidebar-countdown-timer- Wrapper div (show/hide withdisplay: block/none)#sidebar-countdown-display- Time text element (update with.textContent)#game-stats-panel- Stats panel (must always exist, never destroy)
// ✅ GOOD - Preserves game stats panel
const sidebarTimer = document.getElementById('sidebar-countdown-timer');
const sidebarDisplay = document.getElementById('sidebar-countdown-display');
if (sidebarTimer) {
sidebarTimer.style.display = 'block';
}
if (sidebarDisplay) {
sidebarDisplay.textContent = `${mins}:${secs.toString().padStart(2, '0')}`;
}
4. Add Logging for Debugging
When showing/hiding sidebar elements, add console logs to verify game stats panel persists:
const gameStatsPanel = document.getElementById('game-stats-panel');
console.log('🎯 TASK START - Stats panel element:', gameStatsPanel);
console.log('🎯 TASK START - Stats panel display BEFORE:', gameStatsPanel?.style.display);
// Show sidebar timer
if (sidebarTimer) {
sidebarTimer.style.display = 'block';
}
console.log('🎯 TASK START - Stats panel display AFTER:', gameStatsPanel?.style.display);
5. Hide Timer on Task Complete
Always hide the sidebar timer when task completes:
if (timeRemaining <= 0) {
clearInterval(timerInterval);
// Hide sidebar countdown timer
const sidebarTimer = document.getElementById('sidebar-countdown-timer');
if (sidebarTimer) {
sidebarTimer.style.display = 'none';
}
task.completed = true;
// ... rest of completion logic
}
Task-Specific Examples
Edge Task (Level 1)
File: interactiveTaskManager.js ~line 4660
Fixed Pattern:
// Don't create inline timer in HTML
// Use sidebar timer instead
const sidebarTimer = document.getElementById('sidebar-countdown-timer');
const sidebarDisplay = document.getElementById('sidebar-countdown-display');
if (sidebarTimer) sidebarTimer.style.display = 'block';
// Update timer in interval
timerInterval = setInterval(() => {
timeRemaining--;
const mins = Math.floor(timeRemaining / 60);
const secs = timeRemaining % 60;
if (sidebarDisplay) {
sidebarDisplay.textContent = `${mins}:${secs.toString().padStart(2, '0')}`;
}
if (timeRemaining <= 0) {
if (sidebarTimer) sidebarTimer.style.display = 'none';
// ... completion logic
}
}, 1000);
Rhythm Task (Level 2)
File: interactiveTaskManager.js ~line 4818
Issue: Was using sidebar.innerHTML = ... which destroyed game stats
Fixed Pattern:
// Don't do this:
// sidebar.innerHTML = `<div>Timer HTML</div>`;
// Do this instead:
const sidebarTimer = document.getElementById('sidebar-countdown-timer');
const sidebarDisplay = document.getElementById('sidebar-countdown-display');
if (sidebarTimer) sidebarTimer.style.display = 'block';
if (sidebarDisplay) sidebarDisplay.textContent = timeString;
Video Start Task (Level 3)
File: interactiveTaskManager.js - Need to check implementation
Pattern to Apply:
- Find
createVideoStartTaskfunction - Look for any
sidebar.innerHTMLorcontainer.innerHTMLpatterns - Replace with sidebar timer element usage
- Add logging to verify stats panel persists
- Ensure timer hides on completion
Verification Checklist
When implementing the fix for any task:
- Task does NOT use
sidebar.innerHTML = ... - Task does NOT use
container.innerHTML = ...that affects sidebar - Task uses
#sidebar-countdown-timerand#sidebar-countdown-displayelements - Task shows timer:
sidebarTimer.style.display = 'block' - Task updates display:
sidebarDisplay.textContent = timeString - Task hides timer on complete:
sidebarTimer.style.display = 'none' - Logging added to track game stats panel visibility
- Tested in-game to verify stats panel stays visible throughout task
Common Task Types to Fix
- video-start - Video playback with timer
- tag-files - File tagging interface
- slideshow - Image slideshow with timer
- dual-video - Dual video display
- quad-video - Quad video display
- webcam-mirror - Webcam display tasks
- Any task with
durationorshowTimer: trueparams
Files Involved
- Task Implementation:
src/features/tasks/interactiveTaskManager.js - Sidebar HTML:
campaign.html(lines ~1270-1290) - XP Display Update:
campaign.html(lines ~6815-6825) - Level Start Logic:
campaign.html(lines ~4129-4137)
Reference: Sidebar Structure in campaign.html
<div id="campaign-sidebar" class="campaign-sidebar">
<!-- Game Stats Panel - MUST ALWAYS EXIST -->
<div id="game-stats-panel" class="game-stats-panel" style="display: block;">
<div class="stat-item">
<span class="stat-label">XP:</span>
<span id="sidebar-current-xp" class="stat-value">0</span>
</div>
<div class="stat-item">
<span class="stat-label">Session:</span>
<span id="sidebar-session-time" class="stat-value">0:00</span>
</div>
<div class="stat-item">
<span class="stat-label">Level:</span>
<span id="sidebar-current-level" class="stat-value">1</span>
</div>
</div>
<!-- Timer Panel - Show/hide as needed -->
<div id="sidebar-countdown-timer" style="display: none;">
<div class="timer-label">Time Remaining:</div>
<div id="sidebar-countdown-display" class="timer-display">0:00</div>
</div>
</div>
Key Takeaway
If your task has a timer and shows it in the sidebar:
- Use
#sidebar-countdown-timer(show/hide wrapper) - Use
#sidebar-countdown-display(update text content) - NEVER replace
sidebar.innerHTML - Always hide timer on task completion
This preserves the game stats panel and prevents the "disappearing stats" bug.