Scene Management
Relevant source files
The following files were used as context for generating this wiki page:
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene.java
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/TitleScene.java
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/AboutScene.java
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/SurfaceScene.java
Scene management in Shattered Pixel Dungeon is the system responsible for controlling the different screens or states of the game, such as the title menu, the main gameplay view, and loading screens. It is built upon the com.watabou.noosa.Scene class from the underlying game engine.
The core of the system is the ShatteredPixelDungeon class, which orchestrates transitions between different scenes. All scenes inherit from a common base class, PixelScene, which provides shared functionality like camera setup, UI scaling, and fade transitions. The most complex scene is GameScene, which handles all aspects of active gameplay, while InterlevelScene manages the transitions between dungeon floors.
Core Architecture
The scene management architecture is composed of a main game class that handles switching and a base scene class that provides common functionality to all concrete scene implementations.
ShatteredPixelDungeon Class
This is the main entry point of the game, extending com.watabou.noosa.Game. It is responsible for global tasks such as initializing audio, handling the game lifecycle, and, most importantly, managing scene transitions.
It provides several static methods to switch between scenes:
switchScene(Class<? extends Scene> c): The standard method to transition to a new scene, which usually involves a fade effect.switchNoFade(Class<? extends PixelScene> c): A variant that switches scenes without a fade transition.seamlessResetScene(): Reloads the current scene, preserving any open windows, which is useful for handling screen resizes.
Sources: ShatteredPixelDungeon.java:80-97
PixelScene Base Class
PixelScene is the abstract base class for all scenes in the game. It extends com.watabou.noosa.Scene and establishes a common foundation for UI, rendering, and lifecycle management.
Key responsibilities include:
- Camera Setup: It initializes two cameras:
Camera.mainfor the game world and a staticuiCamerafor all user interface elements. This separation allows the game world to be zoomed and panned independently of the UI. - UI Scaling: It calculates a
defaultZoomfactor based on the device's screen resolution and interface size settings. This ensures the pixel-art aesthetic is maintained and the UI is scaled appropriately across different devices. - Fade Transitions: Implements a default
fadeIn()mechanism using an innerFaderclass to create smooth visual transitions between scenes. - Window Management: It includes logic to save and restore
Windowinstances across scene reloads, such as during a screen rotation.
Sources: PixelScene.java:70-120, PixelScene.java:200-211
Class Hierarchy
The following diagram illustrates the inheritance structure of the primary scenes.
This diagram shows how ShatteredPixelDungeon extends the base Game class and how all specific scenes inherit from the common PixelScene.
Sources: ShatteredPixelDungeon.java:31, PixelScene.java:51, GameScene.java:120, TitleScene.java:44, InterlevelScene.java:68
Key Scenes
The game is divided into several distinct scenes, each with a specific role.
| Scene | File Path | Primary Purpose |
|---|---|---|
TitleScene | scenes/TitleScene.java | The main menu screen for starting or continuing games and accessing other menus like Rankings and About. |
GameScene | scenes/GameScene.java | The main gameplay interface, rendering the dungeon, hero, items, enemies, and all associated UI panes. |
InterlevelScene | scenes/InterlevelScene.java | A loading screen that manages the transition between dungeon floors, handling level generation and loading in a background thread. |
SurfaceScene | scenes/SurfaceScene.java | The victory screen displayed when the player wins the game by returning to the surface. |
AboutScene | scenes/AboutScene.java | An informational screen that displays game credits and links. |
ChangesScene | ui/changelist/ | Displays the game's version history and changelog. The content is dynamically built from classes in this package. |
Sources: TitleScene.java, GameScene.java, InterlevelScene.java, SurfaceScene.java, AboutScene.java, ui/changelist/v2_X_Changes.java:26
Scene Transition Flow
Transitions between scenes are fundamental to the game's flow, especially when moving between dungeon levels. The InterlevelScene is central to this process.
The diagram below shows a typical sequence from starting a new game to changing floors.
InterlevelScene: The Transition Manager
The InterlevelScene is more than just a loading screen; it's a state machine that manages the complex process of moving between dungeon floors.
Transition Modes
It operates in different modes, defined by the InterlevelScene.Mode enum, which dictates the type of transition to perform.
| Mode | Description |
|---|---|
DESCEND | Moving to a deeper floor. |
ASCEND | Moving to a shallower floor. |
CONTINUE | Loading a saved game from the main menu. |
RESURRECT | Reviving the hero after death using an Ankh. |
RETURN | Returning to a previous level from a sub-level (e.g., a quest area). |
FALL | Falling through a chasm to the floor below. |
RESET | Regenerating the current level. |
Sources: InterlevelScene.java:72-74
Asynchronous Level Loading
To prevent the UI from freezing during level generation or loading (which are I/O and CPU-intensive), InterlevelScene spawns a background Thread. This thread executes the necessary logic (e.g., Dungeon.newLevel() or Dungeon.loadLevel()). Meanwhile, the main render thread displays a loading animation. Once the background thread completes, the scene transitions to GameScene.
The flow within InterlevelScene is managed by a Phase enum (FADE_IN, STATIC, FADE_OUT).
This flowchart shows how InterlevelScene handles asynchronous loading and manages its internal state to provide a smooth transition.
Sources: InterlevelScene.java:195-231, InterlevelScene.java:311-382
GameScene Internals
The GameScene is the most complex scene, responsible for rendering the entire interactive game world.
Layered Rendering
It uses a series of Group objects to manage rendering order, ensuring that elements are drawn correctly on top of each other. Key layers include:
terrain: The base dungeon floor and water.heaps: Items lying on the ground.mobs: The hero and other characters.walls: Dungeon walls, drawn on top of characters to create a 3D effect.gases: Visual effects for gas clouds.fog: The fog of war obscuring unexplored areas.healthIndicators: Floating health bars and numbers.- UI Panes:
StatusPane,Toolbar,GameLog, etc., which are part of the scene but rendered by theuiCamera.
Sources: GameScene.java:160-185, GameScene.java:230-310
Actor Thread
GameScene separates game logic from rendering by using a dedicated actorThread. This thread runs the main game loop (Actor.process()), which processes turns for the hero, enemies, and other game elements. The main render thread is responsible for drawing the state of the game and updating animations. The two threads communicate to ensure the display is synchronized with the game state. This prevents long-running game logic from causing the framerate to drop.
Sources: GameScene.java:623-652