Skip to content

Dungeon Generation

Abhinav Pradeep edited this page Sep 3, 2026 · 1 revision

Dungeon Generation

JSON describes the rooms and their connections. The dungeon system builds one active room at a time from rooms.json.

System overview

rooms.json
    ↓ FileLoader
WorldConfig and RoomConfig
    ↓ RoomManager selects one room
RoomFactory
    ↓
Active room entity and its components
    ↓ RoomCreated event
Enemies, obstacles, exits and walls are spawned

The main classes are:

  • WorldConfig: holds the complete room graph and validates its references.
  • RoomConfig: describes one room's size and contents.
  • RoomManager: owns the active room, player, camera and runtime progress.
  • RoomFactory: assembles a room entity from one RoomConfig.
  • TerrainFactory: creates the room's dungeon floor.
  • EnemyManagerComponent, ObstacleComponent and ExitComponent: create the configured room contents.

Starting the dungeon

When MainGameScreen is created:

  1. FileLoader reads configs/rooms.json into a WorldConfig.
  2. RoomManager validates the world references.
  3. It finds startRoomId and startEntryPointId.
  4. RoomFactory creates the starting room entity.
  5. RoomManager.create() registers the room and player.
  6. The room receives a RoomCreated event.
  7. The player is placed at the configured starting entry point.

Building a room entity

RoomFactory.createRoom(room, camera, cleared) builds an ECS entity containing:

Component Responsibility
RoomAssetsComponent Loads the shared dungeon, enemy, fixture and audio assets.
GameAreaDisplay Displays the room title and temporary status messages.
TerrainComponent Renders terrain using the configured width and height.
WallComponent Creates four physics boundaries around the terrain.
FollowingCameraComponent Keeps the camera focused on the player within the room.
ObstacleComponent Creates every configured rock and barrel.
ExitComponent Creates the visible doors and bookshelves.
EnemyManagerComponent Creates and tracks the room's configured enemies.

Terrain and positions

RoomConfig.mapWidth and mapHeight determine the terrain bounds. TerrainFactory fills those bounds with the Fantasy Dreamland floor and applies scattered floor variants.

Every position in JSON is stored in tiles. Components call TerrainComponent.tileToWorldPosition() when placing entities, so the configuration does not depend on renderer scale.

The JSON does not currently choose every individual floor tile. It controls room dimensions and gameplay content placed on top of the shared terrain.

Spawning room contents

Once the room is registered, its components create their owned entities:

  • WallComponent creates four invisible boundary walls.
  • ObstacleComponent reads each obstacle type and calls ObstacleFactory.
  • ExitComponent renders doors and bookshelves at their declared positions.
  • EnemyManagerComponent creates each configured enemy through NPCFactory and tracks it until death.

Entities created by these components belong to the active room. Disposing the room also removes its walls, fixtures, enemies and room-owned projectiles.

Interacting with an exit

Pressing E emits the player's interact event. RoomManager then:

  1. Finds the nearest configured exit within interaction range.
  2. Shows a message if the exit is unavailable.
  3. Blocks entry into an already completed dungeon.
  4. Blocks exits marked requiresClear while enemies remain.
  5. Records the current room as cleared when appropriate.
  6. Records dungeon completion when completesDungeon is true.
  7. Stores the requested destination for the next safe update.

The transition is not performed directly inside the input event. MainGameScreen first completes physics and entity updates, then calls RoomManager.update(). This keeps room creation and disposal outside a locked Box2D update.

Paired doors and arrival

A paired door points to a door in another room, and that destination door points back. WorldConfig.validate() ensures the references are reciprocal and their sides are opposite.

When the transition runs, the player is positioned three tiles inside the destination door:

  • LEFT: move right from the door.
  • RIGHT: move left from the door.
  • TOP: move down from the door.
  • BOTTOM: move up from the door.

This makes returning through a door place the player beside the corresponding physical entrance rather than at a generic room spawn.

Clearing rooms and completing dungeons

EnemyManagerComponent fires roomCleared after all tracked enemies are defeated. RoomManager keeps two small runtime hashsets:

  • clearedRoomIds: rooms that should not respawn enemies.
  • completedDungeonIds: entire dungeons that can no longer be selected.

Debugging transitions

The in-game terminal command below clears every tracked enemy in the active room:

room clear

Table of Contents

Home

Test Plan

Team 2

Features

Components
Player
Items and Inventory
Enemies
Interactable NPCs
Cutscenes and Dialogue
Music
Bosses
Rooms
Weapons
Abilities & Spells
Game Screens and Areas
Dungeons

Game Engine

Getting Started

Entities and Components

Service Locator

Loading Resources

Logging

Unit Testing

Debug Terminal

Input Handling

UI

Animations

Audio

AI

Physics

Terrain

Concurrency & Threading

Settings

Troubleshooting

MacOS Setup Guide

Clone this wiki locally