Helios AI Battle Engine Summary

👍

Reminder - Keep Daily Backups

When working on a strategy game with a kit as big as the Complete Kit - always keep a working daily backup! Save yourself the trouble of rolling-back changes and losing work.

What is Helios?

One of the most complex components in the City Building Kit is the Helios AI battle engine located at Scripts/Helios/Helios.cs. The Helios engine's purpose is to coordinate and centralize, as much as possible, all operations regarding a strategy battle game.

The idea behind Helios was to reduce the processing load necessary for the units and to individually keep track of their goals, since we expected it to become a problem/add up when hundreds of units are instantiated.

This centralized processing script is a powerhouse and fully editable. Plus, editing for developers is simplified with all functions under one centralized umbrella.

Helios handles diverse situations such as:

Scenarios:
A new group of units is instantiated – the nearest building location is sent to them to attack
A building is destroyed – the unit groups attacking the building are reassigned to another target (if any)
The player selects a building – the nearest group of units is ordered to attack the new target
The player selects a group, and then points to a building – the respective group is sent to attack that building

All About the Helios Engine Functions

As the Scripts/Helios/Helios.cs is a huge engine that controls all of the components of battle, we've added a breakdown of the 50+ functions in Helios with a short description about what each does in the list below.

As Helios is a huge component, we recommend you play a battle to truly understand how these functions all flow together for a seamless battle strategy game experience.

FunctionDescription
void Talk(string text)Shows the text in the Chimera corner text box.
IEnumerator GarbleMessage()Garbles the Chimera text, called after a building is destroyed. (Just for special effects, no real purpose)
void Select0()Runs when the user first deploys the 1st group. Initiates the group button and auto-selects the group sprites.
void UserSelect0()Called when the user selects the 1st group button. Group units show a star above their sprites. If no units, disables this group button.
void Select1()Runs when the user first deploys the 2nd group. Initiates the group button and auto-selects the group sprites.
void UserSelect1()Called when the user selects the 2nd group button. Group units show a star above their sprites. If no units, disables this group button.
void Select2()Runs when the user first deploys the 3rd group. Initiates the group button and auto-selects the group sprites.
void UserSelect2()Called when the user selects the 3rd group button. Group units show a star above their sprites. If no units, disables this group button.
void Select3()Runs when the user first deploys the 4th group. Initiates the group button and auto-selects the group sprites.
void UserSelect3()Called when the user selects the 4th group button. Group units show a star above their sprites. If no units, disables this group button.
IEnumerator DisableGroupButton(int i)Waits for a second before disabling the group button.
void Delay()Runs Relay.cs DelayInput() function.
void ResetGroupLabels(int index)Cleans up and resets the group labels (4 group controls)
IEnumerator GetFirstBuilding()Finds the first building for the AI to attack
void NetworkLoadReady()First function run in Helios. Called by SaveLoadBattle.cs to initiate Helios.
void PrepareBuildings()Prepare buildings for battle, health and disabling any damage effects
void PrepareLoot(string buidingType)Prepares the total loot for the base and sets it in the battle variables. Chimera talks this value out, and destroying buildings disburses a portion of this total value based on the building currency type.
void FindSpecificBuilding()When the player taps on a building, tells the unit group selected to find this specific building
int FindNearestGroup(Vector2 newTargetPos)Finds the closest group to the new target building, gives up if there are no units deployed
void FindNearestBuilding()Check for buildings or weapons to destroy. If none, starts coroutine MissionComplete
int GetBuildingListIndex(int buildingIndex)translates a real buildingIndex (ex: 32) into a possibly smaller list index (ex:2), this happends when the user builds and destroys buildings - the buildingIndex grows
void KillUnit(int groupIndex, int unitIndex)Remove dead unit from group and play kill sound
void RemoveFromDeployed(int unitIndex)Dead unit, remove from the list
void SearchAliveBuildings()Check if there are any buildings left that haven't been destroyed. If none, start coroutine MissionComplete()
void SelectTargetGrid()Find a new object's grid coordinates for unit pathfinding to attack.
void MarkAsPassable(Transform transform)Sets the grid coordinate as passable for pathfinding (no object in the way)
void CopyTargetLists()Copies the target list to every unit in the group (depending on the group)
void ResetSurroundIndex()sets surroundIndex[selectedGroupIndex] = 0;
void StopUpdateUnits()sets updatePathMaster to false (controls path updates)
void StartUpdateUnits()Starts the Coroutine "ResumeUpdateUnits"
void UpdatePaths()Changes the pathfinding target for units and assigns the path.
void ResetUpdatePaths(int index)Rests the pathfinding update
void Update ()Major core function - called once per frame. Continuously updates everything necessary for gameplay from unit totals to structure destruction and so on. This is a big function, anything you need updated continuously put here.
void AdjustRubbleZ(GameObject rubble)Fix for the destroyed building sprite.
void UpdateUnitsNo()As troops die, updates the Unit total under the groups buttons
IEnumerator LateProcessUnitGroup(int index)If deploying troops, waits for a period of time before processing the group.
void ProcessUnitGroup(int index)Determines if the group still has units. If it does, check if all buildings are destroyed with SearchAliveBuildings(). If not, FindNearestBuilding() and start pathfinding.
void UpdateSelectStars()If you switch between groups - highlights the new group with stars above their HP.
void UpdateGroupPosition(int index)If there's still units in a group, updates their position.
IEnumerator UpdateTargetGroup(int index)Waits 1.5 seconds. Automatically updates a new target if a building was destroyed by the AI.
void UpdateTarget(int index)Updates target for the group in control
IEnumerator ResumeUpdateUnits()Waits for 0.3 seconds and resumes pathfinding
void DisablePanels()Deactivates all panels.
void Retreat()Retreat button clicked in the UI. Initiates MissionComplete
IEnumerator MissionComplete()Finishes battle. Marks all units as idle and runs ActivateEndGame()
void ActivateEndGame()Sets the MissionCompletePanel as active with and fills it with the battle results.
void AllUnitStars(bool b)Set stars above all units. (means all selected)
void SelectedUnitStar(bool b)Shows a star above the selected group as active.
void AllUnitsImmortal(bool b)Developer hack. Sets all units as immortal. Called from GUI buttons.
void SelectedImmortal(bool b)Developer hack. Sets selected unit group as immortal. Called from GUI buttons.
void AllBuildingsIndestructible(bool b)Developer hack. Sets life as nearly indestructible for all buildings. Called from GUI buttons.
bool ExistingBuildingStar(int i, bool b)Check if star effect above building exists, destroys.
int GetBuildingIndex(int listIndex)Returns the buildingIndex variable from StructureSelector
void CreateBuildingStar(int index)Initiates 3D star effect above building.
void ProcessBuildingStar(GameObject BuildingStar, int i)Sets the effect to the building.
void CreateorDestroyStar(int index, bool b)Destroys star effect.
void SelectedIndestructible(bool b)Developer hack. Sets life as nearly indestructible for selected building. Called from GUI buttons.
void AllStop()Developer hack. Used for testing. Stops all battle actions. Called from GUI buttons.

Other functions of Helios...

In addition, Helios performs smaller functions, like processing the loot as the buildings are damaged, keeping track of battle end conditions, retreat orders, destroyed units, ordering cannons to fire when a building is under attack, etc.

800

Group orders. Click on image to view larger

There are several optimizations in place:

  • Sending the new targets to units is done in sequence, so the units don't look for their path all at once
  • All the calculations are done at 1 second intervals.

AITarget Cubes for Pathfinding

Each grass prefab has target cubes and obstacle cubes – to send the units to those grid locations, or to mark the pathfinder grid properly with locations the units can not walk on. These cubes have their mesh renderers disabled, but they can be enabled so you can see them.

The AITarget cubes are necessary for the units to know where to go – to which square in the pathfinder grid - to attack a certain building.

Also there is a “surround” function who makes the units occupy each grid, starting with the nearest.

800

Bounds surrounding the object. Click on image to view larger

Unit Lists

The units are kept in lists – one general list, and then individual lists for each group. Most operations require processing only one of the groups, but there are orders that are passed to all.

  • DeployedUnits – all deployed units, regardless of their group
  • GroupO, GroupI, GroupII, GroupIII

Unit Groups

The position of each group is given by the first element in the list - GroupO[0] – this is a simplification, since the units can be spread on the entire map before attacking a building.

Units will all converge on the same building, chosen as the current target.

800

Click on image to view larger

The targets for each group are kept in an array -

targetBuildingIndex = new int[unitGroupsNo];

This array will contain the building indexes under attack by each group, for instance {5, 12, 2, 4}.

Since the user can both build and destroy buildings on his initial map, in which case the building index just grows, the building indexes are not necessarily in order, from 0 to the number of buildings.

Since most of the lists in Helios are created on the fly when the map is loaded, there is a translator, who translates the actual building index, stored in the BuildingSelector, to the continuous list index (from 0 to total number of buildings) we have:

GetBuildingListIndex(int buildingIndex)

For more details about PvP Battles...

Please select the topics under PvP Battle Matchmaking on the menu bar on the left, or Online Server Sync. These two sections describe everything there is to know about how the strategy elements work, and how online server sync allows players to challenge other players and how you can manage it all from one simple interface.