Skip to content

Game and Entity Configuration Files

Isaac Robinson edited this page Oct 4, 2023 · 3 revisions

What are configuration files?

Configuration files are technically made up of two parts, a configuration file (like a .json file) and a configuration class. In the engine we use FileLoader.readClass to load a given .json file into its respective configuration class.

A configuration class is very simple to write - as it is simply a public class that has certain public properties that outline the information wanting to be stored in said config file. For example:

public class BaseEntityConfig {
  public String spritePath = "";
  public GridPoint2 position;
  public List<String> requiredTextures = null;
  public Vector2 scale = new Vector2(1,1);

  public BaseEntityConfig() {
    //Add defaults here
  }
}

To see examples on how to write .json files see Loading Configuration classes with json.

Default values for a config file can either be set when you declare to property or in the constructor. Please note that if you are using any config loading methods that the constructor is run before it loads the new data into the variables.

{
  "spritePath": "images/oldman_down_1.png"
  "position": {
    "x": 10,
    "y": 10
  }
}

Here is an example of what a json file might look like for a BaseEntityConfig. Notice that you don't have to define all properties here, and if you don't it will use the default value defined in the class.

Using configuration files in the game

Configuration files are used in the game to define levels, game areas, and to store all entity data.

The LevelConfig class

The LevelConfig class is used to store all data pertaining to a specific level. It contains a list of GameAreaConfig variables which outline all the different game areas for that level. This should always have atleast 1 area in it but may contain more. For example, a level may have a main game area, a game area for the inside of a cave and a game area for the inside of a shop. An example LevelConfig json file could look like:

{
  "gameAreas": [
    {
      INSERT GameAreaConfig JSON HERE
    },
    {
      INSERT GameAreaConfig JSON HERE
    }
  ]
}

The GameAreaConfig class

The GameAreaConfig class is used to store all static textures, sounds and map information. Additionally, it stores a reference to a AreaEntityConfig which stores all the entities to be created in this game area. Any textures that are required for a gamearea to run needs to be listed in either the texturePaths or textureAtlasPaths arrays. There is additionally a winConditions list which allows definition of a set of conditions (currently only ResourceCondition) that are required before the player can leave the game area. If this is ommitted from the GameAreaConfig class, there will be no restriction on exiting the area. An example GameAreaConfig json file could look like

{
  "texturePaths": [
    REQUIRED TEXTURE PATH,
    REQUIRED TEXTURE PATH
  ],
  "textureAtlasPaths": [
    REQUIRED TEXTURE ATLAS PATH,
    REQUIRED TEXTURE ATLAS PATH
  ],
  "soundPaths": [
    REQUIRED SOUND PATH,
    REQUIRED SOUND PATH
  ],
  "backgroundMusicPath": "sounds/BackgroundMusic.wav",

  "mapName": "Planet Earth",
  "terrainPath": "map/base.tmx",
  "winConditions": [
    {
      "resource": "Solstite",
      "threshold": 100
    }
  ],
  "areaEntityConfig": {
    AREA ENTITY CONFIG JSON
  }
}

Note that the if using the mapConfigLoader.loadMapDirectory method the areaEntityConfig does not have to be in the same file.

The AreaEntityConfig class

The AreaEntityConfig class is used to store all enemies that exist in a game area. This class contains a hashmap from a String to a List<Object>. The key for this map is the getSimpleName() of the objects configuration class - i.e. "PlayerConfig", "ShipConfig", "ExtractorConfig", etc. For more information about creating entities got to Creating and adding a new entity. An example AreaEntityConfig .json file would look like:

{
  "ShipConfig": [
    {
      class: com.csse3200.game.entities.configs.ShipConfig,
      "spritePath": "images/LeftShip.png",
      "position": {
        "x": 35,
        "y": 40
      }
    }
  ],
  "EnemyConfig": [
    {
      class: com.csse3200.game.entities.configs.EnemyConfig,
      "health": 20,
      "baseAttack": 10,
      "speed": 5,
      "behaviour": "PTE",
      "spritePath": "images/base_enemy.atlas",
      "position": {
        "x": 40,
        "y": 40
      }
    },
    {
      class: com.csse3200.game.entities.configs.EnemyConfig,
      "health": 20,
      "baseAttack": 10,
      "speed": 5,
      "behaviour": "PTE",
      "spritePath": "images/base_enemy.atlas",
      "position": {
        "x": 20,
        "y": 20
      }
    }
  ],
  "ExtractorConfig": [
    {
      class: com.csse3200.game.entities.configs.ExtractorConfig,
      "resource": "Solstite",
      "health": 200,
      "tickRate": 1000,
      "tickSize": 10,
      "position": {
        "x": 20,
        "y": 30
      }
    }
  ],
  "UpgradeBenchConfig": [
    {
      class: com.csse3200.game.entities.configs.UpgradeBenchConfig,
      "position" : {
        "x": 20,
        "y": 40
      }
    }
  ]
}

Alternatively, instead of writing all the entities in a single file you can use the directory model (Recommended) which is outlined here: Loading Configuration classes with json.

Creating and adding a new Entity

To create a new entity follow these steps:

1. Decide on your EntityConfig class

When constructing a new entity type, you have two options:

a. Use the BaseEntityConfig [Not Recommended - this doesn't allow you to easily spawn them in mapGameArea]

This can be used when the new entity does not have any unique properties to the BaseEntityConfig class.

b. Create a new EntityConfig class [Recommended - allows the most flexibility for expansion and spawning]

This will usually be the best course of action as it allows for easy extension in future without large refactoring. This is needed for any entities that have additional properties that need to be saved, such as health, type, damage, etc. Make sure that this extends from BaseEntityConfig. There is also a HealthEntityConfig which can be extended for entities that use the combatStatsComponent

Default values

If your entity has a default value - such as always using the same sprite, same health, etc - consider adding it to the Config class as a default. You can do this by setting a default value to the property:

public String spritePath = "defaultPath.png";

Additionally, if you have used a new class that overrides another config, you can set defaults for properties in that class using a constructor:

public NewEntityConfig() {
    this.spritePath = "defaultPath.png";
}

2. Implement into the MapGameArea

The MapGameArea is the place where a GameAreaConfig json file gets loaded and used. To access a variable within the areaEntityConfig, use the following methods:

public <T extends BaseEntityConfig> List<T> getEntities(Class<T> entityType)
public <T extends BaseEntityConfig> T getEntity(Class<T> entityType)

These methods either return a single entity (if only one of that config type should every be used) or the list of entities. As a parameter you should pass it the type of config file related to the entity you want. I.e playerConfig for a player entity, etc.

Sprite loading

The entity config will automatically load the sprite (located in the spritePath property within BaseEntityConfig), but any extra textures need to be added to the requiredTextures list (also located in the BaseEntityConfig class. This way the map will automatically load all dependancies at initialisation.

Using the factories

All Entity factories should be being constructed with a config file. This allows entities to be saved to json files and reloaded using the factories. If you are creating a new Entity for the game, please also create a factory that is able to be called from a config file.

UML Representation

ConfigurationUML

Clone this wiki locally