Skip to content

Loading rag files into the game

CodePilot58 edited this page Oct 5, 2021 · 2 revisions

Loading levels into the game area is handled by no single class. There are a collection of classes, all working together to read the information from a .rag file to put it into the game. This wiki page will explain what each of these steps are.

Background information

Here is a class diagram containing the classes that are involved with loading in a new level:

Class diagram for classes involved in level loading

And here is a sequence diagram for loading in a new level, starting from when the LevelLoadTrigger tells AreaService to send load to the AreaManager (see Map Generation):

Sequence diagram for classes involved in level loading

So, the overview of the important classes and their usage:

RagnarokArea

This is the GameArea subclass responsible for holding all of our spawned entities. All level entities are spawned in an object of this class.

AreaManager

This is a subclass of RagnarokArea that holds an object of RagnarokArea which it then sends messages to spawn entities into. This class is linked to an AreaService, which means that the Terminal can send messages to it without knowing about the actual AreaManager class. This is the class that the code talks to most, it just relays spawning messages into its RagnarokArea.

Includes a bufferedPlaces variable, which holds all of the lines of information for spawning platforms, floors, rocks, and spikes.

RagLoader

A static class which in its createFromFile(level) function sends the information from a level file to the Terminal.

Terminal

Service (following the Service Locator pattern present in the game engine) that gets and parses string commands sent to it. These commands are then executed once the MainGameScreen calls processMessageBuffer in its update() method.

What this means

So as the sequence diagram outlines, the spawning of entities happens after processMessageBuffer() is called. Each of these messages does something different:

  • config: sets information about the level like its width (AreaManager.bPWidth), height (bPHeight), and world type (AreaManager.currentWorld) as well as letting the AreaManager know when certain sections of the file are finished, like config("close", "init") means those arguments given earlier are all done, and the next stuff will be spawning in terrain.
  • queue: add a line of terrain parts to the bufferedPlaces variable. This comes straight from the .rag and looks something like "..SP..RF", representing a column of the level (read from left-right being top-bottom) and is translated into a String array line {"null", "null", "spikes", "platform", "null", "null, "rocks", "floor"}.
  • spawn: spawn an entity at the given (x,y) coordinates. Type could be "skeleton" or "wolf".

These commands are sent a executed in the order they are read from the .rag file. So configs first, then terrain, then a $@player ... line, then entity spawning.

The $@player ... line is important; it no longer spawns a player but on reading it RagLoader sends a message that the terrain has finished being loaded. makeBufferedPlace is then called.

Once all the commands have been processed, the game continues on as normal having has a new level be spawned.

Implementation

Placing all the terrain

By terrain I mean platforms, floors, spikes, and rocks. These are all spawned into the RagnarokArea by makeBufferdPlace. This function does the following:

  • Iterate through bufferedPlaces to get each terrain piece, with its column and row representing its y and x coordinates int the level respectively.
  • If the terrain piece is a spikes or rocks, spawn them
  • If the terrain piece is a platform or floor, it is more complicated.

Placing platforms or floors

The platforms and floors are spawned in horizontal chunks, so that there is a single hitbox for every line of terrain, the reason why is covered in issue #67. This is done in AreaManager.spawnLineOfMap(...), a function which does these things:

  • Finds out how many rows long that chunk of terrain is
  • Spawns in a floor or platform that long using RagnarokArea.spawnMapChunk(...)
  • Change bufferedPlaces so that all the pieces that have just been placed are 'null' instead of 'platform' or 'floor'.

These blocks of platforms or floors are disposed of by the Wall of Death's TouchDisposeComponent like most other entities. Since they are many entities linked by one 'collider' entity, this entity has a GroupDisposeComponent.

GroupDisposeComponent class diagram

GroupDisposeComponent sequence diagram

This component is a simple one, it holds a list of all entities that it is encompassing. When the collider is disposed of, the GroupDisposeComponent will flag all of the entities in that list for disposal.

Spawning in everything

Becuase of how the levels are loaded and how the TerrainFactory makes the game's coordinate system, all coordinates passed form AreaManager to RagnarokArea are multiplied by a GRID_SCALE to traverse the coordinate systems.

Loading levels sequentially

Loading of levels one after another is handled by the startNextArea variable in AreaManager. This is a simple integer that is set to the end of a level after it is finished loading. Then, any entity has this variable added to its x coordinate on spawning into the game, making it all fit together end to end.

Rag Files

How the rag files are created and saved into the game is covered by the ragEdit tutorial pdf by team 4.

Table of Contents

Home

Student Documentation

Design Document

Graphical Design
User Testing
Sound and Music
Code Design / Documentation
Enemies

Game Engine

Getting Started

Technical Aspects
Entities and Components

Service Locator

Loading Resources

Logging

Unit Testing

Debug Terminal

Input Handling

UI

Animations

Audio

AI

Physics
Game Screens and Areas

Terrain

Map Generation

Concurrency & Threading

Settings

Troubleshooting

Common bugs

MacOS Setup Guide

Clone this wiki locally