Over the past two weeks I have been conducting a great deal of engineering work on Ancient Armies to get it ready for the implementation of column movement.
It all started when I was looking at a bug with the fatigue system. This is the bug that my new telematics system picked up a few posts ago where fatigued units were not regaining their freshness after exertions.
Whilst probing around the fatigue system I was horrified by the fact that the code for it seemed to be literally everywhere! Having the code for a single subsystem littering an entire game can make it very difficult to understand, debug and can of itself cause many other engineering problems further down the line.
An inspection of the cohesion subsystem revealed a similar issue.
I was mortified. I’m typically very hot on software coupling and cohesion. I guess it was just the way these two subsystems had evolved over time.
In the interests of simplification and maintainability, I decided to completely refactor both of these subsystems so that they are both located in one place within their own respective classes.
Doing this was a non-trivial affair, it involved grabbing bits of code from all over the system and moulding them into a singular coherent class.
It took a fair bit of time but the rewards have more than made up for it.
For a start, it made fixing the fatigue system incredibly easy:
For the first time, fatigue in the game is now being recovered properly after a unit’s exertions. The screenshot above shows the game providing real-time data to my telematics application on the right. This shows two units exerting and then resting with their fatigue levels doing exactly what I expected them to!
The telematics application has been a God-Send. For a start it originally discovered this issue, something that would have been very difficult to spot with standard tools. But more importantly, it also easily verified that my fix was working!
To try and prove this code fix was working from within the code editor would have been a tedious and time consuming affair. But with telematics, it is as easy as running the game and viewing the results!
The telematics system also came to the rescue with cohesion too:
After the refactor of the cohesion subsystem, the graphics weren’t showing a unit’s cohesion levels properly. A quick run up of the telematics application proved that there was nothing wrong with the underlying modelling and that it was in fact an update issue to the graphical subsystem!
Again, without telematics, this would have taken much longer to determine as it would have been difficult proving that the cohesion system was working properly over time.
The other tooling to provide great assistance was my new automated build process – as introduced in the previous blog entry. Seeing the installers magically appear on my NAS drive after committing code never grows old. Nor does being able to tell exactly which version of Ancient Armies I’m running! Both of these seemingly small details, go a long way to making the job of cracking bugs a lot easier.
Although the refactoring of the fatigue and cohesion subsystems took two weeks, it leaves the software in a much better state.
For a start, all the complexities of cohesion and fatigue modelling are encapsulated and hidden away within their respective classes. None of the rest of the system needs to know how they work. Even when I’m calling these sub-systems, I no longer need to memorise how they work as it is all nicely tucked away.
When other systems within Ancient Armies call fatigue and cohesion, they can now ask simple questions like, is a unit fatigued? or exhausted? and they can do so without having to do any of the sums themselves. This helps to simplify the code and to ensure that one achieves consistent results throughout the game.
The other big bonus from the refactor, is that if either sub-system needs tweaking in the future, I know exactly where to go – they are both housed in their own files. More importantly, I only need to learn what the code is doing in that one file to fully understand the subsystem. This is far easier than traipsing through the entire game’s codebase trying to work out what’s going on!
Finally, in what seems like a long journey, I am now in a position to start work on column based movement. So tune into the next post to see some of the early results from my efforts.