Saturday, March 10, 2018

Playing with Colors: Catalog I

A couple of weeks ago, I posted an article going into an in-depth account on the process of revamping the visual design of FPS Tower Defense Toolkit. As part of the said process, I experimented with various color schemes before finally settling on something that helped establish the theme of a virtual playground.

Perhaps due to this new experience, and partly as a result of a series of problems that pushed my life in various unexpected and adverse directions, I started looking at things from a whole array of new and exciting perspectives. And thus I stumbled upon the beautiful realm of color theory. So it was about a week ago, that I started toying with the idea of experimenting with different color schemes on a daily basis. Today marks the eighth day of this new experimental chapter, and I decided to archive my various forays into the unknown on a sort of weekly basis. I'm not exactly going with the idea of doing it on any specific day of the week, but rather having one catalog for every seven experiments. So today I present to you the first article of the new Playing with Colors series.

Colors: #ff0000 + #ffffff

Colors: #ff0000 + #000000

Colors: #ffff00 + #000000

Colors: #00ff00 + #0da6ff

Colors: #00ffff + #ff2c2c

Colors: #ffff00 + #00ffff

Colors: #6ead3a + #efedef + #254558

That's all there is for this week. As mentioned above, a new catalog will be published after the next seven experiments. Meanwhile, you can follow me on Twitter for a daily dose of color combination shots.

Saturday, March 3, 2018

FPS Tower Defense Toolkit Tutorial: How to create a new level

1. First, ensure that the default Game Mode & Game Instance class parameters in the Project Settings are set to BP_GameMode & BP_GameInstance classes respectively.

2. Now create a new map, open it, & lay down the floor meshes. Add a Nav Mesh Bounds Volume & extend it to encapsulate all the floor meshes. This will enable AI bots to traverse across the level.

3. Add a Lightmass Importance Volume around the core game space.

4. The next step is to add instances of BP_EnemySpawnPoint to act as spawning volumes for the enemy waves. As can be seen in the next screenshot, I've added a couple of spawn points in my level:

5. Now add a BP_PowerCore actor to the level in order to provide the primary target for the enemy AI bots.

6. The toolkit uses modular grid generators to act as platforms for tower placement. But before adding them to the scene, first, add a BP_GridManager actor. The Grid Manager determines the size of individual grid cells across all grid generators in the level through it's publicly exposed variable 'GridCellSize'.

7. With the grid cell size specified, it's now time to add the grid generators. Drag & drop instances of BP_PlanarGridGenerator into the level. The overall size of the generator in the X & Y (local space) directions can be specified through the 'GridCountX' & 'GridCountY' variables as shown below:

8. Now add an instance each of BP_ProjectileManager & BP_ObjectPoolManager into the level. If you plan to use the pooling system, just set 'PoolPlasmaProjectiles?' to true through the details section of the actor. Since this system uses a fixed size pooling system, also make sure to specify the pool size through the 'PoolSizePlasmaProjectile' variable.

9. The next step is to add an instance of BP_EnemyAIManager. It will tackle the responsibility of keeping track of potential targets for the enemy AI bots. While the target acquisition and response logic are handled directly by the bots themselves, the Enemy AI Manager aims to provide them with all the necessary information in that regard.

10. Now comes two of the most important classes required for the functioning of the toolkit: the Tower Manager and Wave Spawn Controller. Add the BP_TowerManager actor first. There's no need to make any changes to its default parameters, but if you're interested in knowing more about the class, check out the concept overview post for the same at:

Next, add an instance of either BP_BatchedWaveSpawnController or BP_WeightedWaveSpawnController to the level. While most of the default parameters will work right out of the box without any need for customizations, you will have to add references to the enemy spawn points within the publicly exposed array 'BatchedWaveSpawnDataArray', if you're going for the former model. Just make sure to specify the 'SpawnPoint' parameter for each wave by linking it to one of the spawn points added to the level in Step 4.

For further reading about the wave spawning systems, see:

11. Now onwards to the final step. All that's left to do is to add level bounds so that actors like projectiles that can move across the level gets destroyed once they cross a certain threshold. Add six BP_LevelBounds actors along the outer periphery of the level, making sure that they form a cuboid shape to encapsulate the entire level.

With that, you should have a fully functional level at your disposal. If you have any queries regarding the workflow, feel free to let me know in the comments section.

If you're interested in the toolkit, you can purchase it through the Unreal Engine Marketplace:

Friday, March 2, 2018

FPS Tower Defense Toolkit Basics: Weighted Wave Spawn Controller

The FPS Tower Defense Toolkit comes equipped with two different types of wave spawning models: one centered around user-defined wave patterns, and another geared towards generating waves based on weighted probability distributions. I covered the former of the two in an earlier article. You can read more about it here: FPS Tower Defense Toolkit Basics: Batched Wave Spawn Controller. Today I'm going over the design of the second model: the Weighted Wave Spawning System.

The WeightedWaveSpawnController is intended to provide the designers with a tool capable of generating waves of AI bots in an automated manner. Unlike its contemporary, which requires the designer to explicitly specify each and every aspect of the wave, we have a system here that spawns units based on a weighted probability distribution. This approach essentially allows us to control the spawn probabilities of different AI classes based on the weights associated with them.

Another factor that helps with the automation process is the threat rating attribute, which keeps increasing with each subsequent wave. As the threat rating goes up, it opens the door for spawning high tier enemies. Meanwhile, the number of low tier enemies may go up as well. Both of these factors together increase the overall difficulty of the game over time.

To aid in the functioning of these systems are a host of variables that can be customized directly from the editor. I will go through each of those attributes one by one and briefly explain their individual functionalities:

1. WeightedWaveSpawnData: Controls the shifting dynamics of waves through the following parameters:
  • NumberOfWaves: Determines the total number of waves.
  • TowerBaseResourceAllocation_BaseValue: The number of towers bases to be distributed to the player per wave.
  • TowerBaseResourceAllocation_StartingBonus: Bonus tower bases to be provided to the player at the start of a level.
  • TowerPointResourceAllocation_BaseValue: Tower points to be distributed to the player prior to the first wave.
  • TowerPointAllocation_LinearGrowthMultiplier: The number of tower points to be distributed to the player keeps changing based on a linear function. This parameter controls the growth rate of tower point allocation with each new wave.
  • WaveThreatRating_BaseValue: Threat Rating of the first wave. Determines the starting difficulty of the level.
  • WaveThreatRating_LinearGrowthMultiplier: The wave threat rating increases with each new wave based on a linear function. This parameter controls its growth rate and thus provides an estimate of how fast the difficulty rises up as the player progresses through the level.
  • SpawnInterval_MinValue: Minimum duration between spawning of individual bots.
  • SpawnInterval_MaxValue: Maximum duration between spawning of individual bots.
  • MaxUnitToWaveThreatRatio: Restricts the types of units that can be spawned in a wave based on the ratio of their threat rating to the wave threat rating. Only AI classes with these ratios less than or equal to this parameter will be spawned. As a result, this feature can be used to prevent high tier units from being spawned during the initial waves.
2. AISpawnWeightingDataArray: Enables setting of the spawn weights, with each element of the array used to represent the spawn probability data about an individual AI class. Each element of the array contains the following attributes:
  • AIType: An enum that defines the AI model.
  • BaseWeighting: Controls the spawn weight of this AI class. Higher values relative to other classes increase the spawn chances, while lower values reduce it.
  • CanBeSpawned?: Determines if this AI type can be spawned. Can be used to control/restrict the types of enemies present in different levels.
  • DataTableRowName: Connects the AI class with the associated row in the DT_EnemyAIStats data table. [No need to explicitly specify this as it will be set automatically by the wave spawn controller]
3. NumberOfWaveCycles: Not applicable to this model. Used by Batched Wave Spawn Controllers to repeat wave patterns.

4. TimedWaveStarts?: Determines if new waves will start automatically after a designated amount of time. If turned off, the player will have to manually trigger new waves.

5. WaveTimerInterval: If TimedWaveStarts? is set to true, then this parameter controls the time interval between waves.

Thursday, March 1, 2018

FPS Tower Defense Toolkit Basics: Batched Wave Spawn Controller

The FPS Tower Defense Toolkit comes equipped with two different types of wave spawning models: one centered around user-defined wave patterns, and another geared towards generating waves based on weighted probability distributions [Read more about it here: FPS Tower Defense Toolkit Basics: Weighted Wave Spawn Controller]. Today we're going to cover the first model: the Batched Wave Spawning System.

The BatchedWaveSpawnController is intended to provide the designers with absolute control over the wave design and thus works best when going for handcrafted wave patterns. To help in this regard are a host of variables that allow customization of waves directly from the editor. I will go through each of those attributes one by one, and briefly explain their individual functionalities:

1. BatchedWaveSpawnDataArray: This array is responsible for storing all parameters that control the flow of waves, with each element representing information about a single wave. Information about an individual wave is divided primarily into two categories: the spawn control data for various AI classes, and the amount of resources to be distributed to the player.

The first of these data sets is contained within the BatchedAISpawnDataArray. This array is basically a list of spawn control information about the different AI classes to be spawned during the wave. Similar to the pattern employed by the parent array, each element in this array represents information about an individual AI class, thus splitting the wave into different automated batches, and hence the name. Here is a brief overview about the different parameters that define a batch:

  • AIType: An enum that defines the AI model.
  • SpawnPoint: Determines the spawn point actor for this group. These actors handle the actual spawning logic using the information passed on to them by the wave spawn controller.
  • SpawnStartingTime: Determines the time (relative to the starting time of the wave) at which this batch of AI bots start rolling out.
  • NumberOfUnits: Defines the number of individual units in the group.
  • SpawnInterval: Controls the duration between spawning of individual bots.
  • DataTableRowName: Connects this AI class with the associated row in the DT_EnemyAIStats data table. [No need to explicitly specify this as it will be set automatically by the wave spawn controller]
The second data set, dealing with resource allocation management is determined by the following variables: the PreWaveTowerBaseDistributionAmount and PreWaveTowerPointDistributionAmountwhich as the name suggests, control the number of Tower Bases & Tower Points to distributed to the player during the tower construction phase.

2. NumberOfWaveCycles: This parameter enables the aforementioned wave patterns to repeated any number of times. With each subsequent cycle, the enemy AI units gain more HP and thus become more resilient.

It can also be set to zero in order to activate the Endless wave system.

3. TimedWaveStarts?: Determines if new waves will start automatically after a designated amount of time. If turned off, the player will have to manually trigger new waves.

4. WaveTimerInterval: If Timed Wave Starts? is set to true, then this parameter controls the time interval between waves.

Saturday, February 24, 2018

FPS Tower Defense Toolkit v3.0 Dev Log #1: Visual Design Revamp

The FPS Tower Defense Toolkit was published on the Unreal Engine Marketplace more than two years ago, and throughout most of its life cycle, I had concentrated most of my efforts on the addition of new gameplay systems and refinement of existing ones. Very few updates were targeted specifically at improving the visual design, with almost all of them focused on creating a clean and minimalist UI design.

Towards the end of last year, I rolled out a series of mini updates focused on the introduction of new weapons to the player's arsenal. After spending most of the prior updates on refinements to existing systems, this was a huge breath of fresh air to me. First of all, it meant that I had to do research on a diverse set of weapon systems from a wide variety of games. I thoroughly enjoyed this process. There were so many cool weapons and I just wanted to figure out how they all worked. Then came the act of creating working replicas of a selected few of these weapons in Unreal Engine. And this process had a certain playful feel to it, unlike say, working on something that merely increased the overall efficiency without any visible feedback beyond a change in the number of frames per second. I even enjoyed the final testing process, which is usually kind of a mood buster for me. This experience kind of reminded me of what it felt like during the early days of the toolkit's production.

Maybe it was the tonal shift in the experience, or perhaps it was because I really cared enough about these systems to at least create some basic materials and particle systems (which I do not enjoy working on at all), that opened up my mind to the possibilities outside the narrow path that I was following over the past year of the project's life. I felt the need to add some touch of beauty to all parts of the toolkit, even though I had very little experience working on anything other than blueprint scripting. I did not know exactly how to go about doing that, but before I got around to that answer, life took a sudden turn.

Due to some harrowing personal issues, I had to return to my parent's place. Things quickly deteriorated further, and I realized that all my plans would have to wait as it became more and more clear that the likelihood of getting back to work before the end of the year was rather bleak. With access only to my phone, all I could pretty much do from a work standpoint was to provide customer support for the marketplace products. So I spent most of my time studying games and reading up on what was happening in the industry. Perhaps due to the result of being separated from work, and being exposed to a lot of interesting ideas, I started getting excited about all the things that I wanted to do after getting my life back together.

Fast forward a couple of months, and I was back at work. While going over what course of action to take, I decided to do something about the visual design of FPSTDT. I noticed that the sample map provided with the toolkit had a very dark grey color for all walls and floors which, to be honest, looked quite bland and unappealing. Also, there were no distinguishing features on the map, but I figured that I'll set the groundworks for the artistic design first before trying my hands at level design. To provide a frame of reference for the starting position, this is a screenshot from the vanilla map.

The first step was to come up with some basic vision of what I wanted the level to look like. One idea that had crossed my mind during the brief stint away from work was to emulate the visual design of Mirror's Edge and Super Hot. Basically, two contrasting colors used predominantly over the entire level layout. After trying out a few colors in the editor, I really took a liking to the white+red color combination. However, the whites were not looking as clean as they should and the reds turned out to be a bit too bright. So I tried editing the light source to see if its color was causing this tinted result. I also tried adjusting its brightness to get the desired result but to no avail.

After getting frustrated with my lack of experience working on this side of the engine, I tried using unlit emissive materials to see if they could produce what I was looking for. Not only did not help, but it also made it impossible to see the edges of meshes as shown below:

After not making any headway, I started out with a new map from a blank project. I added in a skylight and a sphere reflection capture and applied an alternating white/red color design to the building blocks. The materials were also given a slightly glossy look. Even though it was a simple barebones map made out of cuboid shapes, it finally started looking kind of beautiful, at least compared to the sample map from the toolkit. I guess anything would look beautiful compared to that, but to be honest, I really liked the way the white+red color combination complemented each other. It created a clear distinction between the floor, the tower bases and the towers.

However, there was one major problem with this design. When
 I tried to spawn towers, it was a bit too hard to clearly identify the visual silhouette of the holograms among the bright white floors.

So what started as an exciting prospect of trying to replicate the aesthetic design of Mirror's edge came to a halt. I did not have any other alternative design choices in my mind, and going back to the default style was not an option. So I went ahead and experimented with the entire spectrum of colors in order to identify other interesting color combinations. The floors definitely needed something on the darker side that contrasted well with the holograms. Even though black is the first color that pops up from that viewpoint, it actually looked ok. It did not look as clean as the alternating white plus red design, but it would have to do for now.

With the holographic display issue kind of sorted out, the next problem to tackle was the washed out in-game look. The skylight intensity was ramped up earlier to make all the surfaces look smooth and shiny. Bringing the value down made everything look very dull. I tried to work around this by adjusting the intensity of the directional light, but without making any progress towards the intended result. So I started going over the skysphere settings to see if it would make any difference and noticed that the sun height of the actor was set to -1. Basically, this causes it to display a night sky. Out of curiosity, I decided to check out if it had any impact on the actual lighting of the level by resetting the parameter back to 1. After doing so, I built the lighting again and tested out the level. With the already ramped up skylight intensity, it was like getting caught in Tien's solar flare scene from the intro of Dragonball Z.

Now I could finally bring down the intensity of the skylight down much further, reducing the washed out look further. Around this time I was also reminded of Racer X's car from Speed Racer, which had a striking combination of yellow and black.

So I threw in a few yellow blocks into the scene as well just to get an idea of how it fits into the scene. I could find no immediate use for it, but kept it around just in case some idea pops up in the future.

The level was then expanded outwards to match the scale of the original sample map as I wanted to get a good comparison. It definitely did look better than before, and unfortunately, I do not have any screenshots from this particular phase, but it somehow felt like there was a definite lack of visual cohesion. I hardly have any experience working on art/level design aspects of the engine, but the power core, with its holographic material, looked kind of out of place for some reason. It later occurred to me that there was no unifying theme holding everything together. Since I did not know where to find that, I decided to go back to the roots. I thought about why I started working on this toolkit and what it felt like back then.

During the early stages of the project, I had no intention of publishing it as a toolkit on the Unreal Engine Marketplace. I was very much into Sanctum 2 back then and just wanted to try building the underlying gameplay systems on my own. So it was more of a fun little experiment than anything else at that point. It was, in essence, kind of like playing with a lego set. You may start with trying to create what was shown in the pictures that come with the box, but then the experience transforms into one where you go around exploring your own ideas. Kind of similar to how you start trying to understand and recreate a game but then end up throwing in your own ideas to see what happens. At that point, it kind of feels like a playground, with you actually designing the systems that form this space more than the act of playing with these creations. So I decided to run with this theme of a virtual playground.

With a basic overarching theme set in place, I went around using basic colors to categorize the different building blocks of the level. For example, yellow floor surfaces to signify enemy spawning areas, green for the power core, etc. That went on for a while, experimenting with minor tweaks to the material and lighting setups, and finally, the new visual design for the toolkit was complete.

There's most certainly a lot more room for improvements. The level design, for one, could really help with an upgrade. But this was a good start. And I will continue pursuing this course of action over the upcoming updates.

Sunday, February 18, 2018

Top Down Stealth Toolkit FAQ #2

Q: I want to change the size of the vision arcs. Where can I find the variables that control it? Is there a way to do it from the editor window?

A: You can customize the radius & angle of vision arcs for all types of AI through their perception components. The toolkit uses a custom AI Perception system (BPC_AIPerception) that enables the AI bots to perceive different types of stimuli. It basically allows for four different types of perception (for further details, check out Top Down Stealth Toolkit Basics: AI Perception), out of which the Visual Perception system is responsible for hosting the parameters that determine how far & wide a bot can see. And these include the 'VisionRange' & 'HalfVisionAngle', which among other things, also control the size of the Vision Arcs.

Ideally, these variables could be made public (instance editable) and thus enable customization directly through the editor. However, due to an engine bug ( that automatically resets public struct values stored in components, I had to revert it back to being editable only from the parent blueprint to which the component is attached. So this means that the aforementioned attributes will require editing through the details panel of perception components in AI blueprints (as shown in the screenshot below). Doing so will instantly apply the changes to all actors of that particular AI class.

I understand that this is a bit tedious compared to directly editing these attributes from the editor details panel, but Epic has marked the bug as fixed for the v4.19 release. So if the fix does make it into the final release, it should then be possible to set the variable to public and directly test out changes through the editor itself.

Wednesday, February 14, 2018

Tower Defense Starter Kit v2.2 Dev Log #2: Data Driven AI Design

In the previous dev log for the v2.2 update of Tower Defense Starter Kit, I talked about the new improvements to the wave spawning system, & in particular, the introduction of weighted spawn probabilities for different AI classes. If you're interested in knowing more about the same, you can get an in-depth read at Tower Defense Starter Kit Dev Log #1: Weighted Wave Spawning System. Getting back to the topic at hand, it was while working on the idea of weighted probability distributions that I decided to try out a data-driven approach to spawning AI bots. The tower spawning system had received a similar upgrade during the early stages of the toolkit and ever since then, I've occasionally had this thought cross my mind.

The introduction of a data-driven design ended up greatly streamlining the process of adding new features related to towers, and across a wide variety of scenarios. Most notable among these was that further changes to HUD systems required a far less hands-on approach as most of the associated UI elements were already being displayed dynamically based on the underlying data. And this drastically reduced the time required to release subsequent updates. However, all these advantages did not exactly warrant doing the same for the AI systems, as unlike towers, there were very few processes that were interlinked with them. Plus most of the updates were focused on other aspects of the toolkit. But that is about to change.

The primary focus of the next few updates is to improve the AI & Wave design elements of the toolkit. As mentioned in the previous dev log, I'd like to first create a foundational framework which facilitates the introduction of further customizations with ease. So as implemented in the case of tower spawning systems, I decided to make a small step towards taking a data-driven approach to AI design. No changes have been made to the core AI logic at this point. Instead, the basic attributes common to all AI classes, (like HP, Attack Damage, Vision Range, etc) have been migrated over to a new data table as shown below:

Over the course of new few updates, I would like to transfer more of the AI control parameters into the data table. For example, the Healer class AI has additional parameters that determine how often & by how much it can heal allied bots in the vicinity. A similar case can be said of the Tower Disabler bot as well, which can temporarily disable all nearby towers at periodic intervals. As of now, the variables that control these specialized functions still reside within their respective classes. In the future, I would like to have these unique parameters set through the data table as well. This could potentially allow us to have all data pertaining to the AI systems at a centralized & easily editable location, & also dynamically add special abilities like healing, based on the associated information.

Anyways I don't want to rush down that path without going over all the potential alternatives. So I'm taking it one step at a time right now. The v2.2 update will introduce the data-driven approach at a basic and limited level, with the wave spawning systems already synchronized with this design philosophy. I hope to develop it into a full-fledged system soon enough.