This repository has been archived on 2026-05-04. You can view files and clone it, but cannot push or open issues or pull requests.
Galaxy-Strike-Online/Client-Server/js/core/GameEngine.js

1568 lines
71 KiB
JavaScript

/**
* Galaxy Strike Online - Game Engine
* Core game loop and state management
*/
class GameEngine extends EventTarget {
constructor() {
super(); // Call EventTarget constructor first
console.log('🛑 DEBUG STOP 1: GameEngine constructor starting');
const debugLogger = window.debugLogger;
if (debugLogger) debugLogger.log('GameEngine constructor called', {
autoSaveInterval: 5,
timestamp: new Date().toISOString()
});
this.isRunning = false;
this.lastUpdate = 0;
this.gameTime = 0;
// Auto-save settings
this.autoSaveInterval = 1; // Default 1 minute
this.autoSaveTimer = null;
this.lastAutoSave = 0;
// Save slot information
this.saveSlotInfo = {
slot: 1, // Default save slot
useFileSystem: !!window.electronAPI // Use file system if Electron API is available
};
console.log('🛑 DEBUG STOP 2: Save slot info initialized:', this.saveSlotInfo);
// GUI update settings
this.guiUpdateInterval = 1000; // Update GUI once per second (1000ms)
this.lastGUIUpdate = 0;
// Game logic settings (independent of frame rate)
this.gameLogicInterval = 1000; // Update game logic every 1 second
this.gameLogicTimer = null;
// Game state
this.state = {
paused: false,
currentTab: 'dashboard',
notifications: [],
loading: true
};
console.log('🛑 DEBUG STOP 3: Game state initialized:', this.state);
// Systems
this.systems = {};
// Event listeners
this.eventListeners = new Map();
console.log('🛑 DEBUG STOP 4: About to call this.init()');
this.init();
console.log('🛑 DEBUG STOP 5: GameEngine constructor completed');
}
setMultiplayerMode(isMultiplayer, socket = null, serverData = null, currentUser = null) {
const debugLogger = window.debugLogger;
console.log('[GAME ENGINE] Setting multiplayer mode:', isMultiplayer);
if (debugLogger) debugLogger.logStep('setMultiplayerMode', { isMultiplayer });
this.isMultiplayer = isMultiplayer;
this.socket = socket;
this.serverData = serverData;
this.currentUser = currentUser;
// Store multiplayer settings for systems that need them
this.multiplayerConfig = {
isMultiplayer,
socket,
serverData,
currentUser
};
console.log('[GAME ENGINE] Multiplayer mode configured:', {
isMultiplayer,
hasSocket: !!socket,
hasServerData: !!serverData,
hasCurrentUser: !!currentUser
});
}
// Get random integer between min and max (inclusive)
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Get random float between min and max
getRandomFloat(min, max) {
return Math.random() * (max - min) + min;
}
async init() {
console.log('[GAME ENGINE] Initializing game engine');
const logger = window.logger;
const debugLogger = window.debugLogger;
if (logger) await logger.info('Initializing game engine');
if (debugLogger) await debugLogger.startStep('gameEngineInit');
try {
// Initialize core systems but don't setup new game data
await this.initializeSystemsForLoad();
if (debugLogger) await debugLogger.logStep('Systems initialized, setting up event listeners');
// Set up event listeners
await this.setupEventListeners();
if (debugLogger) await debugLogger.logStep('Event listeners setup complete');
if (logger) await logger.info('Game engine initialization completed');
if (debugLogger) await debugLogger.endStep('gameEngineInit', {
systemsInitialized: Object.keys(this.systems).length,
eventListeners: this.eventListeners.size
});
} catch (error) {
console.error('Failed to initialize game:', error);
if (logger) await logger.errorEvent(error, 'Game Engine Initialization');
if (debugLogger) await debugLogger.errorEvent(error, 'Game Engine Initialization');
}
}
async startGame(continueGame = false) {
const logger = window.logger;
const debugLogger = window.debugLogger;
console.log('[GAME ENGINE] startGame called with continueGame =', continueGame);
if (logger) await logger.info('Starting game', { continueGame });
if (debugLogger) await debugLogger.startStep('startGame', { continueGame });
try {
if (continueGame) {
console.log('[GAME ENGINE] Loading existing save data...');
if (debugLogger) await debugLogger.logStep('Loading existing save data');
await this.loadGame();
console.log('[GAME ENGINE] Save data loaded');
} else {
console.log('[GAME ENGINE] Creating new game...');
if (debugLogger) await debugLogger.logStep('Creating new game');
await this.newGame();
console.log('[GAME ENGINE] New game created');
}
// Start game loop
// CRITICAL: Ensure UIManager is initialized before starting game
if (this.systems.ui) {
console.log('[GAME ENGINE] Final UIManager initialization check...');
try {
await this.systems.ui.initialize();
console.log('[GAME ENGINE] UIManager initialized successfully');
} catch (error) {
console.error('[GAME ENGINE] UIManager initialization failed:', error);
}
}
this.start();
console.log('[GAME ENGINE] Game loop started');
if (debugLogger) await debugLogger.logStep('Game loop started');
const loadingStatus = document.getElementById('loadingStatus');
if (loadingStatus) {
console.log('[GAME ENGINE] Hiding loading status text');
if (debugLogger) await debugLogger.logStep('Hiding loading status text');
loadingStatus.classList.add('hidden');
}
const gameInterface = document.getElementById('gameInterface');
if (gameInterface) {
console.log('[GAME ENGINE] Showing game interface');
if (debugLogger) await debugLogger.logStep('Showing game interface');
gameInterface.classList.remove('hidden');
// CRITICAL: Initialize UIManager after showing interface
console.log('[GAME ENGINE] Initializing UIManager after showing interface...');
if (this.systems.ui) {
try {
await this.systems.ui.initialize();
console.log('[GAME ENGINE] UIManager initialized successfully (post-interface)');
} catch (error) {
console.error('[GAME ENGINE] UIManager initialization failed:', error);
}
} else {
console.log('[GAME ENGINE] UIManager not found when trying to initialize after interface');
}
} else {
console.warn('[GAME ENGINE] gameInterface element not found');
if (debugLogger) await debugLogger.warn('gameInterface element not found');
}
if (logger) await logger.info('Game started successfully');
if (debugLogger) await debugLogger.endStep('startGame', {
continueGame,
isRunning: this.isRunning,
gameTime: this.gameTime
});
} catch (error) {
console.error('[GAME ENGINE] Failed to start game:', error);
if (logger) await logger.errorEvent(error, 'Game Start');
if (debugLogger) await debugLogger.errorEvent(error, 'Game Start');
}
}
async initializeSystemsForLoad() {
const logger = window.logger;
const debugLogger = window.debugLogger;
if (debugLogger) await debugLogger.startStep('initializeSystemsForLoad');
if (logger) {
await logger.timeAsync('Game Systems Initialization for Load', async () => {
await logger.info('Initializing game systems for loading');
if (debugLogger) await debugLogger.logStep('Initializing TextureManager');
// Initialize texture manager first
this.systems.textureManager = new TextureManager(this);
if (logger) await logger.systemEvent('TextureManager', 'Initialized');
if (debugLogger) await debugLogger.logStep('TextureManager initialized');
if (debugLogger) await debugLogger.logStep('Creating Player system (without initialization)');
// Create systems but don't initialize with default data
this.systems.player = new Player(this);
if (logger) await logger.systemEvent('Player', 'Created');
if (debugLogger) await debugLogger.logStep('Player system created');
if (debugLogger) await debugLogger.logStep('Creating Inventory system (without initialization)');
this.systems.inventory = new Inventory(this);
if (logger) await logger.systemEvent('Inventory', 'Created');
if (debugLogger) await debugLogger.logStep('Inventory system created');
if (debugLogger) await debugLogger.logStep('Creating Economy system (without initialization)');
this.systems.economy = new Economy(this);
if (logger) await logger.systemEvent('Economy', 'Created');
if (debugLogger) await debugLogger.logStep('Economy system created');
if (debugLogger) await debugLogger.logStep('Creating IdleSystem');
this.systems.idleSystem = new IdleSystem(this);
if (logger) await logger.systemEvent('IdleSystem', 'Created');
if (debugLogger) await debugLogger.logStep('IdleSystem created');
if (debugLogger) await debugLogger.logStep('Creating DungeonSystem');
this.systems.dungeonSystem = new DungeonSystem(this);
if (logger) await logger.systemEvent('DungeonSystem', 'Created');
if (debugLogger) await debugLogger.logStep('DungeonSystem created');
if (debugLogger) await debugLogger.logStep('Creating SkillSystem');
this.systems.skillSystem = new SkillSystem(this);
if (logger) await logger.systemEvent('SkillSystem', 'Created');
if (debugLogger) await debugLogger.logStep('SkillSystem created');
if (debugLogger) await debugLogger.logStep('Creating BaseSystem');
this.systems.baseSystem = new BaseSystem(this);
if (logger) await logger.systemEvent('BaseSystem', 'Created');
if (debugLogger) await debugLogger.logStep('BaseSystem created');
if (debugLogger) await debugLogger.logStep('Creating QuestSystem');
this.systems.questSystem = new QuestSystem(this);
if (logger) await logger.systemEvent('QuestSystem', 'Created');
if (debugLogger) await debugLogger.logStep('QuestSystem created');
if (debugLogger) await debugLogger.logStep('Creating ShipSystem');
this.systems.shipSystem = new ShipSystem(this);
if (logger) await logger.systemEvent('ShipSystem', 'Created');
if (debugLogger) await debugLogger.logStep('ShipSystem created');
if (debugLogger) await debugLogger.logStep('Creating UIManager');
if (typeof UIManager !== 'undefined') {
console.log('[GAME ENGINE] UIManager class found, creating real UIManager');
this.systems.ui = new UIManager(this);
// Expose UIManager globally for button onclick handlers
window.uiManager = this.systems.ui;
window.game.systems.ui = this.systems.ui;
if (logger) await logger.systemEvent('UIManager', 'Created');
if (debugLogger) await debugLogger.logStep('UIManager created and exposed');
} else {
console.error('[GAME ENGINE] UIManager class not found - this should not happen!');
if (debugLogger) await debugLogger.error('UIManager class not found - this should not happen!');
// Create minimal UI system to prevent crashes (should never be needed based on logs)
this.systems.ui = {
showNotification: (message, type, duration) => {
console.log(`[UI MINIMAL] ${type}: ${message}`);
},
updateUI: () => {
console.log('[UI MINIMAL] updateUI called');
},
switchTab: (tabName) => {
console.log('[UI MINIMAL] switchTab called');
}
};
}
if (debugLogger) await debugLogger.logStep('Creating CraftingSystem');
this.systems.crafting = new CraftingSystem(this);
if (logger) await logger.systemEvent('CraftingSystem', 'Created');
if (debugLogger) await debugLogger.logStep('CraftingSystem created');
if (debugLogger) await debugLogger.endStep('initializeSystemsForLoad', {
systemsCreated: Object.keys(this.systems).length
});
});
}
}
async initializeSystems() {
const logger = window.logger;
const debugLogger = window.debugLogger;
if (debugLogger) await debugLogger.startStep('initializeSystems');
if (logger) {
await logger.timeAsync('Game Systems Initialization', async () => {
await logger.info('Initializing game systems');
if (debugLogger) await debugLogger.logStep('Initializing TextureManager');
// Initialize texture manager first
this.systems.textureManager = new TextureManager(this);
if (logger) await logger.systemEvent('TextureManager', 'Initialized');
if (debugLogger) await debugLogger.logStep('TextureManager initialized');
if (debugLogger) await debugLogger.logStep('Initializing Player system');
// Initialize in dependency order
this.systems.player = new Player(this);
if (logger) await logger.systemEvent('Player', 'Initialized');
if (debugLogger) await debugLogger.logStep('Player system initialized', {
playerLevel: this.systems.player.stats.level,
playerExperience: this.systems.player.stats.experience
});
if (debugLogger) await debugLogger.logStep('Initializing Inventory system');
this.systems.inventory = new Inventory(this);
if (logger) await logger.systemEvent('Inventory', 'Initialized');
if (debugLogger) await debugLogger.logStep('Inventory system initialized', {
inventorySize: this.systems.inventory.items.length
});
if (debugLogger) await debugLogger.logStep('Initializing Economy system');
this.systems.economy = new Economy(this);
if (logger) await logger.systemEvent('Economy', 'Initialized');
if (debugLogger) await debugLogger.logStep('Economy system initialized', {
credits: this.systems.economy.credits,
gems: this.systems.economy.gems
});
if (debugLogger) await debugLogger.logStep('Initializing IdleSystem');
this.systems.idleSystem = new IdleSystem(this);
if (logger) await logger.systemEvent('IdleSystem', 'Initialized');
if (debugLogger) await debugLogger.logStep('IdleSystem initialized');
if (debugLogger) await debugLogger.logStep('Initializing DungeonSystem');
this.systems.dungeonSystem = new DungeonSystem(this);
if (logger) await logger.systemEvent('DungeonSystem', 'Initialized');
if (debugLogger) await debugLogger.logStep('DungeonSystem initialized');
if (debugLogger) await debugLogger.logStep('Initializing SkillSystem');
this.systems.skillSystem = new SkillSystem(this);
if (logger) await logger.systemEvent('SkillSystem', 'Initialized');
if (debugLogger) await debugLogger.logStep('SkillSystem initialized');
if (debugLogger) await debugLogger.logStep('Initializing BaseSystem');
this.systems.baseSystem = new BaseSystem(this);
if (logger) await logger.systemEvent('BaseSystem', 'Initialized');
if (debugLogger) await debugLogger.logStep('BaseSystem initialized');
if (debugLogger) await debugLogger.logStep('Initializing QuestSystem');
this.systems.questSystem = new QuestSystem(this);
await this.systems.questSystem.initialize();
if (logger) await logger.systemEvent('QuestSystem', 'Initialized');
if (debugLogger) await debugLogger.logStep('QuestSystem initialized');
if (debugLogger) await debugLogger.logStep('Initializing ShipSystem');
this.systems.ship = new ShipSystem(this);
if (logger) await logger.systemEvent('ShipSystem', 'Initialized');
if (debugLogger) await debugLogger.logStep('ShipSystem initialized');
if (debugLogger) await debugLogger.logStep('UIManager already initialized in initializeSystemsForLoad');
if (debugLogger) await debugLogger.logStep('Initializing CraftingSystem');
this.systems.crafting = new CraftingSystem(this);
if (logger) await logger.systemEvent('CraftingSystem', 'Initialized');
if (debugLogger) await debugLogger.logStep('CraftingSystem initialized');
if (logger) await logger.info('All game systems initialized');
if (debugLogger) await debugLogger.logStep('All systems created, running individual initializations');
if (debugLogger) await debugLogger.logStep('Running individual system initializations');
for (const [name, system] of Object.entries(this.systems)) {
if (system.initialize) {
if (debugLogger) await debugLogger.logStep(`Initializing ${name} system`);
await system.initialize();
if (debugLogger) await debugLogger.logStep(`${name} system initialization complete`);
} else {
if (debugLogger) await debugLogger.logStep(`${name} system has no initialize method`);
}
}
if (debugLogger) await debugLogger.endStep('initializeSystems', {
totalSystems: Object.keys(this.systems).length,
systemsList: Object.keys(this.systems)
});
});
} else {
// Fallback without timing
if (debugLogger) await debugLogger.logStep('Logger not available, using fallback initialization');
// Initialize texture manager first
this.systems.textureManager = new TextureManager(this);
// Initialize in dependency order
this.systems.player = new Player(this);
this.systems.inventory = new Inventory(this);
this.systems.economy = new Economy(this);
this.systems.idleSystem = new IdleSystem(this);
this.systems.dungeonSystem = new DungeonSystem(this);
this.systems.skillSystem = new SkillSystem(this);
this.systems.baseSystem = new BaseSystem(this);
this.systems.questSystem = new QuestSystem(this);
// UIManager already initialized in initializeSystemsForLoad
this.systems.crafting = new CraftingSystem(this);
for (const [name, system] of Object.entries(this.systems)) {
if (system.initialize) {
await system.initialize();
}
}
if (debugLogger) await debugLogger.endStep('initializeSystems', {
fallbackMode: true,
totalSystems: Object.keys(this.systems).length
});
}
}
async setupEventListeners() {
const debugLogger = window.debugLogger;
if (debugLogger) await debugLogger.startStep('setupEventListeners');
// Window events
if (debugLogger) await debugLogger.logStep('Setting up window event listeners');
window.addEventListener('beforeunload', () => {
if (debugLogger) debugLogger.logStep('beforeunload event triggered - saving game');
this.save();
});
window.addEventListener('visibilitychange', () => {
// if (debugLogger) debugLogger.logStep('visibilitychange event triggered', {
// hidden: document.hidden,
// visibilityState: document.visibilityState
// });
if (document.hidden) {
// if (debugLogger) debugLogger.logStep('Document hidden - saving game');
this.save();
}
});
// Keyboard shortcuts
if (debugLogger) await debugLogger.logStep('Setting up keyboard shortcuts');
document.addEventListener('keydown', (event) => {
if (debugLogger) debugLogger.logStep('Key pressed', {
key: event.key,
code: event.code,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
shiftKey: event.shiftKey
});
// Ctrl+S for manual save
if (event.ctrlKey && event.key === 's') {
event.preventDefault();
if (debugLogger) debugLogger.logStep('Manual save shortcut triggered (Ctrl+S)');
this.save();
}
});
// Game loop events
if (debugLogger) await debugLogger.logStep('Setting up game loop events');
this.addEventListener('gameStarted', () => {
if (debugLogger) debugLogger.logStep('Game started event received');
});
this.addEventListener('gameStopped', () => {
if (debugLogger) debugLogger.logStep('Game stopped event received');
});
this.addEventListener('gameSaved', () => {
// if (debugLogger) debugLogger.logStep('Game saved event received');
});
this.addEventListener('gameLoaded', () => {
if (debugLogger) debugLogger.logStep('Game loaded event received');
});
// Setup UI event listeners
if (debugLogger) await debugLogger.logStep('Setting up UI event listeners');
if (this.systems.ui && typeof this.systems.ui.setupEventListeners === 'function' && !this.uiEventListenersSetup) {
this.systems.ui.setupEventListeners();
this.uiEventListenersSetup = true; // Prevent duplicate setup
if (debugLogger) await debugLogger.logStep('UI event listeners setup complete');
} else if (this.uiEventListenersSetup) {
if (debugLogger) await debugLogger.logStep('UI event listeners already setup, skipping');
}
if (debugLogger) await debugLogger.endStep('setupEventListeners', {
windowEvents: 2,
keyboardShortcuts: 2,
gameLoopEvents: 4
});
}
start() {
const debugLogger = window.debugLogger;
if (this.isRunning) {
if (debugLogger) debugLogger.log('GameEngine.start() called but game is already running', {
isRunning: this.isRunning,
gameTime: this.gameTime
});
return;
}
if (debugLogger) debugLogger.logStep('Starting game engine', {
gameLogicInterval: this.gameLogicInterval
});
this.isRunning = true;
this.lastUpdate = performance.now();
if (debugLogger) debugLogger.logStep('Game engine started, beginning game loop');
this.gameLoop();
// Loading screen is now handled by startGame() method
// Don't duplicate the hiding logic here
if (debugLogger) debugLogger.logStep('Game loop initiated');
}
async stop() {
const debugLogger = window.debugLogger;
if (debugLogger) await debugLogger.startStep('stopGame');
console.log('[GAME ENGINE] Stopping game and saving...');
if (debugLogger) await debugLogger.logStep('Stopping game engine');
if (!this.isRunning) {
if (debugLogger) debugLogger.logStep('Game already stopped, ignoring stop request');
return;
}
this.isRunning = false;
// Clear game logic timer
if (this.gameLogicTimer) {
clearInterval(this.gameLogicTimer);
this.gameLogicTimer = null;
}
// Clear auto-save timer
if (this.autoSaveTimer) {
clearInterval(this.autoSaveTimer);
this.autoSaveTimer = null;
}
// Clear server polling timer (multiplayer mode)
if (this.serverPollTimer) {
clearInterval(this.serverPollTimer);
this.serverPollTimer = null;
}
// Stop economy system timers
if (this.systems.economy) {
this.systems.economy.stopShopTimers();
}
console.log('[GAME ENGINE] Game stopped and saved successfully');
if (debugLogger) await debugLogger.endStep('stopGame', {
gameTime: this.gameTime,
isRunning: this.isRunning
});
}
startAutoSave() {
const debugLogger = window.debugLogger;
// Load saved interval or use default
const savedInterval = localStorage.getItem('autoSaveInterval');
this.autoSaveInterval = savedInterval ? parseInt(savedInterval) : 5;
console.log(`[GAME ENGINE] Starting auto-save with ${this.autoSaveInterval} minute interval`);
if (debugLogger) debugLogger.logStep('Starting auto-save system', {
interval: this.autoSaveInterval,
intervalMs: this.autoSaveInterval * 60 * 1000,
savedInterval: savedInterval,
isRunning: this.isRunning
});
// Clear any existing timer
this.stopAutoSave();
// Set up new timer
this.autoSaveTimer = setInterval(async () => {
if (debugLogger) debugLogger.logStep('Auto-save timer triggered', {
isRunning: this.isRunning,
paused: this.state.paused,
gameTime: this.gameTime,
lastAutoSave: this.lastAutoSave
});
console.log('[GAME ENGINE] Auto-save timer triggered - isRunning:', this.isRunning, 'paused:', this.state.paused);
if (this.isRunning && !this.state.paused) {
console.log('[GAME ENGINE] Auto-saving game...');
if (debugLogger) debugLogger.logStep('Auto-saving game');
try {
await this.save();
this.showNotification('Game auto-saved', 'info', 2000);
console.log('[GAME ENGINE] Auto-save completed successfully');
this.lastAutoSave = Date.now();
if (debugLogger) debugLogger.logStep('Auto-save completed successfully', {
lastAutoSave: this.lastAutoSave
});
} catch (error) {
console.error('[GAME ENGINE] Auto-save failed:', error);
if (debugLogger) await debugLogger.errorEvent(error, 'Auto-save');
}
} else {
console.log('[GAME ENGINE] Auto-save skipped - game not running or paused');
if (debugLogger) debugLogger.logStep('Auto-save skipped', {
reason: this.isRunning ? 'paused' : 'not running',
isRunning: this.isRunning,
paused: this.state.paused
});
}
}, this.autoSaveInterval * 60 * 1000); // Convert minutes to milliseconds
this.lastAutoSave = Date.now();
if (debugLogger) debugLogger.logStep('Auto-save timer started', {
timerId: this.autoSaveTimer,
lastAutoSave: this.lastAutoSave
});
}
stopAutoSave() {
const debugLogger = window.debugLogger;
if (this.autoSaveTimer) {
console.log('[GAME ENGINE] Stopping auto-save timer');
if (debugLogger) debugLogger.logStep('Stopping auto-save timer', {
timerId: this.autoSaveTimer,
wasRunning: true
});
clearInterval(this.autoSaveTimer);
this.autoSaveTimer = null;
if (debugLogger) debugLogger.logStep('Auto-save timer stopped');
} else {
if (debugLogger) debugLogger.logStep('stopAutoSave called but no timer was active', {
timerId: this.autoSaveTimer,
wasRunning: false
});
}
}
updateAutoSaveInterval(newInterval) {
const debugLogger = window.debugLogger;
console.log(`[GAME ENGINE] Updating auto-save interval to ${newInterval} minutes`);
if (debugLogger) debugLogger.logStep('Updating auto-save interval', {
oldInterval: this.autoSaveInterval,
newInterval: newInterval,
isRunning: this.isRunning
});
this.autoSaveInterval = newInterval;
// Save to localStorage
localStorage.setItem('autoSaveInterval', newInterval.toString());
// Restart auto-save with new interval if game is running
if (this.isRunning) {
if (debugLogger) debugLogger.logStep('Restarting auto-save with new interval');
this.startAutoSave();
}
if (debugLogger) debugLogger.logStep('Auto-save interval updated successfully', {
currentInterval: this.autoSaveInterval,
savedToStorage: true
});
}
start() {
const debugLogger = window.debugLogger;
if (this.isRunning) {
if (debugLogger) debugLogger.log('GameEngine.start() called but game is already running', {
isRunning: this.isRunning,
gameTime: this.gameTime
});
return;
}
if (debugLogger) debugLogger.logStep('Starting game engine', {
gameLogicInterval: this.gameLogicInterval
});
this.isRunning = true;
this.lastUpdate = Date.now();
// Start game logic timer (completely independent of frame rate)
console.log('[GAME ENGINE] Starting game logic timer with interval:', this.gameLogicInterval);
this.gameLogicTimer = setInterval(() => {
this.updateGameLogic();
}, this.gameLogicInterval);
// Start auto-save
this.startAutoSave();
// Check and apply any pending server data
if (this.checkAndApplyPendingServerData) {
this.checkAndApplyPendingServerData();
}
console.log('[GAME ENGINE] Game engine started');
if (debugLogger) debugLogger.logStep('Game engine started successfully', {
gameLogicInterval: this.gameLogicInterval,
autoSaveInterval: this.autoSaveInterval
});
}
updateGameLogic() {
const debugLogger = window.debugLogger;
// Use fixed 1-second interval for all updates
const fixedDelta = 1000; // 1 second in milliseconds
console.log('[GAME ENGINE] Game logic update called - adding', fixedDelta, 'ms to playtime');
if (this.state.paused) {
if (debugLogger) debugLogger.logStep('Game logic update called but game is paused', {
gameTime: this.gameTime,
fixedDelta: fixedDelta
});
return;
}
this.gameTime += fixedDelta;
// Log update performance every 300 frames (approximately 5 seconds)
if (debugLogger && this.gameTime % 15000 === 0) { // Every 15 seconds of game time
debugLogger.logStep('Game logic update cycle', {
gameTime: this.gameTime,
fixedDelta: fixedDelta,
isRunning: this.isRunning,
paused: this.state.paused,
currentTab: this.state.currentTab
});
}
// Update player play time with fixed delta
if (this.systems.player && this.systems.player.updatePlayTime) {
console.log('[GAME ENGINE] Before update - player playTime:', this.systems.player.stats.playTime);
this.systems.player.updatePlayTime(fixedDelta);
console.log('[GAME ENGINE] After update - player playTime:', this.systems.player.stats.playTime);
}
// Update all systems with fixed delta
for (const [name, system] of Object.entries(this.systems)) {
if (system && typeof system.update === 'function') {
try {
system.update(fixedDelta);
} catch (error) {
console.error(`[GAME ENGINE] Error updating ${name} system:`, error);
if (debugLogger) debugLogger.errorEvent(error, `Update ${name} system`);
}
}
}
// Update UI displays (money, gems, energy) after system updates
// Only update UI if in multiplayer mode or if game is actively running
const shouldUpdateUI = this.systems && this.systems.ui &&
(window.smartSaveManager?.isMultiplayer || this.isRunning);
if (shouldUpdateUI) {
console.log('[GAME ENGINE] Updating UI displays');
try {
this.systems.ui.updateUI();
console.log('[GAME ENGINE] UI update completed');
} catch (error) {
console.error('[GAME ENGINE] Error updating UI:', error);
}
}
// Only emit UI update event if in multiplayer mode or game is actively running
const shouldEmitUIUpdate = window.smartSaveManager?.isMultiplayer || this.isRunning;
if (shouldEmitUIUpdate) {
this.emitUIUpdateEvent('full');
}
// Emit game updated event
this.emit('gameUpdated', { gameTime: this.gameTime });
}
update(deltaTime) {
// Legacy method - game logic now handled by updateGameLogic()
// This method kept for compatibility but doesn't process game systems
}
shouldUpdateGUI() {
// Use centralized UI update control from UIManager
if (this.systems && this.systems.ui && this.systems.ui.shouldUpdateUI) {
const currentTime = Date.now();
if (currentTime - this.lastGUIUpdate >= this.guiUpdateInterval) {
this.lastGUIUpdate = currentTime;
return true;
}
}
return false;
}
updateGUI() {
const debugLogger = window.debugLogger;
console.log('[GAME ENGINE] Updating GUI');
// Update UI displays (money, gems, energy) after system updates
// Only update UI if in multiplayer mode or if game is actively running
const shouldUpdateUI = this.systems && this.systems.ui &&
(window.smartSaveManager?.isMultiplayer || this.isRunning);
if (shouldUpdateUI) {
console.log('[GAME ENGINE] Updating UI displays');
try {
this.systems.ui.updateUI();
console.log('[GAME ENGINE] UI update completed');
} catch (error) {
console.error('[GAME ENGINE] Error updating UI:', error);
}
} else {
// Skip UI updates when not in multiplayer and game is not actively running
if (this.systems && this.systems.ui) {
console.log('[GAME ENGINE] Skipping GUI updates - not in multiplayer mode');
}
}
}
// Event system
on(event, callback) {
if (!this.eventListeners.has(event)) {
this.eventListeners.set(event, []);
}
this.eventListeners.get(event).push(callback);
}
emit(event, data) {
if (this.eventListeners.has(event)) {
this.eventListeners.get(event).forEach(callback => {
try {
callback(data);
} catch (error) {
console.error(`[GAME ENGINE] Error in event listener for ${event}:`, error);
}
});
}
// Also dispatch as DOM event for UIManager
this.dispatchEvent(new CustomEvent(event, { detail: data }));
}
emitUIUpdateEvent(type, data = {}) {
const eventData = {
type: type,
timestamp: Date.now(),
...data
};
console.log('[GAME ENGINE] Emitting UI update event:', eventData);
this.emit('uiUpdate', eventData);
}
// Notification system
async showNotification(message, type = 'info', duration = 3000) {
const logger = window.logger;
if (logger) await logger.playerAction('Notification', { message, type, duration });
const notification = {
id: Date.now(),
message,
type,
duration,
timestamp: Date.now()
};
this.state.notifications.push(notification);
// Auto-remove notification after duration
setTimeout(() => {
this.removeNotification(notification.id);
}, duration);
// Update UI
if (this.systems.ui) {
// UI updates handled by individual systems
}
}
removeNotification(id) {
this.state.notifications = this.state.notifications.filter(notification => notification.id !== id);
}
processNotifications() {
const now = Date.now();
this.state.notifications = this.state.notifications.filter(
notification => now - notification.timestamp < notification.duration
);
}
// Save/Load system
async save() {
const logger = window.logger;
const debugLogger = window.debugLogger;
console.log('[GAME ENGINE] Save method called');
if (logger) await logger.info('Saving game');
// if (debugLogger) await debugLogger.startStep('saveGame');
try {
// if (debugLogger) await debugLogger.logStep('Collecting save data from systems');
console.log('[GAME ENGINE] Collecting save data from systems...');
const saveData = {
player: this.systems.player.save(),
inventory: this.systems.inventory.save(),
economy: this.systems.economy.save(),
idleSystem: this.systems.idleSystem.save(),
dungeonSystem: this.systems.dungeonSystem.save(),
skillSystem: this.systems.skillSystem.save(),
baseSystem: this.systems.baseSystem.save(),
questSystem: this.systems.questSystem.save(),
gameTime: this.gameTime,
lastSave: Date.now()
};
// if (debugLogger) await debugLogger.logStep('Save data collected', {
// playerLevel: saveData.player?.stats?.level,
// gameTime: this.gameTime,
// saveDataSize: JSON.stringify(saveData).length,
// });
// console.log('[GAME ENGINE] Save data collected, player level:', saveData.player?.stats?.level);
// console.log('[GAME ENGINE] Save slot info:', this.saveSlotInfo);}
// Check if we should save to server (multiplayer mode)
if (window.smartSaveManager && window.smartSaveManager.isMultiplayer) {
console.log('[GAME ENGINE] Saving to server in multiplayer mode');
if (debugLogger) await debugLogger.logStep('Saving to server in multiplayer mode');
try {
const serverSaveResult = await window.smartSaveManager.savePlayerData(saveData);
if (serverSaveResult) {
console.log('[GAME ENGINE] Game saved successfully to server');
if (debugLogger) await debugLogger.logStep('Game saved successfully to server');
} else {
console.warn('[GAME ENGINE] Server save failed, falling back to local storage');
if (debugLogger) await debugLogger.warn('Server save failed, using local fallback');
// Fallback to localStorage
const saveKey = `gso_save_slot_${this.saveSlotInfo?.slot || 1}`;
localStorage.setItem(saveKey, JSON.stringify(saveData));
}
} catch (error) {
console.error('[GAME ENGINE] Error saving to server:', error);
if (debugLogger) await debugLogger.errorEvent(error, 'Server Save');
// Fallback to localStorage
const saveKey = `gso_save_slot_${this.saveSlotInfo?.slot || 1}`;
localStorage.setItem(saveKey, JSON.stringify(saveData));
console.log('[GAME ENGINE] Error fallback: Game saved to localStorage');
}
} else {
// Local save logic (existing code)
const isLocalMode = window.liveMainMenu && window.liveMainMenu.isLocalMode;
if (isLocalMode) {
console.log('[GAME ENGINE] Using localStorage for local mode save');
if (debugLogger) await debugLogger.logStep('Saving via localStorage for local mode');
try {
const saveKey = `gso_save_slot_${this.saveSlotInfo.slot}`;
const saveString = JSON.stringify(saveData);
// Save to localStorage
localStorage.setItem(saveKey, saveString);
console.log('[GAME ENGINE] Game saved successfully to localStorage');
console.log('[GAME ENGINE] Save key:', saveKey);
console.log('[GAME ENGINE] Save data size:', saveString.length, 'characters');
console.log('[GAME ENGINE] Current localStorage keys:', Object.keys(localStorage));
// Verify save exists
const verifySave = localStorage.getItem(saveKey);
console.log('[GAME ENGINE] Save verification:', !!verifySave ? 'SUCCESS' : 'FAILED');
if (debugLogger) await debugLogger.logStep('Game saved successfully to localStorage', {
saveKey,
saveDataSize: saveString.length
});
// Emit save event
this.emit('gameSaved', { slot: this.saveSlotInfo.slot, saveData });
// if (debugLogger) debugLogger.logStep('Game saved event emitted');
} catch (error) {
console.error('[GAME ENGINE] Failed to save to localStorage:', error);
if (debugLogger) await debugLogger.errorEvent(error, 'LocalStorage Save');
throw error;
}
} else {
// Use file system if available, otherwise localStorage (original logic)
if (this.saveSlotInfo && this.saveSlotInfo.useFileSystem) {
if (window.electronAPI) {
// console.log('[GAME ENGINE] Using Electron API to save game');
// if (debugLogger) await debugLogger.logStep('Saving via Electron API', {
// slot: this.saveSlotInfo.slot,
// useFileSystem: true
// });
try {
// Save through Electron API
const result = await window.electronAPI.saveGame(this.saveSlotInfo.slot, saveData);
if (result.success) {
// console.log('[GAME ENGINE] Game saved successfully via Electron API');
if (debugLogger) await debugLogger.logStep('Game saved successfully via Electron API', {
slot: this.saveSlotInfo.slot,
result: result
});
// Emit save event
this.emit('gameSaved', { slot: this.saveSlotInfo.slot, saveData });
// if (debugLogger) debugLogger.logStep('Game saved event emitted');
} else {
console.error('[GAME ENGINE] Failed to save via Electron API:', result.error);
if (debugLogger) await debugLogger.errorEvent(new Error(result.error), 'Electron API Save');
// Fallback to localStorage
if (debugLogger) await debugLogger.logStep('Falling back to localStorage');
const saveKey = `gso_save_slot_${this.saveSlotInfo.slot}`;
localStorage.setItem(saveKey, JSON.stringify(saveData));
console.log('[GAME ENGINE] Fallback: Game saved to localStorage with key:', saveKey);
if (debugLogger) await debugLogger.logStep('Game saved to localStorage fallback', {
saveKey,
dataSize: JSON.stringify(saveData).length
});
}
} catch (error) {
console.error('[GAME ENGINE] Electron API save error:', error);
if (debugLogger) await debugLogger.errorEvent(error, 'Electron API Save');
// Fallback to localStorage
if (debugLogger) await debugLogger.logStep('Falling back to localStorage due to error');
const saveKey = `gso_save_slot_${this.saveSlotInfo.slot}`;
localStorage.setItem(saveKey, JSON.stringify(saveData));
console.log('[GAME ENGINE] Error fallback: Game saved to localStorage with key:', saveKey);
}
} else {
console.warn('[GAME ENGINE] Electron API not available, using localStorage');
if (debugLogger) await debugLogger.warn('Electron API not available, using localStorage');
const saveKey = `gso_save_slot_${this.saveSlotInfo.slot}`;
localStorage.setItem(saveKey, JSON.stringify(saveData));
console.log('[GAME ENGINE] Game saved to localStorage with key:', saveKey);
if (debugLogger) await debugLogger.logStep('Game saved to localStorage', {
saveKey,
dataSize: JSON.stringify(saveData).length
});
}
} else {
// LocalStorage fallback
if (debugLogger) await debugLogger.logStep('Using localStorage save');
const saveKey = `gso_save_slot_${this.saveSlotInfo.slot}`;
localStorage.setItem(saveKey, JSON.stringify(saveData));
console.log('[GAME ENGINE] Game saved to localStorage with key:', saveKey);
if (debugLogger) await debugLogger.logStep('Game saved to localStorage', {
saveKey,
dataSize: JSON.stringify(saveData).length
});
}
}
if (logger) await logger.info('Game saved successfully');
// Check if we should also save to server (multiplayer mode)
if (window.smartSaveManager && window.smartSaveManager.isMultiplayer) {
console.log('[GAME ENGINE] Also saving to server in multiplayer mode');
try {
await window.smartSaveManager.savePlayerData(saveData);
console.log('[GAME ENGINE] Game saved successfully to server');
} catch (error) {
console.error('[GAME ENGINE] Error saving to server:', error);
// Don't throw error - local save was successful
}
}
// if (debugLogger) await debugLogger.endStep('saveGame', {
// gameTime: this.gameTime,
// saveSlot: this.saveSlotInfo?.slot,
// success: true
// });
}
} catch (error) {
console.error('[GAME ENGINE] Save failed:', error);
if (logger) await logger.errorEvent(error, 'Game Save');
if (debugLogger) await debugLogger.errorEvent(error, 'Game Save');
throw error;
}
}
async loadPlayerData(playerData) {
console.log('[GAME ENGINE] Loading server player data into game');
try {
// Apply player stats
if (playerData.stats && this.systems && this.systems.player) {
console.log('[GAME ENGINE] Applying player stats:', playerData.stats);
this.systems.player.load(playerData.stats);
}
// Apply inventory
if (playerData.inventory && this.systems && this.systems.inventory) {
console.log('[GAME ENGINE] Applying player inventory:', playerData.inventory);
this.systems.inventory.load(playerData.inventory);
}
// Apply ship data
if (playerData.ship && this.systems && this.systems.ship) {
console.log('[GAME ENGINE] Applying player ship:', playerData.ship);
this.systems.ship.load(playerData.ship);
}
// Apply base data
if (playerData.base && this.systems && this.systems.base) {
console.log('[GAME ENGINE] Applying player base:', playerData.base);
this.systems.base.load(playerData.base);
}
// Apply quest data
if (playerData.quests && this.systems && this.systems.quests) {
console.log('[GAME ENGINE] Applying player quests:', playerData.quests);
this.systems.quests.load(playerData.quests);
}
// Apply skill data
if (playerData.skills && this.systems && this.systems.skills) {
console.log('[GAME ENGINE] Applying player skills:', playerData.skills);
this.systems.skills.load(playerData.skills);
}
// Apply idle system data
if (playerData.idleSystem && this.systems && this.systems.idleSystem) {
console.log('[GAME ENGINE] Applying player idle system:', playerData.idleSystem);
this.systems.idleSystem.load(playerData.idleSystem);
}
// Apply dungeon system data
if (playerData.dungeonSystem && this.systems && this.systems.dungeonSystem) {
console.log('[GAME ENGINE] Applying player dungeon system:', playerData.dungeonSystem);
this.systems.dungeonSystem.load(playerData.dungeonSystem);
}
// Apply crafting system data
if (playerData.craftingSystem && this.systems && this.systems.craftingSystem) {
console.log('[GAME ENGINE] Applying player crafting system:', playerData.craftingSystem);
this.systems.craftingSystem.load(playerData.craftingSystem);
}
// Apply game time
if (playerData.gameTime !== undefined) {
this.gameTime = playerData.gameTime;
console.log('[GAME ENGINE] Game time restored:', this.gameTime);
}
console.log('[GAME ENGINE] Server player data applied successfully');
// Show notification to user
if (this.showNotification) {
this.showNotification(`Welcome back! Level ${playerData.stats?.level || 1}`, 'success', 3000);
}
} catch (error) {
console.error('[GAME ENGINE] Error loading server player data:', error);
if (this.showNotification) {
this.showNotification('Failed to load server data!', 'error', 3000);
}
}
}
async load() {
const logger = window.logger;
const debugLogger = window.debugLogger;
console.log('[GAME ENGINE] Load method called');
if (logger) await logger.info('Loading game');
if (debugLogger) await debugLogger.startStep('loadGame');
try {
if (debugLogger) await debugLogger.logStep('Loading save data', {
saveSlot: this.saveSlotInfo?.slot,
useFileSystem: this.saveSlotInfo?.useFileSystem
});
let saveData;
// Use file system if available, otherwise localStorage
if (this.saveSlotInfo && this.saveSlotInfo.useFileSystem && window.electronAPI) {
console.log('[GAME ENGINE] Loading via Electron API');
if (debugLogger) await debugLogger.logStep('Loading via Electron API');
const result = await window.electronAPI.loadGame(this.saveSlotInfo.slot);
if (result.success) {
saveData = result.data;
console.log('[GAME ENGINE] Game loaded successfully via Electron API');
if (debugLogger) await debugLogger.logStep('Game loaded via Electron API', {
slot: this.saveSlotInfo.slot,
dataSize: JSON.stringify(saveData).length
});
} else {
console.error('[GAME ENGINE] Failed to load via Electron API:', result.error);
if (debugLogger) await debugLogger.errorEvent(new Error(result.error), 'Electron API Load');
throw new Error(result.error);
}
} else {
// LocalStorage fallback
console.log('[GAME ENGINE] Loading from localStorage');
if (debugLogger) await debugLogger.logStep('Loading from localStorage');
const saveKey = `gso_save_slot_${this.saveSlotInfo.slot}`;
const saveString = localStorage.getItem(saveKey);
if (saveString) {
try {
saveData = JSON.parse(saveString);
console.log('[GAME ENGINE] Game loaded from localStorage');
if (debugLogger) await debugLogger.logStep('Game loaded from localStorage', {
saveKey,
dataSize: saveString.length
});
} catch (parseError) {
console.error('[GAME ENGINE] Failed to parse save data:', parseError);
if (debugLogger) await debugLogger.errorEvent(parseError, 'Parse Save Data');
throw new Error('Corrupted save data');
}
} else {
console.warn('[GAME ENGINE] No save data found in localStorage');
if (debugLogger) await debugLogger.warn('No save data found in localStorage', { saveKey });
throw new Error('No save data found');
}
}
// if (debugLogger) await debugLogger.logStep('Applying save data to systems');
// Apply save data to systems
if (saveData.player && this.systems.player) {
console.log('[GAME ENGINE] Loading player data...');
this.systems.player.load(saveData.player);
if (debugLogger) await debugLogger.logStep('Player data loaded', {
level: saveData.player?.stats?.level,
experience: saveData.player?.stats?.experience
});
}
if (saveData.inventory && this.systems.inventory) {
console.log('[GAME ENGINE] Loading inventory data...');
this.systems.inventory.load(saveData.inventory);
if (debugLogger) await debugLogger.logStep('Inventory data loaded', {
itemCount: saveData.inventory.items?.length || 0
});
}
if (saveData.economy && this.systems.economy) {
console.log('[GAME ENGINE] Loading economy data...');
this.systems.economy.load(saveData.economy);
if (debugLogger) await debugLogger.logStep('Economy data loaded', {
credits: saveData.economy.credits,
gems: saveData.economy.gems
});
}
if (saveData.gameTime) {
this.gameTime = saveData.gameTime;
if (debugLogger) await debugLogger.logStep('Game time restored', {
gameTime: this.gameTime
});
}
// Emit load event
this.emit('gameLoaded', { saveData });
if (debugLogger) debugLogger.logStep('Game loaded event emitted');
if (logger) await logger.info('Game loaded successfully');
if (debugLogger) await debugLogger.endStep('loadGame', {
gameTime: this.gameTime,
saveSlot: this.saveSlotInfo?.slot,
success: true
});
} catch (error) {
console.error('[GAME ENGINE] Load failed:', error);
if (logger) await logger.errorEvent(error, 'Game Load');
if (debugLogger) await debugLogger.errorEvent(error, 'Game Load');
throw error;
}
}
async newGame() {
const logger = window.logger;
const debugLogger = window.debugLogger;
console.log('[GAME ENGINE] Starting new game initialization');
if (logger) await logger.info('Starting new game');
if (debugLogger) await debugLogger.startStep('newGame');
try {
// For new games, we need to properly initialize systems with default data
if (debugLogger) await debugLogger.logStep('Initializing systems for new game');
// Initialize inventory with starting items
if (this.systems.inventory) {
console.log('[GAME ENGINE] Initializing inventory with starting items');
if (debugLogger) await debugLogger.logStep('Initializing inventory with starting items');
await this.systems.inventory.initialize();
}
// Initialize DungeonSystem for new game
if (this.systems.dungeonSystem) {
console.log('[GAME ENGINE] Initializing DungeonSystem for new game...');
if (debugLogger) await debugLogger.logStep('Initializing DungeonSystem for new game');
try {
await this.systems.dungeonSystem.initialize();
console.log('[GAME ENGINE] DungeonSystem initialized successfully for new game');
if (debugLogger) await debugLogger.logStep('DungeonSystem initialized successfully for new game');
} catch (dungeonError) {
console.error('[GAME ENGINE] DungeonSystem initialization failed for new game:', dungeonError);
if (debugLogger) await debugLogger.errorEvent(dungeonError, 'DungeonSystem initialization failed for new game');
}
} else {
console.log('[GAME ENGINE] DungeonSystem not found in systems!');
}
if (this.systems.player) {
console.log('[GAME ENGINE] Resetting player to initial state');
if (debugLogger) await debugLogger.logStep('Resetting player to initial state');
this.systems.player.resetToLevel1();
console.log('[GAME ENGINE] Player reset completed');
if (debugLogger) await debugLogger.logStep('Player reset completed', {
level: this.systems.player.stats.level,
experience: this.systems.player.stats.experience,
playTime: this.systems.player.stats.playTime
});
console.log('[GAME ENGINE] Setting up new player');
if (debugLogger) await debugLogger.logStep('Setting up new player');
this.systems.player.setupNewPlayer();
console.log('[GAME ENGINE] Player setup completed');
if (debugLogger) await debugLogger.logStep('Player setup completed', {
level: this.systems.player.stats.level,
experience: this.systems.player.stats.experience
});
} else {
console.error('[GAME ENGINE] Player system not available');
if (debugLogger) await debugLogger.error('Player system not available');
}
if (debugLogger) await debugLogger.logStep('Resetting economy system');
console.log('[GAME ENGINE] Step 2: Resetting economy system');
if (this.systems.economy) {
console.log('[GAME ENGINE] Calling economy.reset()');
if (debugLogger) await debugLogger.logStep('Calling economy.reset()');
this.systems.economy.reset();
console.log('[GAME ENGINE] Economy reset completed');
if (debugLogger) await debugLogger.logStep('Economy reset completed', {
credits: this.systems.economy.credits,
gems: this.systems.economy.gems
});
} else {
console.error('[GAME ENGINE] Economy system not available');
if (debugLogger) await debugLogger.error('Economy system not available');
}
// Skip inventory reset - initialize() already handles proper setup
if (debugLogger) await debugLogger.logStep('Skipping inventory reset - already initialized');
console.log('[GAME ENGINE] Skipping inventory reset - already initialized with starting items');
if (this.systems.inventory) {
if (debugLogger) await debugLogger.logStep('Inventory already initialized', {
itemCount: this.systems.inventory.items.length
});
} else {
console.error('[GAME ENGINE] Inventory system not available');
if (debugLogger) await debugLogger.error('Inventory system not available');
}
if (debugLogger) await debugLogger.logStep('Resetting quest system');
console.log('[GAME ENGINE] Step 4: Resetting quest system');
if (this.systems.questSystem) {
console.log('[GAME ENGINE] Calling questSystem.reset()');
if (debugLogger) await debugLogger.logStep('Calling questSystem.reset()');
this.systems.questSystem.reset();
console.log('[GAME ENGINE] Quest system reset completed');
if (debugLogger) await debugLogger.logStep('Quest system reset completed');
// Activate the tutorial quest for new games
console.log('[GAME ENGINE] Activating tutorial quest for new game');
if (debugLogger) await debugLogger.logStep('Activating tutorial quest');
this.systems.questSystem.startQuest('tutorial_complete');
console.log('[GAME ENGINE] Tutorial quest activated');
if (debugLogger) await debugLogger.logStep('Tutorial quest activated');
} else {
console.error('[GAME ENGINE] Quest system not available');
if (debugLogger) await debugLogger.error('Quest system not available');
}
if (debugLogger) await debugLogger.logStep('Resetting game time');
console.log('[GAME ENGINE] Step 5: Resetting game time');
this.gameTime = 0;
console.log('[GAME ENGINE] Game time reset to 0');
if (debugLogger) await debugLogger.logStep('Game time reset', { gameTime: this.gameTime });
if (logger) await logger.info('New game initialized successfully');
if (debugLogger) await debugLogger.endStep('newGame', {
gameTime: this.gameTime,
playerLevel: this.systems.player?.stats.level,
success: true
});
} catch (error) {
console.error('[GAME ENGINE] Failed to initialize new game:', error);
if (logger) await logger.errorEvent(error, 'New Game Initialization');
if (debugLogger) await debugLogger.errorEvent(error, 'New Game Initialization');
throw error;
}
}
// Utility methods
formatNumber(num) {
if (num >= 1e9) return (num / 1e9).toFixed(2) + 'B';
if (num >= 1e6) return (num / 1e6).toFixed(2) + 'M';
if (num >= 1e3) return (num / 1e3).toFixed(2) + 'K';
return num.toString();
}
formatTime(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = Math.floor(seconds % 60);
if (hours > 0) {
return `${hours}h ${minutes}m ${secs}s`;
} else if (minutes > 0) {
return `${minutes}m ${secs}s`;
} else {
return `${secs}s`;
}
}
toggleDebugConsole() {
const debugLogger = window.debugLogger;
// if (debugLogger) debugLogger.logStep('Toggle debug console requested');
// Implementation would go here
// console.log('[GAME ENGINE] Debug console toggle requested');
}
getPerformanceStats() {
const debugLogger = window.debugLogger;
const stats = {
gameTime: this.gameTime,
isRunning: this.isRunning,
lastUpdate: this.lastUpdate,
memory: null
};
// Add memory info if available
if (window.performance && window.performance.memory) {
stats.memory = {
used: window.performance.memory.usedJSHeapSize,
total: window.performance.memory.totalJSHeapSize,
limit: window.performance.memory.jsHeapSizeLimit
};
}
// if (debugLogger) debugLogger.logStep('Performance stats requested', stats);
return stats;
}
// Simple loadPlayerData method for server data integration
async loadPlayerData(playerData) {
console.log('[GAME ENGINE] Loading server player data');
try {
// Apply basic player stats
if (playerData.stats && this.systems && this.systems.player) {
this.systems.player.load(playerData.stats);
console.log('[GAME ENGINE] Applied player stats:', playerData.stats);
}
// Apply inventory
if (playerData.inventory && this.systems && this.systems.inventory) {
this.systems.inventory.load(playerData.inventory);
console.log('[GAME ENGINE] Applied inventory');
}
// Apply ship data
if (playerData.ship && this.systems && this.systems.ship) {
this.systems.ship.load(playerData.ship);
console.log('[GAME ENGINE] Applied ship data');
}
// Apply base data
if (playerData.base && this.systems && this.systems.base) {
this.systems.base.load(playerData.base);
console.log('[GAME ENGINE] Applied base data');
}
// Show notification
if (this.showNotification) {
this.showNotification(`Welcome back! Level ${playerData.stats?.level || 1}`, 'success', 3000);
}
console.log('[GAME ENGINE] Server player data loaded successfully');
} catch (error) {
console.error('[GAME ENGINE] Error loading server player data:', error);
if (this.showNotification) {
this.showNotification('Failed to load server data!', 'error', 3000);
}
}
}
}
// Global game instance
let game = null;
// Export GameEngine to global scope
if (typeof window !== 'undefined') {
window.GameEngine = GameEngine;
}