Sandbox Mode is a new feature that allows developers and testers to create controlled environments where specific game systems are disabled at the engine level.
+
+
+
โ Disable wave spawning system
+
โ Disable weather effects
+
โ Disable UI updates
+
โ Disable audio playback
+
โ Prevent automatic game over
+
โ Maintain full backward compatibility
+
+
+
+
+
How It Works
+
+
Normal Game (Unchanged)
+
// All systems active, game behaves normally
+const game = new Game();
+
+
Sandbox Mode (New)
+
// Wave, weather, UI, audio disabled
+// No game over on player death
+const game = new Game({ sandboxMode: true });
+
+
+
+
Before vs After
+
+
+
+
โ Old Way (Manual)
+
// Create game
+const game = new Game();
+
+// Manually disable each system
+game.systems.wave.update = () => {};
+game.systems.weather.update = () => {};
+game.systems.ui.update = () => {};
+game.audioManager.play = () => {};
+game.audioManager.stopAll = () => {};
+
+// Override methods on prototype
+Game.prototype.setupUIListeners =
+ function() { /* disabled */ };
+
+// Still had game over issues
+// Inconsistent across sandboxes
+
+
+
+
โ New Way (Clean)
+
// One line, everything handled
+const game = new Game({
+ sandboxMode: true
+});
+
+// That's it!
+// Systems disabled at engine level
+// Game over prevented
+// Consistent behavior
+// Backward compatible
// Initialize the sandbox
function init() {
- console.log('[Combat Sandbox] Initializing with real Game class...');
+ console.log('[Combat Sandbox] Initializing with sandboxMode...');
// Override setupUIListeners on prototype before instantiation
// This prevents errors with missing UI DOM elements
@@ -239,42 +239,21 @@
Info
console.log('[Combat Sandbox] UI listeners disabled (prototype override)');
};
- // Create the real Game instance
- game = new Game();
+ // Create the real Game instance with sandboxMode enabled
+ // This cleanly disables wave spawning, weather, UI updates, and audio at engine level
+ game = new Game({ sandboxMode: true });
- // Disable WaveSystem before starting
- if (game.systems.wave) {
- console.log('[Combat Sandbox] Disabling WaveSystem');
- game.systems.wave.update = function() {};
- game.systems.wave.spawnWave = function() {};
- }
-
- // Disable UISystem before starting
+ // Override additional UI methods that try to access DOM elements
+ // These are called by the game but reference elements that don't exist in sandbox
if (game.systems.ui) {
- console.log('[Combat Sandbox] Disabling UISystem');
- game.systems.ui.update = function() {};
game.systems.ui.updateHUD = function() {};
game.systems.ui.showScreen = function() {};
game.systems.ui.showWaveAnnouncement = function() {};
game.systems.ui.showLevelUp = function() {};
game.systems.ui.showGameOver = function() {};
+ console.log('[Combat Sandbox] UI methods overridden to prevent DOM errors');
}
-
- // Disable AudioManager before starting
- if (game.audioManager) {
- console.log('[Combat Sandbox] Disabling AudioManager');
- game.audioManager.init = function() {};
- game.audioManager.play = function() {};
- game.audioManager.playSound = function() {};
- game.audioManager.playMusic = function() {};
- game.audioManager.stopAll = function() {};
- game.audioManager.stopMusic = function() {};
- game.audioManager.update = function() {};
- game.audioManager.setVolume = function() {};
- game.audioManager.startBackgroundMusic = function() {};
- game.audioManager.stopBackgroundMusic = function() {};
- }
-
+
// Set selected ship
game.gameState.selectedShip = 'ION_FRIGATE';
diff --git a/js/Game.js b/js/Game.js
index c6e9011..bc9047c 100644
--- a/js/Game.js
+++ b/js/Game.js
@@ -59,7 +59,8 @@ const DEFAULT_STATS = {
};
class Game {
- constructor() {
+ constructor(options = {}) {
+ this.sandboxMode = options.sandboxMode === true;
this.canvas = document.getElementById('gameCanvas');
this.ctx = this.canvas.getContext('2d');
@@ -179,6 +180,32 @@ class Game {
// Setup UI event listeners
this.setupUIListeners();
+ // Apply sandbox mode if enabled
+ if (this.sandboxMode) {
+ logger.info('Game', 'Sandbox mode enabled');
+
+ // Disable wave spawning
+ if (this.systems.wave) {
+ this.systems.wave.update = () => {};
+ }
+
+ // Disable weather
+ if (this.systems.weather) {
+ this.systems.weather.update = () => {};
+ }
+
+ // Disable UI updates
+ if (this.systems.ui) {
+ this.systems.ui.update = () => {};
+ }
+
+ // Disable audio
+ if (this.audioManager) {
+ this.audioManager.play = () => {};
+ this.audioManager.stopAll = () => {};
+ }
+ }
+
// Start in menu
this.gameState.setState(GameStates.MENU);
this.systems.ui.showScreen('menu');
@@ -414,7 +441,9 @@ class Game {
// Reset systems
this.systems.spawner.reset();
this.systems.render.reset();
- this.systems.wave.reset();
+ if (!this.sandboxMode) {
+ this.systems.wave.reset();
+ }
this.systems.weather.reset();
this.screenEffects.reset();
@@ -1333,8 +1362,10 @@ class Game {
}
// Check for game over with defense system
- if (defense && defense.structure.current <= 0) {
- this.gameOver();
+ if (!this.sandboxMode) {
+ if (defense && defense.structure.current <= 0) {
+ this.gameOver();
+ }
}
}
diff --git a/test-sandbox-mode.html b/test-sandbox-mode.html
new file mode 100644
index 0000000..17b4dbc
--- /dev/null
+++ b/test-sandbox-mode.html
@@ -0,0 +1,298 @@
+
+
+
+
+
+ Sandbox Mode Test
+
+
+
+
๐ฎ Sandbox Mode Test
+
+
+
Test 1: Normal Game Instantiation
+
+
+
+ Expected: sandboxMode should be false, systems should be active
+
+
+
+
+
Test 2: Sandbox Mode Enabled
+
+
+
+ Expected: sandboxMode should be true, systems should be disabled, console message logged
+
+
+
+
+
Test 3: Sandbox Mode Explicitly False
+
+
+
+ Expected: sandboxMode should be false, systems should be active
+
+
+
+
+
Test 4: Other Options Ignored
+
+
+
+ Expected: sandboxMode should be false, other options should not affect behavior
+