Game Loop and Initialization
Relevant source files
The following files were used as context for generating this wiki page:This document outlines the technical architecture of the game's initialization process, scene management, and the main game loop. It covers the flow from the application's entry point in Electron to the per-frame updates within the core GameScene.
Application Startup Flow
The game is packaged as a desktop application using Electron. The startup process begins in main.js, which configures and launches the main application window. This window then loads the Phaser 3 game engine and its associated scenes.
The diagram below illustrates the high-level startup sequence.
Sources: main.js:20-41, renderer/index.html:23
- The Electron
appemits thewhenReadyevent. main.jsexecutescreateWindow(), which creates a fullscreenBrowserWindow.- The window loads the game's entry HTML file. In development, this is a Vite server URL; in production, it's the built
dist/index.html. - The HTML file loads the main renderer script, which creates the Phaser
Gameinstance and starts the first scene,MainMenuScene.
Sources: main.js:20-41, src/scenes/MainMenuScene.js:5
Scene Transition and Game Start
The game's flow is managed through a series of Phaser scenes. The user navigates from the main menu to the game itself, with different paths for new games versus loaded games.
Scene Flow Diagram
This diagram shows the primary paths a user can take to enter the GameScene.
- New Game: When a user starts a new game,
MainMenuScenecallsSaveSlotManager.selectSlot()to initialize a new save file. It then transitions toIntroScene, which plays a cinematic. Upon completion,IntroScenestartsGameScenewith tutorial flags enabled, beginning on theother_cavemap. - Load Game: When loading,
MainMenuSceneagain usesSaveSlotManagerto select the appropriate slot and then directly startsGameScene, passing the saved map key and character type.
GameScene Lifecycle
GameScene is the core of the gameplay, responsible for rendering the map, player, enemies, and handling all interactive logic. Its lifecycle follows the standard Phaser scene methods: init, preload, create, and update.
1. Initialization (init)
The init method is the first to run. It receives data from the scene that started it (e.g., MainMenuScene or IntroScene) and sets up the foundational configuration for the scene.
| Parameter | Type | Description | Default |
|---|---|---|---|
mapKey | string | The key of the map to load from mapData.js. | 'other_cave' |
characterType | string | The key of the character to spawn. | 'soul' |
isTutorial | boolean | If true, the tutorial system will be activated. | false |
isNewGame | boolean | Flag indicating this is the start of a new game. | false |
isRespawn | boolean | Flag indicating the player is respawning after death. | false |
skipSaveCheck | boolean | If true, ignores saved position and loads the specified mapKey. | false |
The primary task of init is to use GameSceneInitializer to establish the scene's context.
This diagram shows the init method's reliance on GameSceneInitializer to load the correct map configuration.
Sources: src/scenes/GameScene.js:63-82, src/systems/GameScene/GameSceneInitializer.js:8-16
2. Asset Loading (preload)
The preload method is responsible for loading all assets required for the scene, based on the mapConfig set in init. This includes:
- Map Assets: Parallax background layers via
MapModel. - Character & Enemy Assets: Spritesheets for the player and all potential enemies using
CharacterAssetLoaderandEnemyAssetLoader. - Effect Assets: Spritesheets for visual effects via
EffectLoader. - Boss Assets: If the map contains a boss, its assets are preloaded.
Sources: src/scenes/GameScene.js:108-157
3. Scene Creation (create)
The create method is where all game objects and systems are instantiated and configured. This is the most complex part of the initialization.
Sources: src/scenes/GameScene.js:180-264
Key steps in the create method:
- UI Initialization: Launches the parallel
UISceneto handle the HUD. - Save Data: Ensures the current save slot is initialized and loads kill/portal progression from
SaveSlotManager. - Player Setup: Uses
PlayerSpawnSystemto create the player character. This system handles spawning at default locations, saved positions, or portal entry points. It also manages respawning after death. - System Initialization: Instantiates critical gameplay systems like
LevelSystem,SkillUnlockSystem, andBossEventHandler. - Object Creation: Creates the background layers, enemies (
EnemyManager), and sets up the camera to follow the player. - Event Listeners: Sets up listeners for
shutdownandpauseto ensure the game state is saved before the scene closes. - Tutorial: If the
isTutorialflag is set (on theother_cavemap), it starts theTutorialSystem.
4. The Game Loop (update)
The update(time, delta) method is executed on every frame and forms the heart of the game loop. It orchestrates all dynamic aspects of the game.
The flow of the update loop is as follows:
- Pre-Update Checks: Verifies that the player is ready and not dead. If the player's health is zero, it triggers the
onPlayerDeath()sequence and halts further updates. - Input Handling: Calls
handleInput()to process keyboard state fromInputHandler. This includes movement, skills, and system commands like opening the pause menu. - Game Object Updates: Calls
updateGameObjects(), which in turn updates the player,EnemyManager,MapModel, and the current boss. This is where physics, AI, and animations are advanced. - Event Emission: Emits events like
player-stats-updatedto inform other systems (likeUIScene) of state changes. - Auto-Save: Periodically (every 5 seconds), the
autoSave()method is called to persist the player's position, resources, and level progress.
Sources: src/scenes/GameScene.js:1248-1293
// src/scenes/GameScene.js:1248-1272
async update(time, delta) {
// ✅ async 추가
if (!this.isPlayerReady()) return;
if (this.player && this.player.health <= 0 && !this.isPlayerDead && !this.player.isDying) {
await this.onPlayerDeath();
return;
}
if (this.isPlayerDead || (this.player && this.player.isDying)) {
return;
}
if (this.jobConditionTracker) {
this.jobConditionTracker.update(time);
}
if (this.skillUnlockSystem?.update) {
this.skillUnlockSystem.update(time, delta);
}
await this.handleInput(time, delta); // ✅ await 추가
await this.updateGameObjects(time, delta);
this.emitPlayerEvents();
this.effectManager.update();
await this.autoSave(time);
}
Sources: src/scenes/GameScene.js:1248-1272
Conclusion
The game's initialization and loop are built on a structured, scene-based architecture provided by Phaser. The process is highly data-driven, relying on configurations from mapData.js and persistent state from SaveSlotManager. The GameScene acts as a central coordinator, delegating responsibilities to specialized managers and systems (EnemyManager, PlayerSpawnSystem, LevelSystem), which promotes modularity and separation of concerns. The update loop ensures a consistent order of operations, from input processing to state updates and periodic auto-saving, creating a robust foundation for gameplay.