Tile Based Level Map Reference - UQcsse3200/2026-studio-1 GitHub Wiki

Tile-Based Level Map: Technical Reference

LevelMapData

LevelMapData is the parsed, render-independent representation of a level. A MapLoader reads a map file and returns a LevelMapData holding the level's dimensions, its legend of tile definitions, its ordered list of layers, and its spawn data. It has no rendering dependencies, so it can be created and asserted on in unit tests without a graphics context. The renderer and collision systems both read from it. All classes live in the package com.csse3200.game.areas.terrain.map.

How it fits together

flowchart LR
  F["maps/*.json"] -->|"JsonMapLoader.load()"| D["LevelMapData<br/>(pure data)"]
  D -->|"TerrainFactory.createTerrainFromMap()"| R["TerrainComponent<br/>(renders layers)"]
  D -->|"LevelGameArea.spawnCollisions()"| C["Tile colliders<br/>(SOLID / PLATFORM / HAZARD)"]
  D -->|"getSpawns()"| S["Player / enemies / loot"]
Loading

LevelMapData is the hub: the loader produces it, and the renderer, collision, and spawning systems all read from it.

Map data model

The data model is made of small, focused classes.

Class Purpose
LevelMapData The whole level: name, tile size, dimensions, legend, layers, spawns.
MapLayerData One named layer holding a grid of TileDefinitions (null = empty).
TileDefinition A legend entry: a TileType paired with a texture path.
MapSpawns The player start plus lists of enemy and loot SpawnPoints.
SpawnPoint A single spawn: an optional type name and tile coordinates.

Key LevelMapData accessors

Method Returns
getWidth() / getHeight() Level size in tiles.
getTileSize() World units per tile.
getLayer(name) A layer by name, or null.
getCollisionLayer() The collision layer, else the terrain layer.
getTileType(x, y) The collision-relevant tile type at a cell, or null.
getSpawns() The MapSpawns for this level.
getTexturePaths() Distinct tile textures to load.

Loading a map

Maps are loaded through the MapLoader interface, so alternative formats (TMX, overworld maps) can be added without changing callers. JsonMapLoader is the default JSON implementation. Its parsing step is exposed separately from file access so it can be unit-tested without libGDX:

public interface MapLoader {
  LevelMapData load(String path);   // throws MapLoadException
}
// Load from an asset file:
MapLoader loader = new JsonMapLoader();
LevelMapData map = loader.load("maps/demo.json");

// Or parse a string directly (used in tests, no graphics context needed):
LevelMapData map = new JsonMapLoader().parse(jsonText);

A missing, unreadable, malformed, or structurally invalid map throws MapLoadException.

Map file format

{
  "name": "Demo Level",
  "tileSize": 0.5,                 // world units per tile
  "legend": {                      // symbol -> tile definition
    "#": { "type": "WALL",     "texture": "images/wall_px.png" },
    ".": { "type": "DECORATIVE","texture": "images/bg_decor_px.png" },
    "=": { "type": "PLATFORM", "texture": "images/platform_px.png" },
    "^": { "type": "HAZARD",   "texture": "images/hazard_px.png" }
  },
"entityLegend": {
    "P": {"type": "PLAYER"},
    "S": {"type": "ENEMY","enemyType": "skeleton"},
    "R": {"type": "ENEMY","enemyType": "ranged-skeleton"},
    "L": {"type": "LOOT"}
},
  "layers": {                      // drawn back-to-front; rows top->bottom
    "background": ["....", "...."],
    "terrain":    ["####", "#  #"],
    "entities:    [" S    L   P "]
  },
}

A space, or any character not in the legend, is an empty cell.

Layers and draw order

Layers are drawn back-to-front in the order they appear in the file. The collision system reads the collision layer if present, otherwise terrain.

flowchart LR
  A["background<br/>(drawn first)"] --> B["terrain<br/>(walls / platforms / hazards)"] --> C["foreground<br/>(drawn last, over the player)"]
Loading

Entity Layer

In sprint two the entity layer was added. Older maps that use the coordinate based spawns system are still supported and are dominant, but this allows for the location of the entities to be explicitly chosen rather than calculating coordinates.

Tile types

Each tile is one of five TileTypes, each mapped to a CollisionType.

FLOOR

Passable ground the player walks and stands on. Collision type SOLID.

WALL

A solid tile that blocks movement. Collision type SOLID.

PLATFORM

A support surface the player can stand on. Collision type PLATFORM.

HAZARD

Passable, but triggers damage on contact via the player's CombatStatsComponent. Collision type HAZARD.

DECORATIVE

Visual-only scenery with no collision. Collision type NONE.

Tile differences

Tile Solid Damages Drawn
FLOOR yes no yes
WALL yes no yes
PLATFORM yes no yes
HAZARD no yes yes
DECORATIVE no no yes

Coordinate system

Layer rows are written top-to-bottom for readability; the loader flips them so the game uses a bottom-left origin — the top row in the file becomes the highest y, the bottom row becomes y = 0. Spawn coordinates are already in this world convention (x right, y up).

flowchart LR
  subgraph File["File rows (top → bottom)"]
    direction TB
    r0["row 0  (top)"]
    r1["row 1"]
    r2["row 2  (bottom)"]
  end
  subgraph World["World tiles (y up)"]
    direction TB
    y2["y = 2"]
    y1["y = 1"]
    y0["y = 0"]
  end
  r0 --> y2
  r1 --> y1
  r2 --> y0
Loading

Creating a level

There are two ways to bring a map into the game.

1. Play a map as a game area — LevelGameArea loads the map, renders it, builds tile colliders, and spawns the player and enemies from the map's spawn data:

TerrainFactory terrainFactory = new TerrainFactory(renderer.getCamera());
LevelGameArea area = new LevelGameArea(terrainFactory, "maps/demo.json");
area.create();

2. Build just the terrain from already-parsed map data (e.g. for a custom area):

LevelMapData map = new JsonMapLoader().load("maps/demo.json");
TerrainComponent terrain = terrainFactory.createTerrainFromMap(map);

Each MapLayerData becomes one tile layer, drawn back-to-front, with tiles typed by their TileType. The map's tile textures must be loaded into the ResourceService first.

Implementation

Source:

  • source/core/src/main/com/csse3200/game/areas/terrain/map/ (data model and loader),
  • areas/terrain/TileType.java and CollisionType.java (tile definitions), and
  • areas/LevelGameArea.java (the game area). Unit tests: src/test/.../areas/terrain/map/.
⚠️ **GitHub.com Fallback** ⚠️