Entity Configuration

In order to configure multiple different types of units and buildings, we follow a data-drive approach in which data assets are used to define all the data that entities use at runtime.

For example, the configs will contain values such as which mesh the entity is using for rendering, it's maximum health per level, it's movement speed, etc.

Configurations are set up in a modular approach so that we can reuse them amongst similar entities. For example, the movement configuration (URTSBoidConfig) is a separate configuration that can be reused by multiple units if they share the same movement stats.

1. Entity Config

The URTSEntityConfig is the base configuration class for both units and buildings, and contains shared data such as health, UI selection data (description, portrait, etc). Some relevant parameters are:

  • Entity Class: Specifies the actor subclass that will be spawned from this configuration. Should be set to ARTSUnit for example, if we're configuring a unit.
  • Default/Heavy Armor: Collection of values containing types of damage and their armor values. It is used when doing damage calculations. The armor value is a number between 0 and 1, which will be multiplied by the damage to attenuate it.
  • Weapon Set: Map of targetable configs and the weapon that will be used when attacking that entity. For example if we define a weapon with URTSBuildingConfig as key, this weapon will only be used when attacking buildings but not units. Define a weapon for URTSEntityConfig in order to have a default weapon that can be used against any entity.

1.1. Unit Config

The URTSUnitConfig is a derived class from the Entity Config, and defines data for all units. Some relevant parameters are:

  • Rendering Mode: For performance reasons, we cannot just render skeletal meshes for all units, since the cost to compute animations on the CPU is quite high. We therefore have two rendering modes available:
    • Skeletal mesh: Recommended for heroes and monsters, since those are low in number and will look slightly better. Uses regular skeletal meshes and anim instance for animations.
    • Static mesh: Implemented using Turbosequence plugin, it renders skeletal meshes as Niagara static meshes, really performant. Recommended for units in battalions.
  • Banner Carrier Config: Config to spawn banner carriers. If blank, no banner carrier will be spawned when leveling up.
  • Unit/Battalion state tree class: The state tree component class used for the AI. It is highly recommended that ALL units share the same class, so don't modify unless there is a explicit reason to do so.

1.2. Building Config

The URTSBuildingConfig is a derived class from the Entity Config, and defines data for all buildings. Some relevant parameters are:

  • Collision2D and Avoidance Points: This ones are calculated at editor time (use call-in-editor function CalculateCollision()) to bake collision data from the mesh. It will be used as static geometry data in movement calculations.
  • Mesh Collision: Simplified mesh used for collision (selection linetracing) and navigation.
  • Navigation mesh small/big: Generates navigation modifiers at the specified scale so that battalions don't try to get too close to buildings when pathfinding.
  • Navigation mesh small/big scale: Scales the navigation meshes. This allows us to reuse the mesh collision asset and just fine-tune the extent of the navigation modifiers by this values.

2. Boid Config

The boid config defines how units move in the boid (movement) simulation. Here, we have values for speed, max speed, acceleration, and we can also define the boid movement rules (arriving to destination, collision, avoidance etc):

  • Mass Config: Reference to mass entity configuration. It should be the same for all boids, so do not modify.
  • NavigationQueryFilter: The navigation filter used when pathfinding. It is recommended to use the single unit one for heroes and monsters, which ignores the buildings navigation areas, and use the battalion one for battalions, which tries to avoid getting too close to buildings.
  • Formations: Array of formations that the unit can use. Use SingleUnitFormation for single units (heroes, builder etc.). This probably will be converted into a single reference since formation switching will be done through abilities.
  • Rules: List of rules for boid simulation. See the documentation for boid simulation for detailed information.
  • Battalion rules: List of rules for battalion movement simulation. See the documentation for boid simulation for detailed information.

3. Formation Config

This one determines how many units exist in a battalion, and how they are positioned in formation. Contains mostly positional data for unit slots, banner carrier position, etc.

  • Formation: Two-dimensional array representing rows and columns in a formation. The first dimension of the array defines how many rows/lines we have, and the second defines each slot per each line. It is highly recommended that we define rows from front to back, and slots in each line from left to right, so that all the logic related to adding/removing units, reversing formation and switching formation works efficiently. It is also recommended that the formation is layout around the (0, 0) position, so for example if there are three rows in the formation, the first one could be (200, x), second (0, x) and last one (-200, 0). This ensures that turning the formation around is smooth.
  • Formation center position: Will be used to calculate collision against other battalions. It is recommended that it's on the (0, 0) position or close.
  • Formation radius: Will be used to calculate the collision bubble around the battalion. Recommended that it encompasses all units inside the formation tightly. Use debug visualizers to adjust the value in game.
  • Reverse formation on big turn: If the formation turns 180 degrees, we usually want to "reverse" the formation (meaning, that front row becomes last row etc) so that units don't have to cross each other. Recommended to be set to true unless it's a single unit.
  • Formation size: It is automatically calculated in the editor when modifying the formation slots, and will determine how many units are in a battalion. It is not possible to use a smaller battalion size with a bigger formation.

4. Weapon Config

Defines the data necessary for damage and combat calculations, such as damage type, amount, wether the weapon does Splash/Area of Effect damage, knocks back units, etc.

  • Pre-attack delay: Time in seconds between the unit being ready and in position, and the actual attack starting.
  • Attack duration: How long the attack lasts in seconds. Attack duration comprises the time in which the animation starts playing, hits, and finishes. During this time, the unit is blocked from performing other orders.
  • Hit times: Once that attack duration time has fired, how long until the damage is actually dealt. Supports multiple hits on the same attack.
  • Reload time: Time in seconds after attack duration until the next attack (will go back to pre-attack delay).
  • Damage execution calculation: GAS class to calculate damage. There is only one available, so use that one, already contains all necessary damage and armor calculations.
  • Targeting mode: How this unit selects enemies:
    • Closest: Will get the closest enemy unit.
    • Random weighted to closest: Select a random enemy, but giving more priority to the closest ones. Recommended for ranged battalions to avoid overshooting one target.
  • Animations: The animations played when using this weapon. Animations contain a "hit time" that has to be input, and should be the visual moment in the animation where blow is dealt. It is used to sync the visual damage time in the animation, with the actual damage logic hit (hit times).
  • Radius and splash damage: If splash damage is active, it allows us to define a series of radiuses and the damage that will be applied to each radius. For example, we could have main damage of 400 for the main target, then 200 damage up to 200 distance units, and then 100 damage up to 400 distance units.

4.1. Simple ranged weapon

Ranged weapons that don't require physics or complex projectiles (basically, normal ranged units such as archers or heroes such as Legolas) should use this configuration. It will spawn a projectile that always hits the target and doesn't collide with enemies in the way. Basically it acts exactly the same as a melee attack, but delaying the damage until the projectile hits the target.

  • Niagara mesh index: Since the projectiles are rendered as Niagara particles, we need to define the arrow meshes in the emitter and copy the mesh index here. Will probably be automated in the future.
  • Mass config: Since projectiles are logically represented as mass entities, they all should use the same projectile mass configuration.

5. Sentry spawner Config

Some entities such as wild lair buildings, can spawn units that patrol the entity and protect it. The spawner config defines this behavior, and can specify which entities are spawned, the time to revive them if killed, etc. Although it can be attached to any entity, it's most likely going to be used with buildings.

  • Producing creeps: array of units that will be produced by this component. If you want multiple units from the same type to be produced, just add two identical items to the array.