GameDev Week 1: OOP and Delegates

James Kim
6 min readApr 24, 2017

After struggling with an overly ambitious project, I thought I would start off with a much more simpler project: a tower defense game for mobile devices.

In this series of weekly blog posts, I will be trying to document my bad and good attempts at programming, drawing and designing games. Keep in mind that I have just started learning programming this year, so my approaches may not be optimal. I would be love to hear any criticisms or suggestions.

This week, I have worked on the basic structure for my game. While it is rather crude looking at the moment, it is made in a way that users can customise and change the AI the way they want. For example, they may want their turrets to attack a point:

Instead, they may also want the turrets to only attack the nearest enemies.

Or they may just want their turrets to just rotate around like a helicopter, unleashing your own bullet hell upon the enemies.

you spin me right round

Players can also customise the AIs and switch between them by clicking on individual turrets or pressing a button. Also, projectiles loaded in each turret are full customisable too.

Implementation: OOP and delegates

I thought this would be the perfect time to practice OOP(Object Oriented Programing). I have two separate JSON databases at the moment: one for turrets and another for projectiles. The UI (mostly non-existent at the moment) takes user Inputs and query the databases for parameters. The parameters are taken to the Turret class and the class is initialised using those parameters. Depending on the parameters, the Turret class adds necessary components to itself like Attack, AI handling, or rotation. Each component is only dependent on the Turret class and nothing else.

I guess this is how OOP works? The thing that took most of my week was figuring out how the AI system was going to work. I wanted the players to be able to fully customise the AIs of their turrets. This meant that the each AI action had to be fully independent so that each command would play well with each other no matter what order they were in.

Flexible AI customisation

Turret AI behaviours can broadly relate to either‘targeting’ or ‘attacking’.

Targeting AI is a crucial AI component in Tower Defense games. These are commands like ‘find the nearest enemy’, ‘find an elite-type enemy’ or ‘find the enemy with the most hp.’

After finding the enemy, the tower also needs to attack it. However, there are different attack behaviours. For example, when a player wants a tower to ‘find the nearest enemy, then attack until it dies’, then the tower needs to be know to override ‘find the nearest enemy’ command with ‘Attack’ command until the enemy dies.

There are also other behaviours like ‘aim at the selected location’, ‘aim at the selected enemy’, or ‘rotate like a helicopter.’ These would all have to play nicely with each other, no matter what order they were in.

To make this possible, I broke down the commands into the smallest components reasonably possible. For example, the command ‘find the nearest enemy’ was divided into three functions: a function that finds all the enemies in the sensor range, a function that finds all the visible enemies, and a function that finds the nearest enemy. Each component is completely independent and re-usable. If I want to construct a new command like ‘find a random enemy’, only thing I have to do is to create a function that calls on these individual functions.

Simple and easy.

I have tried many (misguided) ways to make all my functions completely independent, including static functions, lists that takes a list and returns a list combined with coroutine queuing, (… other various stupid approaches.. ), and finally ending up on delegates with a dictionary of Ienumerators.

Lists within lists

A series of list was a failed approach that was interesting and is worth mentioning. The idea was that each list function would take a list, and manipulate it to return a list. For example, let’s say the player gave this list of command

  1. ‘find all enemies in range’
  2. ‘find all enemies visible’
  3. ‘find the nearest enemy’

In the coroutine loop, they would be loaded using something in lines of: List[i](List[i-1]).

List one would call on an empty list (or the last list of the loop), returning a list with all the enemies in range.List two would call on the list two, returning a list with all the visible enemies.List three would call on the list two, returning a list with the nearest enemy as [0] of the list. And so on.

While I was largely satisfied with the result. There were still myriads of problems with this approach at this point.

  • It still wasn’t flexible enough. There was no way to implement things like ‘Wait/Hold’ WITHIN the functions themselves as they had to be done using a coroutine (or maybe they don’t have to be?) and the code got dirty pretty quickly and….
  • How do I translate a list of command from the player to the list of functions?

At this point, I was not even aware of delegates. One way to go would be to just use strings of list and if/switch statements, but this approach would definitely not be sustainable in the future. Not to mention inelegant. ugh.

what my code could have looked like :^)

Delegates are the bee’s knees

I googled around, and found the existence of Func, and Action (which are types of delegate). Learning about them made my code much more cleaner and efficient. I had fun rewriting other old codes using delegates. If you don’t know what they are and would like to find out more about them, I highly recommend watching this excellent video:

https://www.youtube.com/watch?v=G5R4C8BLEOc

Anyway, after numerous rewrites, I finally settled with what is pretty much a Finite State Machine, with a dictionary that has enums as keys and Ienumerators as values. The commands are given in lists of enum, and the corresponding Ienumerators are played within the main coroutine.

Since I am using Ienumerators, all commands are fully contained within themselves. Each state plays out their associated function once, then switch to the next state,and so on. Which means that implementing AI overrides like ‘Attack until the target dies’ is very easy. All I have to do was to make a function that made a coroutine loop within the coroutine loop until the condition is satisfied.

Object Pooling

While doing this, I’ve also implemented an object pooling system. Because manually rigging the object pool in the inspector sucks, I made a version that automatically makes an object pool for a prefab if there isn’t one, or find and use the existing pool. At this stage, I think readers (if any) would be already bored out of their minds. So I’ll just leave two excellent links that I combined to craft mine:

http://catlikecoding.com/unity/tutorials/object-pools/

https://unity3d.com/learn/tutorials/topics/scripting/object-pooling

What’s next?

Next week, I am thinking of drawing some concept art, and trying out some rough drafts of UI. I am also thinking of implementing singleton game managers which should be simple enough and a save system to go with it. If you do have any questions feel free to ask me at @LLHorizon on Twitter!

--

--

James Kim

Backend Engineer working at Xero. Also passionate about UX, writing and illustration.