Tuesday, February 13, 2018

Tower Defense Starter Kit v2.2 Dev Log #1: Weighted Wave Spawning System

The v2.0 update of Tower Defense Starter Kit introduced some major improvements to the wave spawning system. Prior to this update, the toolkit came equipped with a single Wave Spawn Controller class that handled three different types of spawning models. This design structure was replaced in favor of an inheritance based system with a parent class that handled the base logic, and two new child classes that individually specialized in user-defined (batched) and randomized (threat based) wave spawn patterns. The third model of wave spawning system, which allowed the user to control the spawn data of every individual unit in a wave, was removed since the batched spawning system could essentially achieve the same desired result while making it far easier to edit the wave data.

The reason behind introducing an inheritance based design was self-explanatory, but the true long-term goal behind the v2.0 update was to act as a pivot to alter the design direction of future updates when it comes to the addition of improved features to the wave spawning system. Getting to the point, the batched spawning model works quite well within it's intended design: the creation of user-defined wave patterns. The unit-based system as mentioned earlier did not serve any real purpose and hence did not warrant an upgrade. While it was easy to use when working with small waves (and the reason behind its inclusion in the first place), it got increasingly cumbersome once you start dealing with larger waves of AI bots. It essentially ended up being feature creep that bloated the toolkit and hence was removed.

As for the threat based model, the primary motivation behind its creation was to provide a more automated approach to wave generation. It did not depend on the user to explicitly define the exact nature of the AI units spawned during a wave. However, to be honest, it had very little intelligent design going for it, instead relying a bit too much on randomness. And this has been bugging me for quite some time. And so I got around to thinking if it was truly adding anything relevant to the toolkit's core feature set? Was it providing the customers with a tool that allowed them to replicate popular tower design tropes? While it did serve the purpose of being an alternative design choice to the batched spawning system, it offered too little in the way of providing the end users with any degree of control over the wave generation mechanic. Ultimately, what units got spawned boiled down to a random number with no set of rules beyond having an upper threshold for the threat rating associated with a wave. And this brings us to the core theme of the v2.2 update: the introduction of weighted spawn probabilities to the wave spawning system.

In an effort to improve the design of threat-based spawning system, I started thinking about ideas that could reduce the element of randomness associated with the model. I noticed that while the existing system allowed the designer to specify enemy AI classes that can be spawned in any particular wave, it did not provide any means to control the probability distribution among them. So I introduced a new weight parameter which can be defined for all types of AI that need to be spawned during a mission.

Now, this facilitated the creation of special conditions like setting an increased spawn chance for the weaker enemies while reducing that of the really powerful ones. However, this in itself won't outright prevent higher tier enemies from spawning during the first wave. So that led to the addition of a new conditional check to ensure that only enemies with threat rating lower than a certain specified percentage of the wave's threat rating get spawned. I plan to extend upon this further in future updates by having unlock levels for different classes of AI. I'm also looking into the possibility of trying out a dynamically changing weight system, that could potentially reduce the weighting of lower tier enemies over each passing wave while increasing that of the higher tier ones.

Another area that received an overhaul was the repeating wave cycle design. The batched wave spawning system retains the wave cycles, where it makes sense, but I wanted the new weighted system to have features focused more on generating waves in an automated fashion (without increasing randomness within individual waves) as opposed to having the user define the specifications of each and every aspect of the wave. 
Hence it was replaced in favor of a system which raised the threat rating of each wave through a user-defined growth function.

I've implemented a simple linear growth function as part of the new update, but it can easily be modified to have an exponential growth curve. Maybe even a curve that dips after a certain number of waves to allow for some quiet time before raising the threat levels higher than before. I would definitely like to try out these scenarios in the future, but that's not what this update is about. Right now, I hope to build a foundational framework upon which future updates can be built upon.