This month has been consumed by automated testing and pathfinding.
It is difficult to create units which are unique and balanced. This is important for a multiplayer game, and being a solo developer I have to make tools to test the design assumptions I have created.
In generic software development automated testing allows programmers to quickly check their code is returning the right data. In an environment as complex as Real Time Strategy games, where soldiers navigate a 3D environment in real time, there are so many variables to consider, that the only way to investigate is to run gladiatorial test matches.
I created a user interface to easily customise tests. Each test places a number of units at either side of a small map. The number is determined by their cost (value). The units immediately rush to attack the other team, until one side has none left. The code then calculates who has won, and by how much, and saves that to a text file. This means I can run hundreds of tests overnight and examine the results in the morning, providing a rough measure of whether a unit type is too strong or too weak.
In any game it is unlikely that battles will just be between individual units, so each test creates multiple units, and places them at random locations. Each pairing is then repeated a number of times to provide an average result, which should be more accurate.
Pathfinding has been something else. The old system generated one path per unit, which clearly will not scale if hundreds are involved. Instead, I followed the Flow Field design described by Elijah Emerson, published in ‘Game AI Pro’.
Each map is divided into sectors, which contain tiles. Sectors connect to other sectors via portals (green dots, white lines show connections). Red lines show the flow fields themselves. Each tile has a direction, and when units enter that tile they read the direction they should be facing.
The path visualised above shows the directions five units from the top right must travel to arrive at their goal in the bottom left. Each unit starts in its own sector. But there could be five or ten units in each sector, and yet the cost of generating the path remains the same. The advantage is a considerably more efficient means of moving large groups from A to B.
Initially, it took as long as 100 milliseconds to generate a path for one unit moving along that distance. After some optimisation, the worst case was reduced to 1.5 milliseconds.