Skip to content
Jantoom edited this page Oct 19, 2021 · 4 revisions

Introduction

An essential part of the game's design is ensuring that the level is consistent with the intended themes and emotional objectives. To stay consistent with the goal of placing the player in the shoes of a kid in their home, the terrain and its population should resemble the interior of a house.

This class supersedes [ForestGameArea] by delegating level design to JSON files over the inflexible Java classes.

Technical Explanation

Conceptual design of the Floor class

If we imagine how an entire GameArea translates into the Home concept of the game, we conclude that each game area is effectively one "floor" of the home. In the case of the first floor, this includes the front/backyard and anything else outside the house. We also conclude that one floor consists of many "sub-GameArea's" (i.e. rooms).

The Floor class is meant to extend the existing purpose and functionality of its superclass, GameArea. This including handling the spawning the tiled terrain, and spawning numerous entities on top of it.

The [Room] class doesn't extend GameArea because it is much more straight-forward to have just one Renderer per Floor, along with many other implications.

Defining a Floor using JSON deserialization

The Floor class implements the Json.Serializable interface to allow for de/serialization of Floor instances. We do this instead of the way the terrain and entities were handled in ForestGameArea because levels at this stage of development are much more sophisticated and need a more readable way of describing itself.

Floors are expressed in their own JSON files in the "maps/_floor_plans" directory. Adding more JSON files using the custom format below will add more floors to the sample size used by the random generation algorithm, which will enhance the feeling of randomness.

defaultInteriorTile

This object is used when rooms don't define any of their tiles. We assume that the file intended for the general floor tile to be used in place of the missing tile. This allows us to synchronize the floor texture for several rooms without these rooms having to coordinate with each other. For example, a wooden floor texture can be carried over from a dining room to a living room without either of these rooms having to specify what texture they want. This is important given the randomness of the rooms selected; if every room had to specify its main floor texture, then we could run into funky configurations where the incoherent wooden floorboards are used on the same floor.

The other purpose for this definition is specify hallways. Due to the variability in hallway dimensions, it is nonsensical to serialize every possible hallway. So, creation of hallways assumes its floor texture is that of the floor's default texture.

defaultInteriorWall

This object is only used for specifying the wall texture for hallways. It is assumed that rooms handle their own walls.

tileMap

This is an ObjectMap of Characters to GridObjects. Objects in this map are typically used for defining textures for tiles that do not belong to any room. This usually corresponds to terrain outside of the house. For example, a grass texture can be specified at the Floor JSON level to populate the front and backyards of the house.

entityMap

This is also an ObjectMap of Characters to GridObjects. Objects in this map are typically used for defining the southern/eastern exterior walls of the house. Due to isometric view, we can't see the southern/eastern facing interior walls of a room so these walls must belong to the object that has these wall positions as their northern/western facing ones.

The entities in this map can also be used to override the entities defined at the Room JSON level. A good example of this is specifying where doors should go because rooms have no reference to where they should be without knowing what floor they are part of. Another example is overriding an entire room wall to create an open-space; by replacing these grid points with a dummy/non-existent GridObject, an entity simply won't spawn there.

roomMap

This is an ObjectMap of Characters to Rooms. Each room must have a type, offset and dimensions. This puts individual rooms in relation to one another.

Valid room types are specified in Room. The offset is relative to the floor grid specified in the JSON file (i.e. top-right corner is 0,0 and bottom-right corner is Y,0 where Y is the largest vertical index). This is converted to x,y internally so developers can use the libGDX plugin's JSON skin to quickly locate a y,x coordinate. The dimensions are simply the x,y (not y,x) dimensions of the room. This should include all overridden grid points of the room.

Earlier versions of the Random Map Generation System had room types non-specified in the floor plan. The logic was to have an algorithm that could add another layer of randomization by randomly choosing what type of room they could be, but also ensuring that typical room adjacency properties are met (e.g. a bedroom's only entry/exit would never be a bathroom or a garage). However, this algorithm would rarely yield room configurations that did not match the most common, preconceived configuration so it was scrapped.

floorGrid

This is a Character grid representation of all tiles and entities defined at the Floor level. All Characters specified in the above maps are placed in this grid. It is important that room characters match the room definitions in the room map.

Typical JSON file format

{
  defaultInteriorTile: {
    // Custom GridObject serialization
  }
  defaultInteriorWall: {
    // Custom GridObject serialization
  }
  tileMap: {
    ?: {
      // Custom GridObject serialization
    }
    ...
  }
  entityMap: {
    ?: {
      // Custom GridObject serialization
    }
    ...
  }
  roomMap: {
    ?: {
      // Custom Room serialization
    }
    ...
  }
  floorGrid: {
    // Default JSON Character grid serialization. Note that special tile/entity
    // symbols overriding room symbols will not override tile ownership, 
    // only entity ownership. This is to ensure that the correct tile texture 
    // is placed in the room, and the floor plan can decide to place a door
    // instead of a room wall
  }
}

Calling create( ) post-deserialization

When create( ) is called, every Room in the room map also has create( ) called. Much like ForestGameArea, all assets (from every source related to the floor) are subsequently loaded and the UI related to the floor is displayed. Then, all tiles are set before the entities are spawned into the world. After this, subsequent calls to create( ) will do nothing.

Spawning all tiles

All tiles are spawned using the spawnGridTile( ) method. This method invokes the creation method specified by the GridObject then adds the returned Tile to the map layer. Room tiles are created before tiles that are defined at the Floor level.

For these tiles, each Character is searched for in the tile map. If it is found, then that GridObject is passed to spawnGridTile( ). If not found, then the Character is lastly searched for in the entity map. If so, then the default interior tile is assumed to be the texture underneath. This only happens if the cell at that coordinate was not already set by a room earlier. If the Character is again not found, nothing happens.

A TerrainComponent is created with this information and then spawned into the world. All tiles are now visible by this point.

Spawning all entities

Firstly, the player entity is created in consideration of any dependencies on it throughout the codebase. All tiles are spawned using the spawnGridEntity( ) method. This method invokes the creation method specified by the GridObject then spawns it into the world. Like spawning all tiles, room entities are spawned before entities defined at the Floor level.

For these tiles, each Character is searched for in the entity map. If it is found, then that GridObject is passed to spawnGridEntity( ). If not found, nothing happens.

Finally, any entities that are not defined in any prefabricated JSON files are spawned into the world. This includes the player, cat and mum entities. Basic obstacles are spawned along the outside of the map to prevent any entities from leaving the main game area.

Clone this wiki locally