This is part 4 of a series of posts of making an idle game. See Part 1, Part 2 and Part 3 here.
This being an idle game, there has to be some form of offline progress so you don’t have to leave your computer or phone on all the time just to progress.
It simply works by tracking how much time has elapsed since your last time of play. There are a few preventions I’ve made to prevent time travellers (people who change their system clock to gain huge rewards). This basically makes it harder for people to cheat and a little more tedious. I didn’t want to put in too much effort in cheat prevention since if people want to cheat, they will find a way anyway. At the same time, I think it is not good if a game is too easily exploited. Thus, I did not want to make it too easy to cheat in the game so I made a few extra checks in calculating the offline progress.
If the game detects that you have “time travelled”, it gives you a very visible warning. If you however, continue to time travel, and the game detects repeated time travelling attempts, your offline progress will be nerfed.
Character / NPC dialogue
Almost all of my games have some kind of dialogue system. Like the achievement system, it’s one of those “standard” kind of things that I end up re-using for every one of my games. This game is no different.
The person talking appears on the left, which can even be your characters and heroes. The NPC will play the idle animation usually. The dialogue in this game is the most complex I have ever made.
I probably should have written a dialogue manager to organize the dialogues. How dialogue starts is I type something like:
Which brings me to:
Unlike my tower defense, each dialogue message requires its own ID. My tower defense used a different design where you could put multiple messages under a single dialogue ID which makes it a bit neater, but it cripples some of the customization I can do by separating messages into different IDs.
High resolution graphics
When I first started working on this game, I had issues understand what resolution to make my game at, but now I try to understand how graphics scale on different resolutions and devices and how the different camera settings affect the way graphics are drawn on the screen.
Early versions of my game had a “blurring issue” on high resolution phones, like my Samsung Note Edge which has a resolution of 2560 x 1600 pixels.
It was because my graphics were not designed for such high resolution devices, a pretty amateur mistake I had made when I was doing the graphics. In Flash, you only need to support the resolution you are publishing the game at. But for publishing a game to mobile, you have to cater for the HUGE variety of phone resolutions.
800 x 480, 1000 x 800, 1024 x 768, 1600 x 1000, 2560 x 1600 and so much more!
At this point I had realized that I had not set up my game properly to support these resolutions, but I worked around it and made a script called ResolutionSetter.
This basically sets the resolution of your device to my target resolution. It’s the neatest and quickest fix I could find for my game at this point. So if your phone is 2500 x 1200, and my game is 1000 x 600, it sets your screen resolution to 1250 x 600, which allows my graphics to be displayed on your screen at a 1:1 ratio while still retaining aspect ratio. This causes no blurring in most cases.
Just for fun, I experimented with making my game run at four different resolutions on my Samsung Note. I made a 1/4 Res and Half Res version for fun. It was hilarious seeing the results and playing my game at ultra low resolution on my super high resolution phone.
Here’s how it looks:
It’s a very useful script I think I may bring over to future games. It basically does what Unity’s SetResolutiondoes, but I modified it to not screw up my game’s aspect ratio, which somewhat combines the best of both worlds.
The advantage of this approach is that my graphics will never get scaled up even on high resolution devices which can cause interpolation and blurring. I retain high control over how my graphics appear on different devices. I can set it to render at high res on high res devices and set it to normal res on phones with resolutions lower than 1048 pixels for example.
It’s not the best approach to use, but it is the most suitable one for this project at this point in time.
A possible downside is if you want to design your game specifically for high resolution devices and want them to appear super sharp on those devices, your graphics will not be as sharp if you don’t build your game on a high resolution or export your graphics to cater for that resolution. But this is something I don’t foresee doing as my game is not built for high resolutions now. I’m using “1000 x 625” as my target resolution. If I were to support high resolution graphics next time, I would modify the script to a higher target resolution like “2000 x 1200” instead of “1000 x 600” and the script will aim for that.
At the top of the screen is a row of buffs. Rolling over them shows its description, effect and level of the buff. Each character has its own buff tray.
But how are the buffs applied?
Some things like critical rate can be stacked additively or multiplicatively. I usually put the word ‘boost’ in stuff that stack additively and ‘mult’ in those that stack multiplicatively.
This is executed from a script called the HeroScript which is attached to each hero. When you add or remove a buff, the bonuses from buffs are reset and you add any stats gained from any buffs existing on the character.
The Hero Script
The hero script stores every variable you need to know about the hero. From how much base damage, total damage, multiplicative damage he has, to how much health he regenerates when he attacks an enemy, to how much mana he gains each second, his defense, crit rates, his health multipliers, how much defense he gets from buffs and etc. EVERYTHING YOU NEED TO KNOW IS HERE.
But with so many variables it gets very confusing as to how they are calculated. If the calculations are done in the wrong or unintended order, it can lead to serious issues. But here’s a flow chart I drew that hopefully simplifies the process.
When the hero is created, he first initializes his base stats and gets data from what class he is (is he a warrior or a mage?). If he’s a warrior he may have higher base health and increment per level.
Then, apply any passive skill bonuses he has. A warrior typically has some passive skill that increases HP.
Then apply any class bonus boosts if he is a higher tier warrior (Knight / Paladin).
Then apply the boosts from the main equipment upgrades which takes into account his equipment level.
Then apply any existing solo or party buff effects.
Then apply any global multipliers from the shop/achievement/ascension upgrades.
Now what happens when you buy something, earn an achievement that provides a passive bonus, or you buff or get buffed or if one of your buffs expires?
Recalculating the hero’s stats in every frame is expensive so if any of those things happens, recalculatePowers is called, which in turn recalculates the hero’s stats and gets the new multipliers from the various aspects of the game (Guardian, Shop, Achievement, etc).
Once everything is applied, the hero’s stats are updated with new values and then a call is made to the statsPanel and the upgradesPanel to update the UI to show his new stats. If the player is hovering over a popup over any of the buttons or skills, that popup must also be updated.
I was testing out my game on weaker low-end devices and the game actually crashed. Yes, it was that horrible. I had to make several changes to the way the game loads its content.
How unity loads the assets is that my game takes place in a “Scene”. This scene is called the Game Scene and it contains everything – all the enemies, their sprites, character graphics, backgrounds must all be loaded before the Game Scene can run.
The phone was crashing on the loading screen. So I ran the profiler to see if it can tell me what went wrong.
I saw that a lot of CPU resources were spent on Texture.AwakeFromLoad. It was likely because the game was loading all 150 enemy sprites when you start the game.
I kind of expected this, which was why I wanted to learn Asset Bundles. I had looked into it before. Instead of loading everything when the game starts, you should ideally only load WHAT IS NEEDED. This depends on your game though. But since my levels are separated into 10 main areas, I should only load the area the player is currently at.
Instead, I was loading all 10 areas at once, which causes huge overhead. Unfortunately, I was unable to figure out how to use asset bundles so I used an alternate approach.
I removed all references to the sprites. So basically the enemy is empty at the start. It stores no graphic and is literally just an empty shell of nothing. As the player enters an area, I load a prefab containing references to all the enemy sprites of that area. The enemy now has access to about 10 sprites, but not all the 150 sprites like previously.
So if I enter the desert, I load all the desert enemies. If I enter a swamp, I only load swamp enemies. I can also choose to unload the previous area’s enemies to reduce memory consumption (It seems that anything that is referenced or loaded in the scene, whether visible or not takes up memory, but I’m not sure and I need to run some tests).
This way, I only load what I need. The downside is that there is a noticeable pause on slower devices when advancing to a new area because the game has to load the new area’s enemies.
Previously before this change, the game has to load ten 1024×1024 px backgrounds ALL AT ONCE. However, now it only needs to load the background for your current area.
If you have played other games like Tap Tap Infinity and Tap Titans, you will notice the pause between areas as well. However Tap Titans was very clever. They hid the pause behind a fade to white screen transition. And the loading is executed while the screen is white. While loading, an animation showing the title of the next area moves into the screen, keeping you occupied while the loading is occurring. Most of the time, you don’t notice it because the loading is hidden behind the white screen and the title text animation.
Optimizing enemy loading further
Enemies are the biggest problem during loading times.
I decided to at this point reduce the resolution of my enemies. They are at 2x resolution to support high resolution devices. However, the enemies are currently taking up too much space on phones that do not have that kind of resolutions.
I mentioned atlases previously. An atlas basically combines individual enemy graphics into a combined image to be more efficient. If you’ve made or seen flash games, or any games, character animations are often put into spritesheets containing the different frames.
So if you have 10 separate images, you put them in a spritesheet and you have just one image containing the 10 frames. The game only needs to load that one image and not have to force the engine to keep swapping out image for your one character. This leads to better performance for your game.
Similarly in the diagram below, if you have all those 10 enemies on screen at once, you only need to make 1 draw call as compared to 10 draw calls since you only have one huge texture comprising of everything you need.
But one should not blindly just put monsters into an atlas. If wrongly used, using atlases can turn out to have a negative effect.
In my previous atlas, enemies of different areas are being packed together! This is a BAD thing to do. What this means is that when it is trying to load a particular enemy, say the grassland enemy, it ends up loading the entire atlas, filled with other enemies from other areas that you never need. This takes up additional resources when it is unnecessary! I realized what a big mistake I had made.
Instead of packing all my enemies into an atlas, I now split my enemies into different atlases by the area so the game does not load enemies that will NEVER be drawn on the screen. For example, if I am in the grassland, I should only need to load the grassland atlas and not have to make any requests to load textures from the candyland atlas.
This way, I have a maximum of one enemy atlas loaded in the game when I am in an area. Combined with the lowering of enemy resolutions, I could fit an entire area worth of enemies in a single atlas, which is really awesome!
The game loads in 4-5 seconds even on a very low-end device! It loads in 1-2 seconds on high-end devices.
Combining SpritePacker and Resources.Load
One small technical challenge I faced is that you cannot load sprite atlases in runtime. This is because the game cannot tell when you need the atlas. (Either you load them all at the start or you don’t load them at all.) To use a sprite atlas, you have to know exactly where you need it and when you need it. But I cannot predict when the player will reach the next zone.
This means that you lose out a lot in performance if you want to load individual sprites in the middle of the game (eg when the game has already finished loading the scene).
But you can be a bit creative with how to go about this issue. Actually it’s quite straightforward and takes advantage of how the game allows you to create objects in runtime.
Those damage texts that float up when you damage the enemy, those bullets that are shot from your player are all created in runtime (after loading is finished). So what I did was I created an object that held all the references to the sprites I need. This way, I’m not loading the sprites individually. I’m loading their references to the actual sprites. And those sprites can be sprite packed, which combines the best of both worlds.
When I want to load the sprites, I load the object, which stores the references to the sprites and assign the sprites to my enemy object.
Another scenario where the Atlas is bad was when I packed all my backgrounds in a super huge atlas, which required the game to load the super huge atlas, just to retrieve one background.
At any one point time in the game, only one background is drawn on the screen. In this case, the game is only using up less than 10% of the whole atlas, but is loading the entire atlas into memory. It’s a very inefficient use of atlases, which was why I split them up. Notice the white spaces below and above each background. The white spaces are added to ensure the image retains POT (Power of Two) dimensions.
An image with dimensions like 512 x 512 or 1024 x 1024 will allow it to be compressed more efficiently via a better compression format, resulting in smaller file sizes and less memory usage.
It was also good to move the backgrounds out of the atlas because the huge atlas was 4096 x 4096 pixels, and old devices have a maximum texture size limit of 2048 x 2048px. Anything higher and the device will be unable to display it. I’ve also changed my compression settings for backgrounds from [Compressed] to [Crunched].
This is a new compression setting that only exists for WebGL and is really good. It literally crunches your textures, making them smaller. You can even set the level of ‘crunching’. Changing this for all my enemies resulted in my game dropping from 28MB to 24MB. It’s not a lot since the game already a super small size already and it’s amazing how well this game compressed from the initial 40MB. With the backgrounds, I believe it will drop even further. I set the quality to 50% because at 0%, though it is sharp, the colour quality is lost.
Notice the sand giant’s mouth in the image above. While the rest of the monster remains consistent, the colour of the mouth is greyscaled at 0% crunched quality.
At 50%, my textures retain sufficient visual quality and look good while keeping the file size small at the same time. This part of game development leans more toward trial and error sometimes.
For WebGL, one of the outputs is a .data file (which is roughly the size of my game and contains all the assets of the game). This data file will sit in your browser and require a constant heap of memory. If my game is 30MB, it means your browser needs to constantly give me at least 30MB for my game to run, which is why it is essential to keep this file size small!
The editor log is not an accurate representation of final sizes, but it does give insight into what is taking up space. Below is the log from my build a few months ago. I managed to get the complete (uncompressed) size of the game down to 129MB from the 340MB it was in the past through using better compression formats and sprite atlas-ing.
I also converted my backgrounds from JPEG to PNG. There was absolutely no advantage to use JPEGs and JPG’s lossy format was only going to contribute to lower quality graphics when they are compressed into the final game.
Shop & Secret Shop
Not much to talk about. It’s just stuff you can buy. They affect global multipliers like Shop.goldMult, which is taken into account every time you gain gold.
Because the game lasts a long duration, it is unreasonable to expect players to remember the storyline and I found this a request in many other games. People may want to re-read the storyline so I added a journal panel.
This summarizes what has happened and during the early game when there is little dialogue, it can be something for the player to read and explore about the game. It’s actually the journal which sparked off my interest in adding a story to the game.
Game Balancing & Math
When trying to balance my classes, I had to have a few sheets to calculate how much damage (DPS) each character was dealing. Because their skills have different starting levels and growth, it was important to make sure that they had similar cost ratios. For example, if the warrior gains +10% damage every 1000 EXP, and the mage gains +10% damage every 800 EXP, this eventually accumulates to a big difference and late game, players will just only upgrade the mage.
The balancing in the game isn’t perfect because there are a lot of variables which affect how each character scales. This is further made worse by status effects you can inflict on the monster, like poison, or weaken.
Or buffs that temporarily aid a particular character for a short span of time.
I am pretty sure it’s not difficult for people to find an exploit, but I want to try as much as I can to prevent imbalances in the game.
One thing I learned in my company and working in teams is proper version control. I had been using Dropbox but it is unable to revert the entire project back to an earlier date – it only reverts individual files which makes reverting to an old version a tedious process. Even when working alone, I often found myself wanting to revert to a previous version of my game for various reasons. The most common reason would be that I did something that broke the game but there are other reasons like:
Going back to a previous version to compare the FPS
Looking at exactly what has changed from the previous build, and what code has changed
Looking for old code which I deleted but need to use again, which reduces the need to comment unused code which may clutter my scripts
Since the time I’ve learnt to use SourceTree for my project, I’ve already used it to pinpoint some errors in my game which would have otherwise taken some time to find out. I was really impressed. I’ve not used it to revert to an older build and it’s really, really rare that I need to look at it to see what has changed (it has helped me solve 3 problems in the past 2 weeks), but when I do need to refer to it, it often tells me what went wrong.
SourceTree was probably meant for teams to manage the game that is being worked on by multiple people, but it works really great for individual use as well. Also, a screenshot containing my first commit, which was at 3.43am on 16 May:
That’s all for this post. The game is still in its polishing stages. Despite no more content being added to the game, the final run is the most tedious part. It took some time to go around testing and fixing bugs or fixing the minor issues and cleaning up the game.
I suppose when this is done, it actually will be the closest game I have to be properly released to the public.
I’ll write about the main menu design and write a bit about sounds in the next post.
It has been awhile since I last posted something, but I’ve not been out of touch with game development. In fact, I’m doing something related to it every day.
So what have I been doing?
I’ve been working with a team of game developers at a company that develops educational games.
I’ve been very busy and truth be told I could barely get the energy to continue working on my personal projects and games. I was really depressed. This internship is pretty fun but it can be very tiring and I have very little free time compared to before which ultimately eats into my sleep and my health takes a hit. Juggling work and my personal projects is tough (and hey, I need time to relax sometimes too you know). It took me several weeks to adjust to this lifestyle, but I believe I am now back on track!
Earlier this month, I was deciding whether to create a new game, and what game to create at that. With Web Player shutting down and WebGLfar from being a stable platform to build games on, I realized that now is the perfect time to make a mobile game. Flash and web games are growing less popular by the day, but I decided to do one final push to put a game on the web. I was thinking really hard what I should do.
I looked up my old project, Idle Heroes, and finally decided that I should wrap it up and finish the game.
It was a game I started making when I was still in the army, back in 2015. I worked on it for two months before my army ended and I stopped.
This was my first Unity project, and though I had used Unity while I was studying in school, I barely did any programming then and barely touched the game engine itself. I took on the role of an artist in my final year school project and the programmer was the one who did everything in Unity.
So yea, it was only on April 2015 did I officially start to learn Unity and started this project, Idle Heroes.
It’s funny looking back at work you did one year ago because you’re going all “I wrote that code? That’s so inefficient!” Yes, I was spending a lot of time cleaning up my code and optimizing it for mobile devices.
‘Idle Heroes’ is no longer the game’s name, but it is still the project name and I will refer to it as such for consistency purposes. (I will show the new game name and main menu in a future post.)
What is Idle Heroes?
If you do not want to read Part 1 and Part 2 of the makings of this game, don’t worry as I will just explain it below.
Here is a video (gif) taken during the first week of development (therefore, no animations yet). It demonstrates the game’s core gameplay effectively.
Idle Heroes is an idle incremental game where you hire heroes and upgrade them in order to slay increasingly tough enemies. As you progress to higher zones, you meet new enemies and fight bosses. The gold you gain can be spent to upgrade your character or in the shop to further boost your gold or experience gain amongst other buffs. Each character is a unique class with a set of unique skills which can be upgraded as you gain experience.
As you slay bosses,you also gain gems. Gems are used in very powerful upgrades in the Secret Shop. If you beat the final boss, you can ascend and you will restart the game, but gain a huge boost in power as well as gain access to Guardians, mysterious powerful beings who grant you special powers to help you run through the game quicker and more efficiently.
There are 3 + 1 characters in the game and you unlock them with time. Each character has three tiers.
You can advance into a higher class if you are powerful enough. For example, the warrior advances from a warrior into a paladin, which enhances his tanking abilities.
If you don’t understand, it’s okay because here is some information about the characters.
The warrior is able to attack enemies up close.
Characteristics: High health and defense, his skills boost party members’ defense and when he advances to a higher class, he gains ‘orbs’ when attacking enemies which can be used to increase his defense even further.
The priest casts spells and magic and shoots magic bolts at monsters.
Characteristics: High mana but low health and defense. He heals party members and casts various buffs to boost allies’ offense and defense prowess. He is more of a support class at first but he can advance into Wizard later on which boosts his offensive abilities. (BTW, the animation above is sped up. He doesn’t attack that fast in the game.)
The thief throws shurikens at the enemy from a distance. When he advances into a Ninja, he can inflict poison, which gradually drains the health of monsters.
Characteristics: Average health and mana, has high attack speeds and good against bosses. He has evasion to prevent getting hit by an enemy’s ranged attack and has a chance to steal additional money from monsters. His buff increases the critical rate and damage of all party members.
Last but not least, the Warlock. He is an unfinished character. He is a very powerful end-game character and cannot be hired with gold. He also has an interesting storyline, being once a human until a mysterious curse turned him into an evil Warlock. Hint: You have to fight him in an epic boss fight.
Characteristics: High health, mana and damage but low attack speed. He can cast various auras on his party members. The stat boost depends on what aura he is casting.
I initially intended to have only the first 3 classes in the game, but after making a Warlock boss, I felt that it would be cool that once you defeat him, you get to learn about his backstory and eventually get to hire him as one of your party members. It made the game and story a lot more interesting. A player who played my game was excited to hear that he could actually choose to save the Warlock (in a story dialogue) and in doing so will be able to hire the Warlock.
I think this character is very interesting and based on more player feedback I might eventually add him in the game. For now, his skills and stat balancing is incomplete and I decided to take him out of the game for now.
This game is pretty simple and each character only has 3 states:
While I had initially used Unity’s default Animator class, I realized that it fell short of what I wanted to achieve with my characters.
Because my characters could advance and they would switch sprites, the Animator class required me to use 3 different idle animations, 3 different death animations and 3 different attack animations. It is a limitation of the Animator. I didn’t want to just copy paste the animations because they are all just the same action, just repeated with different sprites. So I made my own animator class and called it SpriteManager.
Here, I can define which sprite the character should use.
It’s actually pretty nostalgic because it’s how I used to animate in Flash. Aside from animations, I also had to consider how the different class tiers would look.
When designing the thief, I asked two friends to rate the colour schemes. I wanted them to rate and arrange them on two criteria:
How powerful the character looked
How nice the character looked
I asked them to rate each character from 1 to 5 on each of those factors (you can see I marked the ratings separately in RED and BLUE in the image above)
The purpose was that I wanted “strong” colours for the higher tiered thief, and “weaker” colours for the lower tiered thief. I’m just going by feeling and observations when I say this but I felt that desaturated colours make the character look weaker and saturated colours closer to the reddish tone look more powerful.
The game has different ‘settings’ and ‘themes’. You start off in the grassland and eventually progress through higher level areas like the Forest and the Swamp. Each area spawns different enemies.
You can see here that I did not do anything different from other games. Like in most Idle incremental games, the scenery changes every 10 levels.Most games have areas like Desert, Antartica, Forest, City, and other really normal typical designs.
I have to admit, I wasn’t too creative with the area design for the first few areas, but I decided to do something different for the last few areas. I scrapped out some of the normal areas and made areas like ‘Outer Space’ and ‘Candyland’.
Those areas obviously don’t make much sense even in the game world (how is the mage breathing in space without any helmet?), but my friend who playtested my game said his favourite was Candyland because it was something special and unique and the monsters were special too.
I think I put a lot of love into the monster and area design for Candyland.
I even made the area boss a giant cupcake! I must have been high when creating these graphics because just for this area, I made a secret boss which is a chocolate yeti. I hope players find him!
The idea of chocolate yeti came when I drew an ice yeti and accidentally hit the colour invert button. This caused my yeti to change into a brown tone. It was amusing to me so I saved it as an image and named him ‘Enemy100’ which was an arbitrary name. It was later turned into an official enemy in the game and he received a proper name (and a candy cane).
Candyland and Space are my two favourite areas in the game. I had the most fun drawing them. I like futuristic things like Star Wars and such, so I knew I had to include a futuristic themed area. It was so delightful drawing these that I had more monsters in this area than any of the other individual areas had.
Just of note, each area has roughly 10 monsters and there are 10 areas. I didn’t go to each individual area and do a count, but this roughly means that there are over 100 enemies in the game! This figure is excluding the 20 area bosses and another 10 unique bosses (like the Guardian, Choco Yeti and other storyline-related one-time appearance enemies).
You might be wondering why the monsters do not have a ‘HIT‘ animation or why the monster only has a simply scaling idle animation. Am I just LAZY? Did I just simply could not be bothered to create more animation frames?
The reason is this – I simply do not have the resources to commit to animating several states for each monster, for 100+ monsters. It would require the game to be structured differently (maybe more enemy oriented, to have less enemies but make them have more detail.)
To be fair, some of the special monsters and bosses have attack animations, and it’s what makes them really stand out from the rest so people know they are fighting something significant and they retain a kind of special ‘status’ which differentiates it from even the area bosses. Currently only the storyline enemies have an attack animation and I intend to keep it that way.
At this moment this game only has 1 artist, programmer, designer and they are all the same person. It’s a lonely one man show and while I would want my game to have all these nice things and animations, sadly there is a limit to how much I can do in so much amount of time and I have to prioritize what goes in the game and what goes in the bin.
These are compromises that I have to make all the time and some of these decisions are not easy to make, such as having to scrap an entire equip item looting mechanic because some things look good on paper but are actually really unrealistic or just plain bad in actual implementation. (more on the item mechanic below)
If I had all the time and resources and manpower in the world, sure I could idealize the perfect game to make but I can’t. In making games, I learned that I have to exercise a lot of self control because if I don’t, I tend to go crazy and start adding content and features that the game was not initially designed for. Many people may think it looks trivial, but it can have very serious consequences.
The most painful decisions to make is to have to scrap something that had gone through so many iterations only to realize that it cannot be done and you have to acknowledge that despite all the time spent, something may just end up going out the window. But if there’s any consolation in that, it’s that you will (hopefully) be a wiser and more experienced person to know not to repeat the same mistake again. I think I talk about these things once in awhile in my posts and sometimes it is these invisible processes which most people do not get to see. Hopefully this didn’t come off as a rant, but if it did, the next time you see a long paragraph without pictures…you may want to avoid it haha.
Anyway, moving on…
As mentioned above, each character has skills. Above is an example of ‘Wisdom’, a buff that increases EXP gain for a short time, an old version of the ‘Weaken’ skill, which weakens an enemy, and ‘Dragon Skin’, which raises party members’ defense. The game has about 12 active and buff skills.
Skills in the game fall into three main categories:
Active Skills (attack the enemy with huge damage or multiple attacks)
Passive Skills (give you a stat)
Buffs (gain a boost in a particular stat for short duration)
Above were pictures of two buff skills when they were a work in progress.
The challenge came when some of the skills were really special and required me to do a few conditions. Take the Resurrection skill for example. When cast, it resurrects dead players, and restores some of their health (depends on the resurrection skill level) and gives them a protective buff.
This meant that Resurrection was not only was an active skill, but it also classified as a buff skill. It was tricky to code because the way I designed the skill structure did not cater for a skill that fell into two categories. But I managed to pull it off in the end. This is the same for drain, a passive skill that has a x% chance to cast a buff – is it categorized as passive or is it a buff?
Proper categorization is important because it affects a lot of things, such as whether the skill is able to be added to the skill tray or not.
The skill tray is where all active skills are displayed and the player can click on them to use them. Later on in the game, you can purchase AUTO-CAST which makes your skills cast themselves once the cooldown is over, a feature I felt was necessary in an idle game.
The skill tray was originally a scrollable interface which scrolls endlessly to the right when you acquire more skills, but I felt that was bad design and instead removed the scrolling while making excess skills roll over to a second row. To reduce clutter, skills on auto cast don’t get added to the skill tray, so even after the double-row implementation, the skill tray never leaks to the second row now.
My favourite skill is an attack called Eviscerate.
It decreases a percentage of the enemy defense and deals high damage. The skill has a cooldown of 1 minute, but each time you kill an enemy, its cooldown shortens by one second.
I used TexturePacker to pack my sprites before I learnt of the Unity SpritePacker.
Early on in the game, monsters dropped loot and you could collect basic equipment to upgrade the characters.
However, the design was very confusing for playtesters and they did not get the idea of the drop mechanic. So I scrapped it. I was kind of disappointed because quite some time was spent on this feature, but the game was better without it. I was not skilled enough then to make a good design work together with the UI and it was a nightmare on mobile trying to display this information to the player.
When the characters attack the enemy or are hit, damage numbers should appear over them or the monster.
While I had worked with bitmap fonts in Flash before, it proved to be something slightly more tricky to do in Unity. The font required alphabets because I had to do number formatting for big numbers (eg 1,200,000,000 displays as 1.2T)
When attacking, damage is displayed which floats up and fades off. In fact, I can take it a step further by making the number bounce, making it bigger as it first appears then shrink back as it floats up. Most standard web games don’t do this, but you can see that in some MMORPGs and takes the text quality up a notch. This was something I learned at my company 🙂
Because the damage numbers can be pretty resource intensive, there is an option to turn them off in the settings. This is true for particle effects as well which has a toggle on its own.
Speaking of particle effects, I went a step further and added a blood effect on players recently.
On the left is a continous blood effect which could be displayed when the character is low on health but it looked weird. On the right is a burst of blood that only appears when the character gets hit. I also changed the shape so it looks more like droplets than just circles. The blood effect was an idea by a friend that I thought would not fit well with the game graphics, but I made it cartoony and it ended up looking pretty decent and somewhat comical. This was actually a very interesting suggestion.
The Ascension System
This is a very huge feature but in summary, it basically resets all your characters’ stats and you start over from the beginning. Any unspent gems you have collected are converted into Enchanted Gems.
And as you can see, they give really huge bonuses to your character when held in possession. And not just that, they can also be used as a currency to purchase powerful upgrades from this guy:
Yep, he is the Guardian and when you meet him, you have to first defeat him as part of the storyline before he shares his powers with you. The fight takes place in a unique zone called ‘The Crossworld’ which you cannot access through normal means.
If you win, you get to own the Guardian and upgrading him will improve your prowess. Of course, this means sacrificing some of your own power since spending the Enchanted Gems means you get less boosts from it.
There are plans to have more guardians in the game, each one offering different abilities. Currently the other guardians are just colour reskins of the first one but I may add new abilities if the game gets enough attention.
When I make a game, there is a high chance that you will see achievements in it. It is not something I will leave out of my games, unless it’s a simple enough game. Even my first flash game, which was a platformer game, had it.
Introvert Storyline Milestones
In a lot of incremental games, they tend to duplicate achievement icons. It’s understandable – you have 100 achievements and drawing 100 icons is a lot of effort. It also makes it easy to identify what achievement it is. This game currently has 120 achievements and each achievement gives different rewards.
I don’t know if it helps, but I actually went to try and make it such that even when I duplicate the icons, I at least change some stuff like their saturation levels and hue so no two icons are exactly identical. The better achievements have more ‘powerful’ icons while your starting easier achievements are more dull. It may not look like it but just adding a little extra detail takes time and effort.
The achievements in this game are probably the most complex I ever made. There are two groups of rewards, one-time rewards and passive bonus rewards. One-time rewards are give you huge amounts of gold/EXP for achieving something. Passive bonus rewards are given by harder achievements, but they last a lifetime! Here are some of them (with arbitrary numbers)
Examples of One-time rewards:
Enchanted Gems +1
Examples of Passive rewards (these are permanent and last through ascensions):
Gold gain +2%
EXP gain +3%
Hero damage +4%
Hero HP +5%
The rewards are defined in the Achievements class.
As you can see it is possible for an achievement to give 5% hero HP and 3 enchanted gems (combining both passive and active rewards), but for simplicity’s sake and not to confuse the player, it is best to limit one type of achievement to give one or two types of reward at max. It keeps things organized and creates interesting gameplay like “the boss killer achievements give gems, they should be prioritised if you need gems, but if you need gold you can farm the other achievement”.
Each achievement’s rewards are entered in the editor, (see the green and pink fields above).
The other fields are set in the script because it’s more tedious to go through each item and enter their names manually.
The whole achievements system is pretty wacky. I categorized them by achievement type to keep them neat and to keep them displayed in a sorted and orderly fashion in the game’s UI. It also makes it easy to add a new achievement tier without messing up the order.
But because there are so many different tiers of achievements and different reward types, something can easily go wrong if you are not careful. For example, mistyping dmgMult *= 105 increases damage multiplier to 105x when it’s probably intended to be 1.05x. This really happened by the way, I kid you not when I say my damage inflated suddenly after earning an achievement.
Thankfully, there is a panel that summarizes your passive achievement bonuses, which is actually as useful to players as it is for me to see what the heck went wrong when something goes wrong.
The thing about this game is there are multiple sources of stats. For damage as an example, there is:
Achievement damage bonuses
Shop item damage bonuses
Guardian damage bonuses
Enchanted gem damage bonus and
Party damage Buffs
This is why it is actually very easy to screw up. They all have to work well with each other to keep the game balanced and working as intended. In my next post I will talk about the hero class and how all those different boosts work with each other.
While this game did not require a loading screen initially, loading times significantly increase on mobile devices and it required me to have one. I made this today:
A random tip is displayed when the game is loading. This screen is disabled on WebGL though as WebGL does not support multi threading. I’m not an extremely technical person, but from what I understand, how it works is that the game runs the loading screen on one thread and is asynchronously loading the game at the same time. The loading screen fetches the progress of the other thread and displays it on screen. However at the moment, WebGL cannot run two threads at once so it will wait for the loading screen to finish loading before loading the game scene. Thus, it defeats the purpose of loading a loading screen if it cannot load the main game scene simultaneously.
Game balancing has always been something important. This being my first game that had a lot of stats and complexity, I learned how to use excel and its formulas. Later on, you’ll see some of the things I’ve done with it (plotting graphs and using those data to compare the power of the different classes at different stages in the game.) But for now, here’s a simple screenshot of the basic math when the game was in early development.
It calculates the health of the enemy and how much time it takes to kill it. Then, it uses the gold gained to simulate upgrading of your damage, and with the new damage, writes how long would it take to kill the next enemy. My friend wrote this, but it helped me get to see the power of math and excel and made me see how useful these tools were in game design. He even colour-coded the time column so one can easily see where the values are at their lowest/highest – aka where progression peaks and drops.
This gameplay was inspired by other idle incremental games, like Clicker Heroes and Tap Tap Infinity. I wanted to go with a different approach – instead of having so many heroes, I wanted to focus on having only a small number of heroes and focus on their character instead. In Clicker Heroes, each hero isn’t very unique and to achieve maximum DPS, I found that I only needed to upgrade the top 3 strongest heroes. So I was only upgrading a maximum of 3 heroes at any one point in time.
This is somewhat applicable to another game I played as well. In Tap Titans, you always aim to upgrade the most powerful character until you get stuck and eventually return to upgrade previous characters. But at any one point, one character is contributing 99.9% of your DPS and the other characters are rendered obsolete.
There is of course nothing wrong with that design. I’m not saying it’s bad or anything. They work really well for Clicker Heroes and Tap Titans and they are really good games and my game likely will have similar problems. But I personally wanted my characters to stand out and have some depth, so I gave them mana, skills, unique abilities. Additionally, instead of making the enemy just a dummy for you to hit, they can fight back! I also added a storyline which reveals more about the game’s world as you progress.
I don’t know if this idea will work well, but it is of course a risk I took when I decided to walk down this path in directing the game’s design! You don’t need to look hard to pick out the flaws in my game’s design, but I’m still learning and my next game will definitely improve! I’m pretty sure there may be other games that may have done this. One of the games that has done this is Tap Heroes, which I drew inspiration from too.
It’s a very simple game (the characters don’t have skills and there is no ascension system or any complex features really), but it inspired me.
How long have I been working on this?
The short answer is… 1 year.
But that includes the time which I did not actually actively spend on making this game. I did not really dedicate a whole year to make this game… that sounds exhausting. So for a more precise answer, I looked through my update logs.
I write down any changelogs in the game and I keep track of every significant and here’s what I got from my change logs. The changelog is viewable in the game to anybody who plays, so they know what has changed since the last version.
Anyway, here’s a summary of the significant dates in the project timeline:
11 April 2015: Idle Heroes created
11 June 2015: Pushed a final update and stopped working on it
13 May 2016: Revived the project
28 May 2016: (Now)
So basically, I worked for two months, then stopped.
Then returned to work on it in May 2016, till now. I suppose if I were to count the actual production period, excluding the time which I did not work on it, it would be…
3 months spent to make this game!
It was a much shorter than I expected. I felt like I had worked on it for ages.
For comparison, my Tower Defense game was made in 10 weeks.
When I create my games, I often capture many screenshots of my development process. I don’t take screenshots all the time, but when I notice something really cool and worth talking about in detail, I take a screenshot and save them to talk about in my blog posts. I will look through my images as I’m writing. I even take videos sometimes.
Some of these screenshots are really interesting to see and I can’t wait to share some in the next few blog posts!
I’ll also write more of the behind-the-scenes technical issues I faced when trying to run this game on mobile and basic stuff I did to try and optimize a battery-draining and turn a slow, unplayable game into something playable. I’ll perhaps also talk about other stuff like texture crunching to reduce memory consumption on WebGL.
There’s also other features in this game I want to talk about that I was unable to cover in this post, like:
Character/NPC Dialogue system
The Journal Book
Main Menu design
Level 101+ Area Design
Clicking/tapping mechanic and upgrades
How all the systems/reward mechanics stack and work together
I actually completed my tower defense game about a month ago, but did not blog about it. (part 9 was supposedly my last post). The past month has been pretty crazy. It was wild and had lots of ups and downs, but I was able to spend one last week just finishing this game. It was week 10 then and the 10 weeks were really crazy.
I have added the official endings to this game as well as a secret ending. I have built it to be playable on Standalone, WebPlayer and WebGL (preview).This is how the final game looks.
For the WebPlayer, the game sits at a size of 26MB. It’s not too large, considering the scale of the game. The game is 50MB for WebGL.
The only thing left to do before publishing it would actually be to get people to test the game and provide feedback, which is pretty hard since I don’t really have any form of playerbase.
What’s left to do?
Aside from publishing this game, which is something I’ve always had trouble doing, I won’t have much time left to work on games any more since I will be preoccupied with daily work life now.
However, as I said earlier, this game was completed one month ago, so what have I been doing for the past one month? Have I been slacking off?
Well, I have been working on something really, really exciting for 5 weeks! It’s a game simulator. I had been inspired by several flash game simulators before – games which simulate another game and some of them deliver quite a wonderful experience and fun that the original game did not. And I want to make my own simulator.
OldStory2! That’s right, a new game project! It will simulate one of the childhood games I played, a game which I had played when I was much, much younger. Looking back there is quite a lot of ‘feels’ which have been lost in the real game. Many people probably have a childhood game -for other people it might be RuneScale, BattleOn, NeoPets, Miniclip, and they all have that magical feeling and place in each of our hearts. Just looking at youtube comments on videos of old soundtracks just gives me the feeling of wanting to make a game that has those feels.
I was really, really really hoping that I would get to work on smaller games since I know work+ studies are coming up and I really do not have much time to spare. But as I was listening to some nostalgic music, I got the ‘feels’ and I couldn’t resist the urge to create another game.
The game will be made with Unity, and will be my first attempt at the platformer genre with this game engine. Basically, I will be building this game from scratch, aside from the graphics and music of the original game.
For the past 5 weeks, I have been heavily developing this game and it really looks fantastic now. I have lots to talk about this game and I already amassed 60 screenshots and lots of draft development work to show. It was really just a mad dash for the past 5 weeks to try and get as much done as possible and for a game made in such short time, I find it actually filled with lots of content. People probably won’t believe this prototype was made in 5 weeks.
Alas, there’s so much to do and I will probably write about this soon. Oh there’s tons to talk about. The prototype is fairly playable. There’s quite a number of content and features implemented so far:
Platformer movement + game physics + slopes preview
Damage effects (multi-line damage numbers appearing over enemy / player)
Hit-able monsters and basic monster AI (about 10+ monster types, some of which can already cast magic/skills)
Several maps and portals to transition between levels
Item drops, item looting, skill unlocking and basic currency to buy stuff
Chat panel and messages
NPCs and a basic quest
Potions and ability to recover HP/MP
Advanced character stats (ability to crit, damage reduction, ignore defense, +buff duration, accuracy, avoidability) along with basic stats like HP,MP,Defense)
It’s kind of like an RPG already. I did list some trivial stuff like tutorial and the chat panel as well as UI. They may seem like ‘unimportant’ stuff that one can easily take for granted, but they actually take time to design and implement and is just as notable as other seemingly huge features like skill casting. Some of the stuff above are still in the test phase. For example, equipment cannot be scrolled properly yet, but can be enhanced and upgraded with money.
I will talk about the progress from week 1 to week 4 in the next few posts so you can see the scale of the game as it progresses and the incredible amount of effort it takes to actually make even a simple platformer work along with all those mechanics above in detail.
Even though I won’t be able to draw as much graphics for this game as my other games (IdleHeroes and my Tower Defense), it is still very fun to get involved in the process of developing a game.
Edit: This project is discontinued as of March 2016, but you may play the very incomplete game here:
I thought that there was going to be nothing else to talk about after the previous post since a lot of content is done. But there is still stuff to talk about, and I will go through what I have done for the past week (aside from final phase testing and polishing – a little bit on that in awhile).
Drawing the last map for the game
The is the last map to be drawn for the game. This was a side-map that I had left as a last priority and I really love this map. Everything from the texture to the colours was fun to do. It was also my last time setting up the waypoints and writing the grid array. Farewell, maps.
I think I kind of like all of the maps I drew toward the end of development because I just get so much inspiration when there are long intervals between each map I draw. I went with a very ‘dusty’ old theme for this map, using desaturated colours, which is very different from the sunny maps. I really like how ‘old’ the Hut appears to be. I should have added a few cracks and holes now that I think about it.
I used a basic texture, but I really like how some textures emote and make this game more interesting to look at. Oh, the Hut spawns monsters. In case that wasn’t obvious from the way the map pathway was laid out.
The game I’m making has grown a lot since 2 months ago and although I started out with a sandbox-like tower defense, it now has a lot of features and content that sets it apart from most other tower defense games. I didn’t have that aim in mind when I first started though – I don’t try too hard to be different and as mentioned in one of my previous posts, making a super unique game with never-before-seen mechanics is not exactly my top priority.
I’m looking forward to letting people play this game, especially with some of the cooler stuff and animations I put in the past few weeks.
Oh, and just for this map, I also drew and coded the final rune to be in this game – the Healing Rune. The name probably already implies what the rune does, but here’s a breakdown of all the runes in my game:
The runes are drawn to scale with one another. I didn’t actually mean to display the Runes and their information in such a presentable (and colorful) way. They look like the official tutorial or ‘help’ screens in the game but they aren’t.
I actually programmed a few unique ‘behaviours’.
Previously, my larva creeps (aka low HP + huge quantity creeps) move in single file. This usually isn’t a problem for normal creeps. But since larva spawn in bunches, it becomes harder to see individual larva when there’s so many of them because they overlap.
So I made them such that they actually zig zag around, with each individual larva having its own random zig zag. This is not only more realistic, but makes them more distinguishable and looks so much cooler.
The other behaviour I made work today was the Hadron Flyer, a special boss that IS ABLE TO TAKE OFF from the default pathway and FLY TOWARD THE END.
Basically, he converts from a ground-moving creep to a flyer, which can ignore the pathway and fly immediately to the exit. Of course, I had to bypass some limitations to make that happen. Now it’s not exactly overpowered because the player is still able to prevent this.
The movement looks simple but you got to be aware of a few things that need to happen when it takes off from the ground:
set its Flyer flag to true (to take into account modifiers like +100% damage to flying enemies)
change its ground waypoints to that of a Flyer
set its new end position
rotate the sprite toward its new end position based on its new calculated direction from current position
disable its acceleration (because it should not keep moving faster and faster now that it is already in the air)
This plane has a passive ability that increases its speed as it travels along a straight path. Take-off only occurs if the plane’s speed reaches 3. And this is preventable with Slow Turrets. I really like the idea of the plane taking off when its speed gets high. But this is the only boss with this ability and you only fight him on one of the optional side maps, so it’s a very rare behaviour and I doubt the player can actually experience it since all he needs is one slow turret to stop the plane from taking off. Still, it was fun to see this work.
I have also seem to finalized the upgrades in the game and their balancing/costs are about 80% settled. There are still two upgrades I have yet to balance.
I’m also converting some of the anti-alias-ed icons to pixel art so they look consistent in the overall skill icon design. And it was also the first time in a long time I went back to Paint, which was the software I originally used to create those skill icons years ago.
Yes, the pixel icons were made years ago with Paint (they were originally made for fun without the intention of actually using them as a game graphic). I merely made a few modifications to make them look up to par with my current graphics standard.
I haven’t yet found the best way to do loading, but because I use an atlas now, the game loads EVERY background map from the beginning. It no longer loads individually, which is what is done previously.
With 42 maps in one atlas, playing any map simply loads all 42 map graphics when I only need one. I don’t notice any delay on my computer, and my levels still insta-loads. But this can be a huge problem for players with slower computers. So what I do is to use static variables to store the Sprites.
This way, they don’t get destroyed when the player quits the level. He can go roam around in the main menu, come back and play the level and the background will be already pre-loaded and waiting for him. He doesn’t have to wait for the backgrounds to reload if he has entered a level before.
Simply put it, this should cut level loading times after the the first play. The effect is probably minimal if you already have a fast computer though. I’m still trying to see if there’s a better solution so I can do this for all my sprites without needing to make 100 static variables for 100 graphics.
Level Select Polishing/Improvements
The Level Select now scrolls much faster. I think it is due to the recent optimizations I made. There used to be a split second freeze when changing pages. But now it so smooth that I coded ‘animated’ moving bars. Notice how the bars move up and down as I switch pages:
It makes the level select look so much better and I really love the effect that there are 3 coloured bars and they all animate smoothly when I scroll through the Level Select.
The Unlimitor is a newly added structure in the game. When you build towers near it, they don’t count toward your total tower limit. (There is a maximum limit to how many towers you can have on the map at once).
This is a really cool concept I wish I explored more on. I don’t have space in the game to squeeze in more structures so I only added this to two of the final maps.
I made this structure for the final map because the final map is extremely large and the player would appreciate an increased limit.
I drew a ‘destroyed’ state so that player has to repair it before receiving the bonuses, but I removed it later on because I feel I have too many ‘broken and repair-able’ structures in the game that almost everything needs repairing, so this structure starts off REPAIRED. That’s like a free lunch in this world.
Oh, not sure if I mentioned this before but you not only repair stuff.
You also destroy stuff. How awesome is that?
Big Foot + Number Formatting
Notice also that in the information panel on the right side of that screenshot, I’ve also changed the way number displays work.
HP: 8,080,000,000 –> 8.080B
I have added a new option that when enabled, numbers or values above 99,999 are optionally displayed as 105k, or 1.5M instead of 1,500,000.
This is however, overriden when values get above 1 billion. I noticed numbers got pretty large on Nightmare game modes and it started to cause problems in the UI where they got resized to unreadable fonts or simply went off-screen.
So large numbers will automatically be formatted whether you have the option on or off, and I have set it to be off by default.
This doesn’t apply to all numbers. Numbers that I know won’t get that high are still displayed as per normal. I can also set how many decimal places the number formatting can go for each text. EXP is typically displayed with two decimal points because I don’t restrict its values.
The End-game Turret
I actually called it the Hybernium Turret. Not really liking the name but it was a draft placeholder name that I got used to from very very early on in development after using it countless times.
I mentioned previously that it’s a one of a kind turret that only appears on the last map and has a unique method of attack. I really love this turret because it’s really unique.
The turret fires a destructive Arc at its enemy. When it does so, some sparks fly off from the center for visual effects. In the screenshot above, The main arc is black, while the secondary arcs are white.
There were some bugs, such as incorrect length of the arc when it shoots enemies. But I managed to shoot down the bugs one by one. Eventually, I also made the attack behave more like an electric arc – adding fading effects and locking onto an enemy before it fades.
It is also capable of unleashing a devastating attack.
Also, for added coolness, its information panel displays its damage as “???”. According to my math and the damage formula I set for it, it should 1 hit KO most monsters up till wave 80.
Why wave 80? Because that is the level of the final boss when he is introduced. I don’t want the turret to 1HKO the final boss’ summons. Having the damage be kept secret also makes this turret a little bit more mysterious. But I’m not sure if it will pander players not knowing what its true damage is.
The Final Boss
Nah, that would be too cliche. Throughout the game you keep hearing of the final boss, but you never actually get to see him until the final map.
This boss was extremely problematic to do because the final map has infinite waves. It is the first and only map to feature a survival mode. Unlike other maps where the superboss is spawned on the last wave, the conditions to spawn this final boss is different.
To spawn the final boss, you have to upgrade the Hybernium Turret to its max level.
This is the only turret in the game to be able to go up to Level 10 (other turrets cap at level 9).
At level 10, it goes destructo-mode and all the waves disappear, and leaves you with only one final wave:
The final boss spawns from a special spot on the map, the Mysterious Rune.
The final boss is the only creep that has a ‘speech bubble’. Sort of. It can talk and the bubble also follows him around the map. There were two ways to go about it. Because text is classified as ‘UI’, they use screen space coordinates and uses a different camera to render.
Sprites like the enemies, my turrets and the map are actual world objects that occupy world space.
I initially attempted to make a Text Mesh. A Text Mesh does not require a UI Camera to render, so I am able to attach it to the enemy conveniently – it functions just like a 2D Sprite and I felt it was more intuitive that way.
Initially the text mesh appears blurry and I had problems with the sharpness of Text Meshes, but I eventually solved the blur issue.
But ultimately I did not use Text Meshes.
I went with UI Text, since that is what Text seems to be designed for. Using a Text mesh means that the text is at a constant fixed size, which normally isn’t a problem, but since my game allows you to zoom in and out, zooming out causes text to appear smaller. This is avoided if I simply use a UI Text.
This final map took me a long time to set up because of how differently it is made from normal maps. It’s not just the large map size, but also the turrets, enemies involved and the way the wave counter works. Special effects and conditions take a long time for me to add because the game doesn’t usually permit these sort of effects and I have to actually extend a lot of functions to make them work without hacks. So I hope it is worth all the effort.
I actually intend to do a proper ending to this game. The only other game I made that had proper endings and multiple endings was Introvert, a story-based game.
I was so intruiged and fascinated with the game’s story and possible endings that I decided to make the game have multiple endings:
Defeated (Bad Ending)
Victory without condition (Neutral Ending)
Victory with condition (Best Ending)
The outcomes of your final battle with the boss and the choices you make determines which ending you get. And yeah, the dialogue box does give you multiple options to choose from, which is very rare.
Oh, did I mention that you cannot quit or leave the battle when fighting the boss?
I think it really adds to the atmosphere. It is restrictive, so it only happens on the last wave. I don’t think it would be too bad. If you played up to the last wave and faced the last boss, I don’t think you would want to quit at that stage, right? The most likely option is if the player realises he is going to lose anyway, so he decides to restart the map, but realizes he has to wait for the boss to walk to the end and finish him. Hopefully this does not pander a lot – I actually need user feedback pertaining to this.
I have done a lot of fancy effects for cutscenes before, including lots of camera movement, parallax scrolling and animations. In this game, I just want something simple – 3 background art to illustrate the different endings.
Although I was supposed to only draw 3 large cutscene images, I ended up drawing 7. Well, at least that means it has a higher ratio of visuals to words for the ending. Here are the 3 original cutscenes:
A Mysterious Cube???
There was initially only planned to be one simple ending to the game, but I ended up adding a lot of special effects like a final superboss, a supermap and a superturret.
The originally ending was actually a pretty bleak ending. It was a bittersweet ending, but I later decided that the game should have one happy ending. Thus, I had hidden a somewhat secret ending in the game. It isn’t too hard to unlock it, but to view the ending you do have to satisfy two conditions. It’s not too hard (I could make it harder if I want to but there is no need to at the moment).
As you progress through the game, you start to find traces of a Mysterious Cube. This is a new object I added recently and is crucial to unlocking the ‘Happy Ending’.
Changes to the Booster Turrets
I changed the range formula for the booster turret and also, it now displays Grid Range rather than unit range, which can be a vague number to indicate the turret’s radius.
This is because the turret works differently (it does not shoot, it boosts nearby turrets). I also changed the way the RANGE UPGRADE skill affects this turret – it no longer affects. Instead, it receives a range boost from a separate skill, the ‘Advanced Boosters’ skill, which has other benefits as well.
I’m starting to polish the game up in the event that it does get released. Not much to talk about. They are really simple things but it’s cumulation of stuff like that which make the game imperfect:
Story and info panels could popup mid-battle and obstruct the screen while action is going on behind, so they now auto-pause the game when triggered during battle
Centering of crooked / improperly-aligned UI
More Bug Fixes
Things like having negative health because I use rounding to integers (2.147b max value) start to appear and I also get tons of other issues as I test various aspects of mid to late game. I’m basically ironing out a lot of the bugs.
At this stage, the game is unlikely to get any more new features or content, and I’m glad because developing any more new stuff is just going to add unnecessary complexity and also delay its release.
I’m now manually testing the last few stages of my game repeatedly. Trust me, it’s really very tiring. I would sometimes rather code and draw new stuff than test my game. And it’s not so much because the game is boring to play, but rather that I have to re-test the same level again and again until I get a good feeling about the difficulty.
With the addition of ‘recommended level’ displays. I also have to play the same map multiple times with different savefiles where my character is at different levels with different skill points, to get the MINIMUM level required to attempt that stage. Unfortunately, Math won’t help much with this type of balancing.
Last week, I had did the balancing up till Map 20. This week, I managed to balance Maps 21 to 29, leaving me to balance the last map on Normal Mode. Then comes balancing of the difficulty modes and the Challenge Maps.
Oh, and the game now has a big alien ship as a final boss on the ‘Area 52’ map I recently drew.
A Game is never done…
I think one thing I (and probably a lot of people) have to realise is that the process of making a game never really ends. Even when you release it, you want to always make it better – and I’m not talking about fixing bugs. I’m talking about adding features or content that players request for – to make the game better, increase its lifespan, etc.
When making this game I had to cut out a lot of ideas due to the lack of time, especially toward the end. Things in my ‘impossible’ scope truly never made it:
Character Equipment (I actually coded an inventory manager and boosting of hero stats if he wears equipment, but I don’t have time to implement).
Shop & Currency. I coded a simple shop in my previous game, IdleHeroes, and I could very well use some of its implementations here. In my design document, I drafted ‘Boss Tokens’ as a special rare currency from bosses that could be used to purchase powerful equipment to boost the hero, which is actually very under-used in the game. This feature is tied to the Equipment mechanic.
A Technology Laboratory with specific branched upgrades. Different research paths would give players customization over the turrets and add further strategic depth to the game.
Active skills. Abilities like casting a meteorite to damage creeps, summoning your own runes to battlefield(!), and increasing gold gain for short durations were very real ideas I drafted in my Impossible scope. I actually made my Rune script similar to turrets so that I can plant runes on the battlefield just like turrets. I have in the game a ‘discard-able’ UI which was reserved specifically for such features that would require an extended UI.
The list can go on really and I bet there will be players who when playing the game, would suggest/request the above feature(s) to be added.
Even for OldStory, the game I published earlier this year, I got messages and PMs from players asking me to add content – new classes, increased money cap, more stuff to do after 40 New Game Pluses (and boy I never expected people to play up till FORTY New Games). I was really happy to hear that. Well, point is, a game is hardly finished even as it is published.
But I’m glad that I was able to implement a lot of the things I set out to do and beyond that. And even without those features, the game already has quite a lot of content, more than the simple sandbox in my documented small scope.
Future Plans (Sidetrack)
After I am done with developing this game, it is likely I will spend the first few weeks of its release fixing any bugs that manage to slip past me (though I will try very hard to prevent this, I don’t have a lot of friends/testers, so it might be inevitable that some bugs will get through in my final testing phase), and also time will be spent updating the game based on user feedback.
But skipping past that, I would likely not have time to make another game of this scale, which is kind of sad. I even felt like making a sequel to this game to fix all the “issues” that the current game has but are too late to fix. There are a lot of things I wish I could do, that I wish I had the time for, but I don’t.
But if I am somehow able to squeeze time out of University life, there are 3 things I really want to do.
1. Continue making (smaller scaled) games
The first is to of course, create shorter, simpler games. I have been always working on seemingly bigger games than I can take on due to being very ambitious and how much I enjoy making games, but I would have to implement some kind of deadline so my passion doesn’t go out of control. But making games alone is truly a time sink. Unless I find a company/team or a group of people with the same common interests as I do, I think it would be best for me to restrict myself to ‘A Game in 14 Days’ kind of rule if I were to continue game development solo. Smaller games might be fun to make and it would be interesting to see what I can whip up in two weeks.
It’s also less risky and beneficial to players as well. If I make a game that is well-received by people and has generally favourable reviews with potential for expansion, I would focus more development time to update and improve it, and maybe even make a version 2. Whereas games with a design that isn’t as fun is best to be left behind and forgotten. I don’t want to waste peoples’ time playing a poorly designed game.
The only problem I guess is that unless the idea of the game is very strong, a game made in 14 days wouldn’t have much depth or features. It would expose me to developing games of different genres, but the output would be something pretty generic – I would be doing it more for the experience than the reward of having a polished, finalized game.
On 25 January, I took a break from game development and I made my very first Flash Animation. I was inspired to learn flash animation because of two things I saw.
First, I had been to this place where I saw artists sketching out frame by frame animations. There was this animation of a character jumping from one hill to another. It was short but it sparked something deep within me – I wanted to be like them and do animations too!
Then, I saw a very cool looking 8 bit animation. It was similar to the way I animated sprites in Introvert and was something that looked like it belonged in an 8-bit game.
Feeling totally awed, I wanted to learn Flash animation. Sadly, I had no prior ‘training’ or ‘formal education’ in animations. I did have experience from sprites I drew for my games. But I felt very left out compared to those people I saw who had undergone such education and were steps ahead of me – people from design backgrounds, or art schools.
Nevertheless, I decided to do a stick figure fight.
My first attempt went really horrible – I tried bone animations but it felt very unnatural to me and tedious. I decided to go with the more hands on approach – literally using my hands to draw the stickman rather than using the mouse to construct and rotate its joints.
I started drawing stick figures, animating them walking frame by frame and to my surprise, I felt like I was actually doing quite well. It was my first time actually animating a stick figure. The frames were pretty smooth and it didn’t look too amateur-ish! I just drew one frame, then another, then another, and I hardly Ctrl+Z-ed. I was just so invested in drawing that hours passed without my knowledge.
It was such an exhilarating experience and I will never forget it – the bitter taste of my initial failure, followed by watching my 5-second long animation play out was second after second of pure joy.
3. Just drawing and drawing
Whenever I get very invested in developing games for weeks and months, I put off a lot of other tasks in my ever-growing TO-DO list.
Depending on the colour of the sticky note, it could be a list of comics to draw, a list of games to play, a list of links to visit… They are basically everything I wanted to do but had to push off. When I have the time, I will be drawing more comics like I have always done, with more room and time for ideas and at a more leisurely pace. I will probably draw more miscellaneous inspirational backgrounds too since I sometimes find myself getting inspired really easily.
So what’s left? I think I actually am somewhat able to see the end of the tunnel. But it’s still very far. I also had a three day-long disruption because my computer could not start up and had to be sent for servicing. It just had to happen on a weekend too.
Content wise, I am left with the special effects of the Final Map and making the actual Endings.
Balancing wise, I have about two maps I have yet to balance. And I also have to ensure that Nightmare mode is not too difficult on the last few levels.
Other than that, the game is playable in all other aspects, and I am happy about that.
This is the 2-month anniversary of my game. Exactly two months and 1 day has passed since I started making this game and this post will cover what I have done in the past week.
In case I have not shown a screenshot of the tutorial and keyboard settings I drew, well, here they are! I personally love the Shortcut Keys information pane
It took 2 hours to draw the keyboard settings because I was trying to get the placement of all the text right and also yeah, I wanted to do something colourful. But I spent most of the time trying on alignment and moving the different buttons and text around to find the best placement to display the information in a tight space.
Buildings that summon monsters
I added a new building type to the game, an underground bunker. This is one of the coolest things because it actually aids balancing rather than hamper it. This mysterious building has its doors locked at first, but you can open it and it will let out creeps!
This makes the map harder but more creeps means you get higher scores and EXP.
This is more for hardcore players who want a challenge. This was not as easy to code as I thought. This was identical to making a duplicate map spawner – this spawner spawns a fixed creep type and adds a fixed number of creep spawns every wave. It also has its own pathing and I now track enemies on map separately – normal enemies and bonus enemies from building spawns.
As a bonus, if you win the map with this added challenge, the underground bunker reveals and unlocks a secret map – Area 52.
I didn’t call this map ‘Area 52’ for nothing. It is definitely one of the coolest Challenge maps I have drawn.
Epic Map #4
I began production on the fourth epic map. (This game has 5 Epic Maps in total and the fifth one is the last level). I toned down on the special effects for this map. However, this map has quite a few story panels and the runes at the center will eventually appear. This map is pretty challenging since it is the first Epic map to feature four entrances. But take a look at the next map.
I love big, epic things. If that wasn’t obvious enough while making this game, it probably is now:
Behold, the biggest map in the game. Four times the size of a normal map. It’s hard to imagine the scale because every picture in this post is the same size -_-. The screenshot above was resized just enough to be able to fit within the blog window, so I had to put a few creeps and turrets on the map for scale. To view the entire map while playing the game, you need to zoom out to 0.5x ZOOM, which makes everything look really puny.
This, this is the only one level of this size and it is the final level. I am finally here. It took forever to implement the last few levels. This is probably one of the last few fun things to actually draw for my game. After this, I would be mostly polishing, sounds/music, and a lot of the important, but not so interesting stuff: Bug fixing, Testing the game and Balancing. These are the stuff that I don’t usually talk about because there isn’t much to say about them when I work on them.
I had been saving the monstrous task of drawing final map to when I have inspiration to do something cool, and also to when I got sick of coding (which I have been doing plenty of the past few days – it’s just so exhausting).
I kept a notepad of what I wanted to do with the final map – accumulating all the cool ideas. It’s really overflowing with ideas that I got to tell myself to STOP or this game will never be done.
There’s something subtle about this map and it’s that it uses a new texture – I realize I had been using the same map texture for over 30 maps. Though I have to say, drawing such a huge map was a nightmare and not actually as fun as I expected.
It was extremely laggy trying to draw it on my tablet. Photoshop also takes nearly half a minute just to compress the map in each time I export it.
The final level also introduces the last creep type in the game. I didn’t draw him ‘just’ to get another creep type in the game. It came purely out of inspiration and I guess it’s what made him look pretty cool and different from standard creeps even though he borrows his basic shapes and features from one:
I can’t wait to actually see him in-game. His body is actually completely transparent. I called him MagiCreep because he looks very fantasy-magical like. Yup, only the visuals were inspired, not the name ideation. I had to make one up on the spot when giving it a name in the script and I went with MagiCreep because the default name is “Creep” and after donating all the cool creep names to my previous creeps, I simply ran out of ideas. Way to go, brain!
I don’t think I talked about this in the previous post. The Nullifier is a turret I made. It has a special ability – it can convert any creep into a Normal Creep. It will lose its special ability, and its stats (speed, health, armor) will be reset to that of a normal creep. I think this kind of special things can be hard to do in some game, but thankfully my game was setup in a way that I realized this wasn’t hard to do at all. Because I use a single enemy prefab and switch between animation states depending on its identity, it turned out I just needed to flick a few switches and reset the creep’s initialization code to ‘transform’ a special creep into a normal one.
This code resets everything from its name to its core stats.
I added a new currency called ‘Crystals’ this is ONLY usable in the last and final level. It isn’t introduced until then because it has a very special and unique purpose that players who reach Map 30 (the last map) will discover. Also unlike gold, you can’t get it from normal creeps – it would defeat the purpose of adding another currency if you could and it’s what makes this currency special.
I’ve also added special buildings that can harvest crystals from the “Crystal Spots” on the map.
Together with crystals, I added a new turret to the game. (not referring to the Mining Turrets above as those are technically buildings)
There is now a 13th Turret. The game had all along planned to have only 12 main turrets, from beginning to end. My intention from the beginning was not to have more than 12 buildable turrets in this game and that intention hasn’t changed.
This final turret cannot be built by the player and appears only in the final map. Therefore, it is essentially a turret that only appears on one map. Apart from the Hero, this has got to be the most unique turret of all. It can only be upgraded with the new special Crystals currency.
And just for an added ‘twist’, this turret starts off as something insignificant – a destroyed building. I really love how this structure looks – the cracks and broken roof.
The turret also has a very unique way of firing. This is the first turret in my game to have a unique bullet property – Electric Arc. Talk about saving the best for last, I hope players actually make it this far to experience all this stuff. Especially the map – that monstrous map alone probably adds half a megabyte to the game size. Using asset bundles would have really helped shave off a few megabytes off this game’s size, especially for players who don’t manage to reach the last map.
I was going to use this tutorial to create lightning arcs for the new turret. But ultimately I adopted a simpler approach. When this turret fires, it creates an electric arc between itself and its target, which then slowly fades away.
After getting that done, I was about to dive deep into a really complex world. Behold…
This was surprisingly fun to talk about despite it being something more to the technical side, but this is important stuff to a game artist.
From here onward, I shall hand over to my programmer alter-ego, who will talk about the steps I took to reduce my game size – and explain how my game dropped from 84MB to JUST 33MB, a real feat in my opinion. And at the end, I’ll let you know whether it dropped further and what my final game size actually is at the moment!
It might be interesting to read if you’re into computer graphics or something like it, and pretty much related to artists as it can be to programmers. My post from here on gets kind of wordy because there isn’t much visuals I can use to illustrate what goes on behind the scenes because it’s more to the technical side and yeah, art does get a bit technical even in 2D graphics.
The Magic of Power of Two
A Power of Two (POT) sprite is an image that isn’t just a square, but it must also be in sizes of:
64 x 64
128 x 128
256 x 256
512 x 512
1024 x 1024 and so on
Here’s an example:
Essentially, you could convert any image to a POT image just by adding some extra pixels around it, but I was exploring better ways to generate POT textures.
I previously thought that there was no clear advantage to use NPOT (Non-power of two) textures VS POT textures. But today I learnt that using POT textures are a tremendous advantage for a game made in Unity. There are other side advantages like performances and mipmaps, but file size was what I was most interested in.
My game had grown to a whopping 84,968KB (85MB) after the latest map additions (mostly thanks to that giant 2.5k by 2.5k pixel map) and this is really bad.
All my maps use NPOT RGB 24bit textures without any compression applied to the map textures. I decided to just cheaply convert it to an unoptimized POT texture just by adding some blank pixels. The image grew from 6400 x 6280 pixels to 8192 x 8192 pixels:
So now you got two of the same images, but one is ‘enlarged’ to have extra pixels for the purpose of making it a Power of Two image. Previously, my ‘MapBackgrounds’ had an uncompressed size of 152MB. But thanks to POT, Unity is able to apply DXT5 compression and the size of the texture has reduced to 85.3MB.
85MB (POT DXT5)
So in summary, with this new data, this is what the updated comparison of the two images looks like side by side:
The new image on the right has a larger file size and is bigger (because it has more pixels) but I was curious to see what effect compressionhad on the build size. I built my game, and when I saw the size of the output, I could not believe what I was seeing.
Game size: 33,861KB, or 34MB. My game had less than HALF of its initial size!!! You won’t believe how overwhelmed by excitement I was to see that. For a game to actually drop by HALF its size is miraculous if you ask me. Of everything I had done so far, I was only able to shave off the game’s size by a few MB at a time, yet this just took a huge 40MB chunk out of the equation with very little work. (Most of the effort was actually me trying to understand what it takes to make compression work and what is going on when the game converts all the textures and generates the game file)
From what I understand, Unity was able to apply DXT5 compression to compress my POT textures, resulting in a drastically smaller final game size.
But were the quality of my textures compromised?
The only problem with POT textures, which may be more of an annoyance would be that it looks pretty ugly. But more than just an annoyance, it’s also a huge waste of image space where the empty pixels could have been used for something.
The reason for the unused space is due to inefficiently expanding the spritesheet for the purpose of getting a POT texture size. This was the slightly unoptimized way of doing things. I made the sprite above for testing purposes. But when it comes to officially creating the actual texture, I use TexturePacker.
I used TexturePacker for lots of development work in OldStory, a game where I heavily relied on spritesheets for animations, but the time has come to now use it again. How it works is you dump a bunch of pictures TexturePacker and it uses an algorithm to rearrange them in a single image that uses the least amount of space possible.
Image courtesy of YYZ
The software also leaves you the freedom to choose how you want your images to be packed
Allow image rotation?
Constrain final sprite to square?
Add padding between sprites?
Any max size?
And the most important: A checkbox to force the final output to be Power of Two
Instead of having two map backgrounds, I now have a main map background that fully utilizes as much of the 8192 by 8192 POT texture space.
Then I have another secondary sheet which optimizes the space for the leftover maps. The same can be done for UI too. You’ve probably already seen me trying to generate a texture atlas before by putting multiple sprites into a single image.
You can see how well TexturePacker actually divides the sprites so there is actually very little unused space even when everything has varying shapes and sizes. Most of the transparency actually comes from my individual spritesheets.
Last week, I used TexturePacker. But it was for fun and used to judge assets by size, but perhaps I will actually be doing this for real for some of the assets in my game. However, I can’t just paste all my sprites into a single texture and expect my game to know how to reference them. There is still more work to be done to achieve something like that.
But assuming I get something like that to work, rather than having blank space, I might be able to squeeze in assets using this to tightly pack my textures together before slicing them respectively with Unity for use in the actual game.
Having converted my maps into POT textures, I decided to move on to converting other assets of my game: The Creeps.
After importing my latest creep assets, my game size increased slightly, to 34,488KB. At 34MB, it is already pretty small, but can it drop further?
I decided to apply POT atlases to the creeps. I wanted to do a trial test by converting half of the creep assets. I had to figure out what was best for my game – having two smaller atlases (512 by 512 px), or have one huge atlas (1024 by 1024 px).
I decided to try them both and here are the results:
34,488KB – Normal creeps (individual sprites)
34,468KB – Two smaller POT atlases of 512 x 512
34,401KB – (POT texture atlas-ed creeps) -> one big 1024 x 1024 creep atlas
Amazingly, the bigger, but single atlas worked best, but not by much. It does show that empty pixels don’t matter much to game size and is more of an eyesore, but still it’s best to avoid them when possible. Even though the atlas-ing was only done for less than half of creeps, the results were underwhelming – only 87 net KB saved.
It seemed like I had stretched the limits of compression. But then, I was just about to encounter a huge gamechanger…
The Magic of SpritePacker!
While TexturePacker is a fantastic software and was my first time using a software of its kind, I realized that Texture Packer had some limitations, mostly because I was using its Lite version and some of the best features were locked. It was at this point that I was told about SpritePacker, which is essentially a ‘TexturePacker’ that is built into Unity itself.
From what I understand, SpritePacker does what TexturePacker does, but reduces several steps I normally do. I can tag several images in my game to compact into a POT texture. Then, Unity will actually automatically add it into an Atlas!
It actually seemed too good to be true. Why didn’t I use this for my maps? However, according to Unity, this is actually done behind the scenes automatically all the time. Having me manually do it, I wondered if I would actually be able to save space at all. I decided to take a look at UI.
In my previous post, I did a bar chart estimation of my asset sizes. UI ranked highest as the single-most space consuming asset bunch (after Backgrounds), compared to my Turrets and Creeps. I decided to do both my UI and turrets.
So I used SpritePacker to convert them. Here’s the results:
34,468KB – Default UI textures
33,305KB – UI POT
32,549KB – Turrets POT
AWESOME! 1MB saved from UI compression and another 1MB from Turrets compression. I was amazed!
At 32MB, it seemed like the game could not go any lower for what it has.
But there was one more thing to compress – InfoPanels. InfoPanels are basically story panels. They are like pictures that tell the story as you progress through the game, like a comic and its individual panels. I have 62 panels in the game to date. Prior to today, I had a temporary 4k x 1.5k graphic sitting in my assets folder containing all the panels. I decided to first uncompress it to its original format, then try to see what effects both TexturePacker and SpritePacker had on it…
32,767KB – Default Panels without spritesheet or atlas (aka uncompressed) 32,549KB – Info Panels NPOT spritesheet by Texturepacker 25,141KB – Info Panel POT atlas by Sprite Packer
23,264KB – Without InfoPanels
The sizes in red is the important stuff. I added a ‘size without infopanels’ to see what the game is like without the InfoPanels at all. In a sense, it’s a “control” variable. I was really amazed by what SpritePacker did.
Without compromising quality, SpritePacker had taken 25% OFF my game size like some discount from a mega sales. I was really ecstatic to see this. Just when I thought the game couldn’t get any smaller, TADA! SpritePacker comes to save the day.
TexturePacker does have its advantages though and I still use it – it all depends on what game you’re making and very project dependent and also depends on how large your textures are. For example, Unity’s SpritePacker doesn’t go higher than 2048px (unless I missed a max size setting), so for my Backgrounds, I still continued to use TexturePacker to pack them and I also pack with it some miscellaneous background environment props to further conserve space. Since the props are smaller, they are VERY good at filling up the extra “empty” space usually caused by the background atlas. I didn’t even need to switch on the built in algorithm that TexturePacker had and I organized the props by max height because it is easier on my eyes – empty/transparent pixels don’t take up much space ultimately. It just looks ugly.
After using TexturePacker again to optimize the second round of leftover backgrounds which were not included in round #1, and using a combination of Unity’s automated slicing to slice some of my environment props, I managed to push the game size to slightly lower. Guess how much it saved? Slightly under 1MB I would say.
Final game size: 24,432 KB ?
With every 1MB I take out of the game, it gets harder to reduce the next MB, so after so many reductions, being able to take out another final Megabyte was satisfying.
That is, until I realized I had yet to convert my bullets/object atlases, so I went to convert them!
New current final game size: 23,987 KB
Well, I think this is the lowest the game can go. There has yet to be music added to the game and based on my previous experimentation, 4 (uncompressed) music tracks added 20MB to the game size, so it still isn’t “safe” from hitting 50MB. I still have yet to explore sound compression at the moment. The game also lacks a few InfoPanels which I have yet to draw so the art assets can still bump up in size.
Before I end the topic of game sizes, I thought that maybe you’d want to know an earlier attempt I had at reducing the game size.
The Magic of Spritesheets?
There’s just so many things I want to say about spritesheets, but first, I was testing a lot with compression. This was back when I had just added SUPER HUGE map to the game and I had yet to do any sort of compression so my game was whopping 78MB.
Unity uses a very complex compression technique – LZMA. I didn’t read up on it and I’m fully aware that any attempt I make to try to understand it will only lead to more confusion.
Compression has always been a very mysterious thing. From what I learned, the advantage of using a spritesheet (a single PNG containing 4 frames) as opposed to having 4 separate PNGS with 4 images has two advantages – the game makes lesser draw calls because it references one texture instead of 4 when rendering your sprite as it animates, and secondly, a well made texture atlas/spritesheet can help reduce the game size slightly.
I had always been confused by compressed vs uncompressed sizes – but over time I am trying to understand it bit by bit. From what I understand, when I export an image out from Photoshop into Unity, the image is compressed by Photoshop (for JPG) to a lossy format. But when it enters Unity, the image is uncompressed, so a 1MB JPG can become 5MB in Unity. Unity then applies its own compression which more efficiently reduces its size and results in the final build size usually being much smaller.
(Sidenote: This is partially why I later converted to using PNGs, because I lose precious image data and quality when I save my maps as JPG)
The tricky thing is, putting textures together can reduce file size, but it might not be a lot. I decided to test it out – I did this before with my maps, but it resulted in a net size improvement of less than 1MB.
This time, I tried again and exported a spritesheet of 30 huge maps. The image’s file size was 20MB, and when I put it in my game. A miracle happened.
My game went from 78,705KB to 27,771KB.
I was totally shocked. Nothing makes sense. I don’t actually know how this huge drop in file size is attributed to. File format? Spritesheet? I guess there’s a lot about compression I have to learn, but I did the same thing to my Story Panels…
And my game went from 27,771KB to 24,174KB. For something pretty small, a 3MB drop is still pretty significant. I of course tested the visual quality of the game. There’s always tradeoffs when you see such a huge drop in file sizes.
The game was not as fantastic-looking as before and started to blur out when I ran the game at full screen resolution. Then I realized why….
In my rush, I had forgotten that I had the max size of my spritesheet set to 2048, which greatly reduced both size of the game AND the quality of the spritesheet.
This caused my 6000 by 6000px map texture to be supercompressed from 150MB to 15MB and this resulted in a final game size of 27MB.
I was very disappointed in myself. I got all excited for nothing.
Anyhow, the game is also currently pretty funky on fullscreen, but it’s a last priority to fix since this will not happen if I deploy to a fixed resolution on the web.
Sure, my game’s final resolution will only be 800 x 600, but the loss in quality is noticeable. Plus, I heard from my friend there is Retina display for PC as well, but aside from the complex issue with resolutions, this just doesn’t look good at all. Setting a 2048 x 2048 max size is a NO-GO.
When I was experimenting with a UI Atlas before actually implementing it with SpritePacker later on, I wanted to first get an overview of all the UI I have in my game and I found something interesting.There is a particular blue button that is 700 pixels wide. I highlighted it above. That’s almost as wide as the default screen resolution of my game. It’s crazy. I must have forgotten to resize it on oversight. Although SpritePacker does a lot of the atlas work for me, I was actually thinking of doing t manually at first because I had no idea that SpritePacker existed. I was looking at the UI atlas summary, identifying which UI buttons could be grouped together and which were better left off alone. The overview allowed me to see which buttons are similar in sizes so I can group them together in a texture atlas if I were to do it manually. Or rather in this case, a UI atlas.
PNG vs JPEG – in a game
Now that I know more about compression, I figured that it would be best to use PNGs in my game. They are not lossy, and since I use POT textures, Unity will apply its own DXR5 compression. Thus, I want to save my image in the highest possible quality before compression takes place.
So I spent a good hour convering all my JPG backgrounds into PNGs. I would actually gladly hire an assistant to do all these miscellaneous tasks. Hey, it’s not an easy job you know – you have to open dozens of huge PSD files, resize them and crop out unecessary background. Then you have to stare at the loading bar after each process because it can take quite awhile to resize and save each file. Repeat this step for 44 maps.
First, you stare at this loading bar:
Then this one:
And finally wait for the file to save (which takes as long as it does to read the file):
Now imagine doing this another 43 times. Though there is an easier way to do this – there’s a shortcut to automate saving PSDs to PNGs, I’m not sure if it is able to automate cropping and resizing, and I do have multiple maps saved in some of the PSDs.
I got to admit, it was fun for awhile multi-tasking operations on my secondary monitors, but it got pretty repetitive fast. (I was typing this post as my images are being resized and saved). I also do a visual-check to make sure my exported PNGs do not have any missing detail from their JPEG counterparts. (Sometimes I have multiple versions of a file because I save final touch ups or small changes in details and I store them as alternate PSD files – v1, v2, v3, but I may end up using V2 as the final version because it looks better and I do not delete the v3 file, which is probably bad working protocol on my part. But we all learn from mistakes, right?).
To add even more complications, I was also experimenting a lot with file sizes with just PNGs alone this time. To showcase it, here are 3 PNG images.
They all look the same (and I overlapped them in Photoshop just to make sure). Unlike Lossy formats like JPG, if I were to go through them pixel by pixel with a color picker, they probably are identical. But they have 3 different file sizes and were saved in different formats/software.
(A) was the output of Texture Packer: Size 6.2MB
(B) is a non-interlaced PNG saved in Photoshop: Size: 6.17MB
(C) is an interlaced PNG saved in Photoshop – Size: 8.2MB
All this time I had been using interlaced PNGs and only today did I actually learn that it does not have any advantage in my game. I can’t assume that interlaced is bad because it generates larger file size because I’m not too sure if the disadvantage of larger file sizes means anything – Unity might just ignore the extra data in the image and compress it just as much either way. The world of compression is just so complex…
One last magic trick…
One last amazing discovery – I had a bunch of 220 x 110 px images. I enlarged them so they could fit in with a spritesheet of 440 x 220 images. Even though the resulting file size was bigger, and should theoretically result in a larger final game size, it ultimately resulted in a smaller final build size – likely due to the way Unity compresses textures that are grouped together.
So voila! Blowing up an image to a higher res to make it fit into a spritesheet actually makes the final game size smaller. I don’t think this always works and may probably only work under the right conditions in certain scenarios. I did this not with the intent of saving space, but to try and find the best practice for packing my spritesheets. Though it saved only a few KB, it was a pretty amazing discovery and it just goes to show the complexity of compression.
The Atlas Dilemma
There are a few instances where I actually have to decide what’s best for the game. Take the very early example of when I was trying to fill up an enemy atlas.
On the left is a huge 1024 x 1024 POT texture, and on the right is a 512 x 512 texture. (Look at the area represented by ‘white’ space representing the actual texture). Mathematically speaking, the one on the right is more efficient in terms of space usage. It squeezes 6 enemies to one atlas, and only requires three 512 x 512 atlas, using up only 75% of the space that an entire 1024 x 1024 texture uses.
But though it is more efficient (in the sense that it has a smaller ratio of empty space) the disadvantage is of course not being able to access the fully array of enemy sprites from one texture atlas, and packing very few sprites kind of defeats the point of the atlas.
Though transparent pixels don’t take up much space themselves, I don’t think anybody likes to have too much transparency. I have a very ambitious idea on how to actually pack every single sprite into an atlas, including actually removing the empty space between the individual sprite frames! This ambitious idea also allows me to automate sprite slicing – a somewhat tedious technique to do if I have varying sprite sizes in an atlas where some creeps are sliced into grids, and some aren’t. For those creeps, I have to divide the sprites into multiple ‘frames’ in Unity manually.
Sadly, this idea is too late to do now and requires a lot of manual work (therefore ambitious).
If I ever make another game after this one, it will definitely be more optimized.
Though most of my week was spent on optimizations, compressions, here are some other things I did:
I love Math, but only when I’m able to solve it. This particular game has lots of Math involved.
Due to the Math involved in some areas of this game, I sometimes use my WACOM to draw out diagrams to countercheck in-game values. The diagram above is to calculate the game camera’s boundaries while panning and to recalculate boundaries based on the current zoom level. (More on this later)
I’ve been finetuning a lot of things. I can’t remember all of it but just recently I added right clicking to center the camera at a particular spot. I also wondered if I should add detailed statistics to individual turrets, but decided against it since it got very messy.
Some difficult to understand options have [i] buttons to learn more about them.
I can’t remember what other things I’ve done. They are mostly the little things I feel would make playing the game a better experience.
Lots of bug fixes
In the past days I have been fixing bugs. Lots and lots of bugs. The game has grown pretty complex and there’s just so much going on.
I really look up to programmers. I sometimes wonder how a team of programmers work together. For me, I know my entire game code inside out so when a bug occurs and when I’m lucky, I can almost immediately tell which script the bug lies in and how to rectify it. But this is rare and usually only for bugs caused by oversight, like this one:
The Booster turret I added previously ends up being able to buff turrets of its type. Sure, it is not able to buff itself and I thought that code was sufficient. But if you build two boosters, they buff each other, which increases their range, and if you have like 10 boosters, they start boosting each other, which increases their range to be in range of more boosters, which boost their range, to boost your range, to boost their range to boost yours! And suddenly you got a booster which has a range covering 75% of the map!
Keep trying and trying…
I’m probably the last person you would turn to to get motivation, but here’s a short story. I was up late night coding. (I was rewriting my entire camera code to support even more dynamic zoom for the final level with the huge map)
I was trying and trying again and again to get my camera bounds correct a.k.a trying to fix a bug with the game camera.
Every time I thought I nailed it, I’d say “This should do it.” Then I’d run the game and something would go wrong.
Then I’d go back to code, change a few lines, then go back and run the game, and then another thing would go wrong.
Then frustrated, but determined, I’d go back to the code, check through it, change more stuff, and I’d say “Okay, this should work.” Then I run the game, and BAM I’m back to where I started. You can imagine me looking at the screen in frustration at this stage.
But after looping through the steps above like as though I was in a for-loop myself, I get a bit more ‘attentive’ each time and just a tiny bit closer to tracking down the bug. I get closer and closer to a solution each time. And even if I don’t, I’d at least cross out what ISN’T causing the bug. Programming is really tricky though, so sometimes I can spend a really long time trying to find the bug. It’s even more frustrating when you find out it’s something stupid.
But after a few hours, BAM success! So yea, you sometimes just got to keep trying and trying. Not blindly though – you got to know where your mistakes lie and not make the same one again. I do that sometimes and it really bites you, so instead of a ‘Once bitten twice shy’ kind of bite, it became more like ‘Once bitten, twice bitten…’ or something. Whatever.
So that’s what making this game is all about – I just keep trying and trying until I get it right or else if I don’t get it right, I make a terrible game. This is true for everything I do. Even for balancing. The balancing was really horrible at the start. It’s still not perfect now, but it is much better than before.
I don’t think I have as much problems with art, but I guess that’s a really subjective matter. I remember struggling a lot with the pixel art and character sizes in Introvert because I was really inexperienced with Flash and character sizes. (This was back in 2013, when I was still studying and Introvert was the very first game I made).
I do acknowledge that this game does indeed have a few flaws, mostly with balancing and sadly I don’t really have the knowledge to solve these issues at this point in time. It is times like these where I really wish I had a team to work with, because it would mean being able to create better games of higher quality. But teams don’t grow on trees nor do they fall from the sky. It has been very fun though getting first hand experience at all aspects of game development, and a great experience nevertheless.
Only 24 hours a day
I guess the other problem of not having a team is that you got to do everything yourself. There’s the issue of time – I work about 14 hours a day at full speed. But even still, there is only so much stuff I can do in a day, and I believe a lot of people would wish days last longer.
I’m not even sure if developing games can be a hobby (more on that later). Developing quality games is not a very good hobby to have and I mean that in the most positive way. A hobby like drawing is something much more reasonable comparatively. When you want to make ‘developing quality games’ as a hobby, it means you are drawing, coding, designing, sounds-ing and handling overall production at once. That’s like multi-tasking 5 hobbies in one.
Assuming in the future I work a regular 9am to 5pm job and each day has 24 hours.
8 Hours is lost to sleep.
8 Hours is spent working.
1-2 Hours is likely spent on transportation to and fro from work.
1-2 Hours is spent on miscellaneous self-maintenance tasks like bathing, eating and leisure activities like watching TV or Star Wars videos. Yes, I call this self-maintenance because these are essential for survival – including leisure. I could work on my game all day but I always spend time doing miscellaneous tasks to rejuvenate myself. Writing on my blog, reading Quora, watching funny videos people share on social media, re-watching The Star Wars Force Awakens trailer, you know – the typical breaks that most average humans need.
Deduct all those hours and you have about 4-6 hours leftover for your hobby. And that’s the maximum time. Working overtime, social gatherings, family outings, miscellaneous commitments are other important essential events that are going to lessen the ‘free time/hobby time’ you have.
During National Service, I was able to keep it up somehow. It was a miracle. Though I took long breaks from game developing, I always returned to it somehow. Even as I stayed in camp on weekend duty, I would sketch out game designs and ideas in the bunk. I guess even from camp, my projects were always calling out to me.
So at the end of the day, and most likely, once I start working, developing games is a very challenging hobby. I wish it could be easier, but at this point in time and with current technology, making a game takes tremendous effort and plenty of commitment and rightfully so because if that weren’t the case, the standard of games would drop.
When games became more easier to make with the introduction of Flash years ago and commercial game engines like Unity in recent years, many games have sprung up. At the same time, a lot of people seem to be monetizing simple games. I see games on STEAM selling for $10 despite having lesser quality than some Flash Games I played years ago.
My personal thoughts / Reflection
I’m probably finished talking about the game and there are no more pictures below. So if you came for the pics, you can quit reading now. Instead of talking more about my progress on the game, I am going to write about what I have experienced in the past few weeks and really just let out some of the things I feel and reflect on when I was making this game.
First off, a question that I think I get most from people close to me (or not): How long does it take me to make a game and when am I going to publish this game?
To make a good game, I would actually need at least 6 months. If you reacted negatively to that statement, either by thinking “that’s long” or “you’re lousy”, then you’re probably one of those people who (hopefully I’m not insulting anyone) don’t really know what it takes to create a game, or a quality game for that matter. If you’ve made a quality game by yourself, then you would be better qualified to judge other developers and, I’d also salute you because making a quality game takes lots of effort and skill and probably experience as well. And this isn’t limited to just games – if you want to make something good, either if you are a fellow app developer, an engineer trying to create a product, it’s going to take time.
I think when people see me making a game (or at least it happens to me), they expect that I’m going to finish and publish it in a month, which may not sound crazy if you’re making a simple ‘Roll a Ball’ game with only one level.
But the truth is that to make a game with depth, balancing, has sufficient content and looks good with sound effects and music… that is going to take awhile. You don’t just say you want to make a game in one month and go”I’m going to design the levels for 1 week, code for 1 week, then draw+animate the characters and backgrounds for 1 week, then finish up the optimization,sounds,polishing,balancing in the last week.” Again, depending on the scale of the game you are making, that can be incredibly feasible, but not for most games. Not one for the scale I’m making anyway and definitely not with the manpower I have: one.
I guess unless you are a fellow developer yourself, it’s easy to underestimate the effort and time it takes to make something. If my game does get published, things like the camera zooming, honing onto a target, the special effects on boss maps, the little spawn animations of the epic bosses, the story panels, tiny popup animations/fading effects… they’re all going to be overlooked by people. Things that took 10 hours to make will only appear on screen for 10 seconds and it doesn’t matter to me. As long as it makes the game fun to look at and enjoyable to play, I really don’t mind working 10 hours on the little things. And if you have read the entire of this post up till this point, you would have realized by now that a lot of time and effort goes into things you don’t see on the screen. Precious development time and effort are spent on many things behind the scenes, things you don’t always see and take for granted, like: optimization to make playing more smooth, size reductions so you don’t wait forever to play the game and balancing.
In the scale of time, 6 months to make a game is not very long, but neither is it very short. 6 months is half a year. For the record, I spent 2.5 years developing Introvert, a lot of that time apparently was from when I was serving National Service and working on other games too. At a rate of 1 game every 6 months, it means that working alone at a 14 hours a day, I make two games every year, which is actually really pathetic, and looking at the number of games out there, it’s easy to assume that making a game is meant to be fast, simple, easy process, and it probably is to an experienced developer or a team of people, or a company. But I’m no company or group of people. I’m just a one man team, a guy trying to make a game that people would want to play.
I saw this ‘Make a game in 10 days’ competition and I would have joined if I were not involved in my own project already. I took the time to see some of the games made by participants. There was one game I spent a good 20 minutes on, and that’s astonishing. It really amazes me what people can do in 10 days and truly inspiring to look at. If I still have time after my game is done with development, I will embark on making smaller games. But chances are studies would take over by then and time will probably become my greatest enemy.
The truth is that as a game gets bigger and has more stuff, without a team it just gets exponentially longer and harder to make. In smaller games a lot of things can be taken out or minimized – there isn’t as much need for insane balancing, or progression, and file sizes become less of a burden. Some of these can be offset by experience though.
It’s like a snowball effect when you make a big game – each new feature multiplies the development time, not just flatly adds it and if you don’t exercise self control, things are going to get out of hand very quickly. You got to be careful about the decisions you make. Speaking of which…
When making a game, (or anything really) you got to make your own decisions for the betterment of the game (or the thing that you create) and it can be something very hard to do. While I get to call the shots in everything from the art to the design, and especially design, I also want input from other people. I’d in fact be very happy to hear what other people feel or think, which is crucial during the design and development phase. The closer the game is to completion, the harder it is to change and modify core mechanics without throwing off the balancing on a huge scale.
But there’s a greater decision that I have to make – my future.
I went to take a look at two university courses at an Open House today. There was one talk I sat for by this particular speaker. I expected it to be some standard pep-talk, but this speaker was fantastic. Not once during the talk did I feel bored at all. I sat there listening intently. He spoke really well and presented himself excellently, probably the result of year after year of speaking to students and parents. It was unlike any of the previous University talks I had been to. But after the talk, it was time to actually look for the right course for me – what should I study?
After a few talks with a few people, the question quickly turned from “what should I study?” to “what is my goal?”
Apparently, the job I am looking for doesn’t exist. Or to be clearer, it doesn’t classify as a real working, stable job. And it makes sense. The job I was looking for is too ‘perfect’. I was really very sad. I didn’t make this Tower Defense game -or any of my previous games- for money and there always will be at least a few people going to tell me that it’s an unusual way of doing things.
Nevertheless, life presents a lot of options to each of us, and I guess that was what I was meant to realise. Yet out of the many options we have in life it is often difficult to find the best one. And having eliminated one of the best options I was looking forward to, there’s not much motivation for me to study actually, but I guess that remains to be seen.
So what’s left to do? A lot it seems. But getting the game size down is really a huge load off my chest. The game went from an (impossible to publish) 80+MB to a (reasonably acceptable) size of 30MB.
Still far from actually publishing it though, and with life commitments starting to kick in, it will take even longer to finish the game and publish it.
At this stage, the game is getting quite technical. I am working on getting the final game size down, compressing my sounds, decreasing scene load times, and grinding down the technical issues – most of which are stuff that programmers would love to do to get their hands dirty, but well being an artist, this stuff totally bores me. But someone has to do it!
But let’s talk about the fun stuff first.
Drawing new Maps
As the game starts to draw to an end, I am finishing up on the map drawings. I have only about 5 more maps to draw before I can wrap up the background art.
A lot of the work remaining now leans more to the technical aspect more than the art.
I’ve also added more complex movement animations to my previous boss.
As the game grows, I started to get sorting problems – as more objects are introduced to the game, their distance to the camera has to be sorted properly. (e.g. Turrets have to be behind the enemies, enemies have to be behind the environment trees but above the map background)
Because I had so many objects, and each object can have its individual sorting layer (e.g. The enemy has a background sprite, then it has its health bar sprite, and a health bar background sprite), and turrets have its main sprite, its equipment (The hero has a hat that is on top of the main character sprite), other UI icons like a star, a disable icon, it got pretty messy. Then there are some enemies that can fly (planes), so they have to be ordered to the top most layer – above trees that would normally ‘cover’ the pathway and other ground enemies.
Because my game is 2D, I make use of the 3rd Axis to determine the ‘draw order’. The Z-axis determines whether an object is in front or behind objects in my 2D but 3D space.
Z = 0 represents the center of the worldspace.
Z = 1 represents something further from the camera (will be obscured by objects at Z = 0)
Z = -1 represents something closer to the camera (aka higher up on the draw order)
To allow my game to expand without having sorting layer issues, I documented all the objects in my game that had their z-axis values adjusted. So when I add a new object, I know exactly what its Z-value should be.
In Unity, there is even an ‘ORDER IN LAYER’ property, which sort of is like an override – no matter what your Z-coordinate is, an object with higher ORDER IN LAYER will automatically be drawn on top of something with lower Order In Layer. This can be changed in code too, so it allows me to do some bizarre things, like my oak tree special boss. Now here comes the exciting part:
(Superbosses are officially called Epic Bosses in the game)
I was making a new boss and I kinda wish I took a real-time video of me drawing this superboss – I had a lot of fun drawing this boss and it is currently one of the largest and most complex enemy I’ve ever drawn for the game.
Like my other superbosses, this one has a lot of unique features and abilities. I don’t call regular bosses superbosses for a reason. When I call something a superboss, it usually means it can do something really cool, like my previous superboss who could do this:
This boss is part of the background at first. His eyes are hidden so hopefully the player thinks “hey, that’s just part of the environment”, but when he comes alive (and hopefully the player will be surprised by that), he spawns additional animated sprites. I had to be careful of the sorting. (Think of it like a human and his body parts – the eyes have to be rendered on top of the face, and branches have to be rendered BEHIND the body) – and to achieve the correct sorting order, I actually set in code the body part’s “Order in Layer” property so that a sprite within a sprite knows how to order itself relative to the main object. Hopefully that didn’t sound too confusing.
It lags badly in Photoshop because the map texture is 3200 x 2400 and I have a lot of tree groups.
Anyway, I wanted to make an animation such that tree branches grow out of the superboss.
I used Onion Skinning to animate the growing branch. I first drew the full branch then ‘erased’ parts of it for the different frames. (You can see the different transparency layers above. Each transparency layer represents one frame of the animation).
This was a rather simple animation with only 5 frames. I know some people may think I should make more frames to make the animation smoother (and I really want to!), but having a large spritesheet for an almost insignificant part of a minor boss wouldn’t be worth it (my game is over the 50MB limit and spritesheets use up A LOT of space). So when making my animations, I have to take game size into consideration. (More about game size below)
Also, I accidentally imported the wrong size of the Oak Tree into the game, causing him to be doubled his actual size, which makes him look even COOLER:
I was considering to make the bigger version his actual size. I mean, just look at the size of the other trees and creeps compared to that monster! But well, sadly I can’t do that. Apart from the glaring issues like having a superthick outline and the level of detail being somewhat lacking for something that huge, it’s simply overkill. The final boss isn’t even that big, and this isn’t the final boss. He is technically the second last superboss in the sequence of superboss appearances in the game.
But this tree doesn’t need to be big to be special.
The Oak Tree Boss is the first enemy in my game to actually have ‘body parts’. Its eyes are animated and saved as a separate spritesheet from the body, both to save memory and space because the body does not move. I used some tricks to actually make this happen. (When he spawns, you can only attack his eyes).
This Oak Tree Boss was not part of the original game scope, but I thought it would be cool to have a boss that is different from other bosses (having multiple body parts), and this is also the first ‘plant’ boss – it’s not creep or animal! It is also the first enemy that cannot move. But it can still threaten you with its summons.
After spending half a day drawing, it was time for the excitement (and frustration) of coding the actual boss. Surprisingly, it went pretty smooth. There were still a few bugs with the initial run and they were all caused by oversight and were easily identified and fixed:
The boss’ arms did not appear at first – because I forgot to set their references in the inspector
The boss’ eyes were rotated (see the screenshot) because the boss is trying to rotate to its next waypoint
Lastly, every creep that spawned was a boss, because this wave is a ‘boss wave’. This was unintended.
Boss’s tree branches were blocked by turrets (I only set the ordering for the main body, but forgot about its body parts, so its body parts were still mapped to the background and covered by turrets)
It took awhile to actually test out the boss, and to make sure that everything was working. Once that was done, I added some special effects and automated camera movement / zooming that trigger when the boss spawns.
And finally, SUCCESS!
The camera effects start once you call the last wave. And there is a brief delay before the boss actually spawns (when the green Health bar above his eyes appears, that’s when he actually spawns).
While this whole idea of an oak tree boss was really cool, I should really stop sidetracking since every day I spend working on stuff like that is a day later the game will be ready to play and publish. It’s pretty hard, sometimes I just get so passionate or fixated about certain things and I can’t stop myself! But there is only so much I can do in a certain time-frame and my ‘holiday’ is not infinite in duration, so sadly, I do have to get strict with myself in what I choose to develop.
I have thrown away a few cool ideas and maps, trying to combine them or just eliminate them altogether from my game scope, partly due to the pressure of trying to compact the final game size to under 50MB (more on that later). Weeks ago, when the game was in its early stages, one person implied to me that I was ‘JUST’ making a game that looks like every other TD out there. I was a little offended by the remark. Many people seem to think a game has to be different or special or else there’s no point making it. But I feel that’s not true. Then again, it kind of depends on what you mean by ‘different’ – gameplay wise? Graphics wise? If you just want to exactly replicate/make a clone of another game, then that does sound pretty pointless. But some games try too much to be different and end up with a very bad design that can put players off rather than attract players – I guess it depends on what is ‘different’. Angry Birds was a copy of Crush the Castle. But it received more attention and became a sensation because it was similar yet different. At its core, they are the same, but their presentation (cartoony graphics) and execution was what made them different. Games are pretty magical. You never know if a game design will succeed – you can’t “predict” accurately whether your game idea attracts or repels players – you’d need a lot of Beta testers and a very wide target audience is hard to please. You can’t please everyone.
Ops, sorry I ranted too long about my thoughts. It’s just that while making this game or any of my games in general, I tend to think a lot about this kind of things. There’s a lot of things involved in making a game behind the scenes, beyond the graphics, beyond the code. It’s the stuff that people don’t always see. People think that making a game is all about- oh crap, am I ranting again? Anyway, back to development.
Beware! BigFoot – the next boss? I’m not going to make anything complex anymore though. Takes too much time.
Okay well, I added a new status effect called ‘Stun’. Status effects are negative debuffs you can inflict on creeps. So far, 3 status effects exist in the game. They are ‘Slow’, ‘Burn’ and the newly added ‘stun’. I drew a simple stun circle that appears when you stun a creep.
Then I decided to add a behaviour to the stunned creep. But what animation should I give it?
A) Just freeze the creep at its current animation frame so it does not move
B) Have the creep continue playing its current animation, but loop it rotating 360 degrees so it looks like it is dazed
For some weird reason, I went with Option (B), since I was curious how that would look like. So while experimenting, I decided to make the monsters turn while they are stunned. And the result was pretty hilarious.
The creeps look like they are dancing around on the spot.
The crazy thing is I actually want to call my new status effect ‘hypnotize’ instead of ‘stun’. Not only is stun pretty overused in games, but call me weird, I actually like this animation. I’m not sure though. Hypnotizing creeps sounds way more interesting, but it doesn’t fit well in my game since the turrets are mechanical, so it doesn’t make sense for a turret to be able to ‘hypnotize’ the creep. So for now, I’m sticking with stun.
In the meantime, I had a mock description for the stun – “Hypnotize creeps at a chance, causing them to stop attacking and break out in a dance.” It’s not meant to be a serious description but something more light-hearted. Dancing creeps are better off as an easter egg. (The rotating stun circle around the creep does make it look like the creep is conducting some sort of dance ritual…)
The Ultimate Level?
I spent about a full day on balancing ‘advanced’ skills, which I added in the previous week. I also had to balance many of the new special Challenge maps I added.
But most of all, I got to finally test and win against Map 20. It was previously too tough, but after the changes, I managed to win on the first try. It was almost too easy – the final boss barely made it halfway through.
Also, notice that I added a new ‘Tip’ dialogue at the bottom. The tip generated will change if you lose a battle. If you lost on a wave of Knights, it displays a tip on how to defeat Knights – it’s pretty dynamic and I realized I needed this because the game is pretty challenging. I replayed my earlier levels from scratch and while doing so, ignored strategy which resulted in me losing twice at Level 4 !!!
I was trying to brute force it by just spamming damage turrets but it did not work because you can’t just spam one tower and hope to win in early-game. I hope this doesn’t make the game too tough. I noticed (sadly) that many people prefer a casual, easy game, one that offers little challenge or just allows you to grind and win levels. Some TDs I played make you replay levels again and again to get EXP and get stronger to win a level. It’s brainless and requires no strategy – all you need is time and endurance to repeat the same level over and over, get your character to Level 100 and suddenly everything is easy.
In my game, you can’t grind to a high level and breeze through levels. So you got to think of how to beat a level, not just grind your way to the top and take the strategy out of it.
Because of that concept, I had to mark levels with a ‘Recommended Level’ tag so people at least know what level they should be before attempting it. It was very accurate at the beginning, but as you progress, there are more factors which makes recommended levels inaccurate – a player can get bonus SP if they get highscores, their skill setups change, and completing Challenges will also increase your damage without increasing your level. These variables I guess are the reasons why games don’t generally put a ‘recommended level’.
It also requires a lot of manual testing on my part to find the appropriate level needed to attempt the map.
I’ve also explored deep profiling, a tool which I can use to monitor the game’s frame rate and CPU usage and draw calls. I haven’t exactly used this much since the game seems to run pretty smoothly so far, save for a few lag spikes.
Since my primary intention is to publish this game to web portals, I intend to build my game on the Web Player platform. I *may* publish it to mobile, but for the moment it is not a priority. Even on the Web Player, there are a few technical issues that I have to resolve – one of which is game size.
Game Size refers to the final size of your playable game – the bigger it is, the longer it takes to load it and you potentially lose players. Web portals also do not accept games that are too big. My game currently sits at 60-70MB (with music and 1600×1200 target resolution). I can probably squeeze it to under 50MB with a target resolution of 800 x 600.
But before talking about Game Size, I actually flashed back to when I was still in Polytechnic, back in 2012.
I remember back in school, our final year project was to make a game. For the most part, I found it pretty fun. I looked forward to it and was really excited. It was the first time we were actually making a game in a team. But we were not taught the importance of keeping the size of a game low. Heck, we weren’t taught a lot of things – it was only when I started developing my own games did I realize there were a lot of things school did not teach us. I ended up having to learn a lot of things by myself, a lot of times the hard way.
I think our final year project submission was likely over 100MB, and for comparison, sites like Kongregate only allow uploads of up to 50MB. Our final project game was made by 5 people over a span of 16 weeks. But the game wasn’t 100MB because it was a ‘big’ game.
To be honest, (and I’m really not trying to brag), but I actually think the scale of this tower defense game is currently about the scale of our final project – what I’m trying to say is that the 100MB wasn’t the result of the game we made being more complex or actually having more content, it’s due to us not being taught that bigger = bad. I think ironically some of us even felt that a bigger game = better, because it means more potential marks because it has more stuff in it?
I guess I was just so disappointed that a lot of things I learned in school did not really apply to the industry or were irrelevant to actual game development. Though it is possible that I’m just not skilled enough to see the connections. Hopefully, and this is if I decide to pursue game development in University, things will be different.
Game Size (Technical)
From here on, my programmer will talk about the technical side of game development. My programmer is pretty weak, so forgive him.
—*Puts on programmer’s hat*—
When I finally got to build(compile) my game to web player after multiple attempts at reducing the file size, experimentation, researching, I was shocked to learn a few things.
Removing four music tracks from my game shaved off roughly 20MB off my file size, dropping it from 57MB to 36MB.
There were actually two things to look at when looking at game size – uncompressed size and compressed size. Unity gives me a list of assets and sorts them by their uncompressed size when I build my game.
The problem I later realized is that this does not accurately reflect the size of the final game. For example, sounds are listed as 0.0% in the Log above. But this sorts by uncompressed assets. It was very fishy because my music tracks were pretty big. In the end I removed music to compare the size difference and going from 50MB to 30MB showed that sounds was definitely bigger than “0.0%” of my game.
And plugging in the size data of my assets revealed another shocking piece of information.
Going from left to right in the bar chart:
Background– contains about 30+ 800 by 600px map backgrounds and environment props
Bug– My creep spritesheets. Bug was the ‘codename’ for creeps from an earlier build
InfoPanel– Tutorial panels, but mostly story panels, sort of like comics in a sense that they tell a story in picture form
Bullets – Self-explanatory. They also contain AoE effects.
Turrets– Spritesheets of all 12 turrets in my game, buildings, as well as the Hero character’s idle/attack animation sprites
Misc– Misc mostly contains UI elements – buttons, skill icons. The tutorials take up a lot of space. Thankfully there aren’t a lot of them.
After manually compressing my backgrounds to 25% of the original sizes, they were now so small they were even SMALLER than the turret graphics! And I was amazed that 11 turrets actually consumed more space than 20+ Creeps, but well, the turrets are drawn in pretty high-res and they do have a lot more detail and their animations more complex leading to bigger spritesheet sizes.
As for bullets taking up so much space, I was puzzled at first, but realized the three biggest bullet sprites are larger than most creeps, because they are AoE effects, not bullets, but I put them into bullets because they function similarly to bullets. I might trim the AoE effect sprites but there are other stuff to trim first.
And shockingly, about 1.5MB of my Miscellaneous assets is from my oversized placeholder HD game logo, which is to be removed from the final build just before publishing.
Before I decided to compress my backgrounds, I actually heard of something called Asset Bundling from my (expert programmer) friend.
As time passes, I have to prepare for when the game gets published. There were 3 problems:
Scene Loading Time
The uncompressed game size sits at 300MB. I used the Editor Log to determine what was causing the size and thankfully managed to find the cause.
The map art assets were a huge contributing factor. I decided to try and learn something called the Asset Bundle to actually load my graphics during runtime, something I have never done before, and it is pretty advanced to me, in the sense that Unity categorized it as ‘Advanced Development’:
Unity probably labelled it ‘advanced’ because it is used mostly by bigger games that get more complex and have larger output sizes.
What the Asset Bundle does is instead of putting the art in the game itself, I load the map graphic from a server via code, only when it is needed.
This keeps the game’s loading time to a minimum – it only loads what is needed. So far in my asset bundle, I have just my backgrounds because they are the largest textures I use.
Asset Bundles (Technical)
(Warning: I found this to be a bit technical. Skip this section if you don’t want to read about the technical aspect of developing games)
After an entire night, sadly my efforts of trying asset bundling were in vain. The amazing thing is I actually got asset bundle to work partially – somewhat, and it was a pretty big achievement for me to actually understand something I considered to be pretty technical – it’s something programmers would probably love doing, but I ain’t got much love for programming so it was literal torture every step of the way.
The thing that stopped it from working was that I needed an actual web hosting site and a domain containing a crossdomain.xml file that allows other domains to retrieve files from it because of a security feature that Unity, (as well as Silverlight and Flash) had. Well, sadly I realized at this point that this was getting way too complex. One problem was leading to another and though I managed to solve the ones I faced so far, this one was beyond me.
I did actually attempt to use a few web hosting sites. The first one I used was 000webhosting. But it had a limit of 5MB per file, which is around the size of 3 of my map graphics (compressed). This defeats the point of using asset bundles if I cannot upload large files. I could use the hack solution of uploading 3 maps per bundle, but then I would need 10 bundles if my game has 30 maps. Totally uncool.
Then there was Filezilla. I spent a lot of time reading up on it and learning about something called FTP (File Transfer Protocol) but it was for naught once again because Unity requires a browser URL to load the asset from the server. Filezilla only gives you the FTP url, which is not the browser URL because Filezilla does not support HTML urls. I was really sad.
I actually tried a few more – Lokad, Load.To, DataFileHost. They were decent but each one lacked what the other had. But my most interesting encounter was with JumboFiles. It boasted 500GB of free space,and more importantly, FTP support which was what I was looking for.
I registed for an account, and guess what? Yep, the servers were down. I could create empty folders, but I could not upload anything. They boasted about having 70,000 users, but to me hat’s just biting off more than you can chew. Not to mention, I had the ‘luck’ of witnessing a DDOS attack happening on 000webhosting‘s server, the first web hosting service I used earlier.
After today’s experience, I really learned to appreciate Dropbox a lot more. Paying $99 for reliability, automated project syncing and limitless file size and customization is reasonable. It’s just too bad it lacks the support I need or I would definitely use it to host my game’s assets. I may give up using Asset Bundles since I am building my game to WebPlayer, which compresses all my textures – my final game size sits at 57MB now, which is slightly above the 50MB limit and is expected to grow, thus the need for Asset Bundles, which would push my game below the 50MB size limit and to make for reasonable download times.
I was extremely frustrated at the end, not because of the quality of the sites I found, but because I didn’t understand a lot of things about crossdomain, xmls and the restrictions of web player. Fortunately I had a lot of brainstorms going on on how to reduce my build size without the need of Asset Bundling.
After compressing my maps once in PSD and prior to Unity’s auto compression, I decided to make my entire map a spritesheet, which is something I didn’t do yet because it was not a high priority.
A hard limit of 4096 x 4096 texture size means I can squeeze in 6 x 7 map backgrounds. That equals to 42 maps!
It turns out it DID actually save some space, but it amounted to less than 1MB. It was too insignificant. I was hoping for greater size drops for the effort it took (not much actually). Maybe I could try Texture Atlases.
I do not understand much about Texture Atlases at this point. People say they are similar to spritesheets, but apparently not exactly the same. I can’t seem to get an answer on how much space it is estimated to save – it’s probably too dependent on the project.
—*Takes off programmer’s hat and lies on the floor in exhaustion*—
Behind the ‘Behind the Scenes’
I actually try to keep each post as short as possible – lesser words if possible because I don’t want to bore people, but sometimes I can’t help it. I kind of realized I love writing (or typing in this case). Just simply talking about the process and the things I love to do makes me happy because I really love drawing and animating and making a game is just a very magical process for me. As for programming, as long as it does not involve technical stuff, I truly enjoy it. Coding creeps and bringing them to life in my game is like sugar rush, and when I work on Superbosses? That’s like feeding me heroin, not that I take drugs. Why would I when I already get super excited from making a game? Making this game has given me more fun than most games I’ve played.
To be able to write about ‘Behind the Scenes/The Making Of’ this game is really enjoyable. At this stage, this game is a summary of 8 weeks of hardcore drawing, balancing, sounds, coding, animations and miscellaneous technical stuff.
So far, I am happy with the art and I’m content with the features. I guess my favourite thing in this game is the upgrade system, the maps and the bosses. Especially the superbosses. The only thing I’m worried about is currently the game’s design and balance – I’m not sure if players will find the difficulty okay and I am also unsure how fun people will find this game. As the game progresses, I personally found it to get less exciting because I no longer unlock new stuff. Well, I guess I’ll have to see how this game turns out.
This is Part 6 of my ongoing journey in the making of this TD game. It is currently Week 6 since the start of this game’s development on 21 Nov.
The game is actually ready to play…sort of. I got balancing done (and this is the most tedious part) for the first 20 maps on the Normal difficulty and partially Hard Difficulty. For the record, I intend for this game to have 25-30 Campaign maps and 15-20 Challenge maps. I have yet to balance the Nightmare difficulty. Currently, it is impossible to attempt it, but with a few more features in place perhaps it will be possible.
But let’s start with what has been done for the past week. I’ll start with something really exciting.
I managed to add a few more epic bosses (not drawn to scale). The first one is the Terminator, and the second is currently the most interesting epic boss:
I talked about using summoning runes as a story element in the previous post – they are objects on the map that can spawn monsters. And the epic boss I just drew can turn himself into a summoning rune! And when he does, he starts spawning monsters!!!
This was a very VERY tricky thing to do. To achieve this effect, I had to make use of almost everything I had coded so far – my spawn script, my rune script, my summoning rune animation, and this is the first enemy in the game to require an animation ‘controller’ to handle my different animation states and to also trigger the spawning at the correct frames.
Here’s a frame by frame animation I drew:
Also, a bit of deception – there isn’t actually a summoning rune on the map when the animation occurs. I actually wanted to make it such that when the animation is complete, the boss is set to invisible, then I set a summoning rune to the boss’ location, and enable the rune for 20 seconds because my summoning rune has an automated script to spawn monsters. In the end though, I decided to go with the boss = rune approach. This had pros and cons.
To date, all my enemies only need a single walk animation. But this beast has 3 animations:
Transform into summoning rune
Transform back to normal (reverse of animationClip #2)
There was one con to my approach of making the rune and the boss the same thing – During spawning, the enemy will also stop moving and the tricky thing is, this epic boss flies – which means in his moving state, he has to be on top of all the ground monsters. BUT, when he is in a summoning state, he has to be BELOW the other monsters.
Again this required some manual work by shifting the boss along the z-axis during the animation transitioning. I also modified my move script to make the boss stop all movement when he is summoning stuff.
Ultimately everything worked and the insane amount of effort was worth it when I played out my battle against this beast.
The boss is actually in the top left corner. You can’t really see him since I took the screenshot at a bad frame – he camouflages with the mobs underneath him. But the fight was very epic.
Sadly, I lost at my own game. I ended up having -17 lives too. Wait-what? That’s a bug. I NEED TO FIX IT NOW!!!!
I think this is the most time-consuming epic boss I have made. The map also lives up to its reputation. It has a gigantic rune in the middle and this rune too has some special effects up its sleeves every 7 waves. It also has its own animations! (If you want to read up about what runes are in my game, it is mentioned briefly in Part 5, my previous post)
I seriously cannot wait to let people try out this map! I used to say that Map #10 looked like the final level because it had 2 special effects.
Then I made Map #15 and it had 3 special effects!
This is currently Map #20. And now that I’ve made my third epic map, I can say that Map #20 is totally badass.
I put a lot of effort into each of my maps and my creeps – and it’s not just the special effects, but right down to each of the creep’s individual animations, and I really hope some people who play my game will notice that because the creeps in the game are actually really small.
I have a few new creeps, some of them are for my Challenge maps. I’ve drawn golems, elementals, and upgraded versions of current creeps.
But there is one creep which is particularly interesting because it is the first monster that is able to debuff your turrets:
Not related to enemies directly, but I added a neat visual display to show a red arrow on turrets that are debuffed and a green arrow on turrets that are being buffed.
I finished up the drawing my last second turret, The Arc. Unlike normal turrets, this turret occupies a gridspace of 2 x 2 grids. I may be changing this turret’s graphic in the final game if I have time for something better-looking.
The reason why I wasn’t quite satisfied with the final result is simple. You can actually tell that when I was drawing the turret above, I was confined to a tiny gridspace in the shape of a square. However, upon getting inspired and actually letting myself draw without limitations against an actual full map background, I was able to draw a few drafts of what I actually envisioned as the ‘ultimate turret’.
I for one, would like to see an epic turret capable of shooting swords to impale my enemies!
More special maps
One of the things I really enjoy is drawing maps. I try to make maps as cool and awesome-looking. There’s an ice map, a fire map, a boss-only map. I really stepped up on the map environment variations since my last post on drawing Maps.
There are also variations in the environment props – like the trees/skulls/flowers/cracks/ponds that litter the map.
My latest map, Map #26 features a special Oak Tree on it. The enemy can actually pass through it and go underneath it. A simple but pretty cool effect that stands out from my normal props which usually serve as decoration and lack any sort of enemy interaction.
There are even more interactable objects on maps – like the Hadron Pulsar I mentioned briefly in my previous post, which is an ‘environment prop’ that you can repair, turning it into a turret!
I also added other unique click-able / interactable objects, thanks to my Building script I coded last week. The cool thing about the script is that it can be applied to any environmental object to make it click-able. But I don’t do it often – it’s sparsely used to preserve the uniqueness of clickable objects and also I don’t want to flood the game with junk by littering every map with these.
The map above has a skull entrance, which is set to be on top of everything else. I also drew glyphs (the white glowing characters) leading up to it.
I also have a treasure map level. This is a side-quest, more of a side-story that is optional to venture on. But if you accept the challenge, you will get a very nice reward and unlock a hidden storyline.
Loading Screen when loading maps
I spent about half a day implementing this. It was a bit technical for someone of my caliber, but I did it. I’ve displayed “loading…” popups before in IdleHeroes, but it doesn’t tell you the current loading progress.
This time, I decided to go advanced. I used an AsyncOperation to get the current loading progress and created a loading scene. As the game loads, a few things happen:
The bar fills up left to right, and color leaps from red to green
The creep will walk from left to right
The background will light up (to 100% brightness at 100% progress)
The loading scene was actually unnecessary since the levels are loaded within half a second. It was so fast I had to go frame by frame to capture the two screenshots above. That’s right, the loading took 2 frames – out of 30 frames a second.
I guess the loading screen would help for those with slower computers so there’s at least feedback to say that the game has not hung, just loading. As the game gets bigger, loading times *might* increase in the future as well.
The tutorial picture above says everything.
These are powerful skill upgrades rewarded by my Challenge feature. For many weeks the Challenge feature gave no rewards. The reason being I wanted challenges to give something special – not plain EXP or skill points, but extremely powerful stuff that you can’t get by playing the game normally – thus ‘Challenges’.
The maps of Challenges are uniquely designed to have special elements in them and special spawns. I’ve drawn unique enemies that don’t appear in the campaign mode, but appear in challenges. I sometimes think that the Challenge maps are far more interesting than campaign levels because I actually make Challenges when I have inspiration, and inspiration is a really powerful thing.
I guess the one good thing about being an independent game developer working solo is that I get to express my creativity a lot as I don’t have many restrictions. I get to inspire myself as I work and it really helps me to make better games!
More Story panels
As the campaign levels are being built, I am also developing the story in accordance to my story script which I drafted out weeks ago.
So far I like the story and enjoy drawing the story panels a lot. Sure, they take up a lot of time for something that is only on-screen for 2-3 seconds, but visuals really tell the story.
Here are some story panels (in no particular order or sequence):
As I was drawing, I had some flashbacks to when I was drawing cutscenes for ‘Introvert’. Despite being my very first game, it had many cool cutscenes that I wish I could show to people I know.
I really enjoyed working on that game a lot, especially since it is a story-driven game and rather personal. I hope to someday release it to the public. Perhaps after I am done with this TD?
For about 6 weeks, my game had been mute. No audio or music, till now.
I have begun adding the official sound effects in my game. I don’t have the money to hire a studio this time (though I might do it for the learning experience?), so I source for royalty free sounds. A lot of times when sourcing for suitable sounds, I don’t really get to find what I want exactly, so I take the closest one I can find and modify it (using Audacity).
But, there are moments when I do manage to find the exact sound I want, and I get really happy! It’s like the sound effect matches exactly what I envision my turret / object would sound like!
My original intention was to use one standard death sound for all my 20+ creep types, but I learnt something from this experience of adding sounds to my game.
Sounds are just as important as music – sounds can add personality to the creep. A creep that has a human-y voice will appear more human-ish. It makes it give the vibe that it is kind, innocent, sound compassionate and almost makes you feel bad for killing it.
A creep that lets out a fantasy death sound removes the human element of it. It’s good for a non-human creature.
On the other hand, lowering the pitch or making the voice deeper makes it more ferocious. I gave this to the more evil-looking creep variations. I actually took a human-ish ‘OUCH’ sound used for a Standard Creep and modified it for one of the Corrupted creep, because the Corrupted Creep is basically a more evil-looking Standard Creep, so the sounds it makes should not be too different from a standard creep.
And finally, the sounds I used for the death of an epic boss is a very deep and long chilling death howl – to give a sense of satisfaction and to tell you that you just killed something really, really powerful, and you should feel good.
As I am sourcing for sounds, I also get a lot of inspiration. Sometimes, I hear cool sound effects that really inspire me to put them into the game and I also manage to find sounds that may not be what I am looking for, but I realize that it would be great for something else – like for a side feature or accompanying a mute animation – I go “Hey, this sounds interesting. Not what I’m looking for but it fits the ‘XXX’ really well”.
Sometimes, I also get the feeling of reverse Deja Vu – I find a sound that I know will be useful sometime in the future, so I save it anyway, just in case.
Unity gives me a lot of control over the audio I use with something called Audio Mixers. It allows me to group audio together, and I can control each group’s audio individually, or globally.
Previously, I used two audio mixers – one for BGM and one for sounds. But I combined both and instead used groups to separate them. Master, Music and Sound. Changing the Master volume changes the volume of every audio clip.
I have also updated my options with sliders for more flexible volume control – previously you could only mute/unmute every single soundtrack and I had no control over music vs sounds.
My options screen got bigger when there were more things in my game to customize – shake screen effects, camera movement were options added over time and I believe there will be more to come.
Also, a look at my taskbar:
Yep, just another average day in game development. Thank god I have three monitors and a supercomputer.
Every day, I am making new stuff – I code new features, I draw new art. I don’t think there ever has been a full day where I’ve never drawn a single art asset or did not have a new line of code in my game. Every day, just so much is being done. And this really makes me happy, to just do what I love and to learn at the same time. I open and close dozens of tabs every day, browsing stackoverflow, forums and googling for art inspiration. I’m going to bet there hasn’t been a day where I did not learn something new.
It is such an amazing and magicalexperience to be making a game and to be part of this entire process.
Oh, I also went back to school today (the Polytechnic which I graduated from 3 years ago). I still don’t know what I want to do with my life.
Going back to school was quite a nostalgic trip and prior to today, I had written a full essay on my adventures in Polytechnic, the ups and downs I have been through in those 3 years and how I was first inspired to create games. I should post that here someday… I think it might be something exciting and maybe surprising(?) to read.
I think next to developing games and drawing, writing is my second hobby. It’s probably the reason I started this blog, so I can talk about the things I love and maybe even inspire someone out there.
This is part 5 of my journey in making a Tower Defense game. It is also 2 Jan, the second day of 2016 at the time of this post, so Happy New Year!
I added special turrets and structures to the game. I put a lot of time into the thought process behind the coding and design and managed to extend my turret class to house a new type of structure – Buildings.
Most of them don’t shoot at enemies, and those that don’t give some kind of bonus.
With this script, I can create different types of structures that do very unique things.
I can also convert any ‘building’ to a turret as well with my build() script.
The structures you see sitting out in the sea are oil rigs – they generate additional gold income at the end of each wave.
I have also coded runes. Runes are a different kind of ‘structure’ that you can build on top of. Unlike buildings, they don’t occupy a grid slot and have a very unique effect. They boost the damage of a turret built on it. Their damage will also be highlighted in green to indicate the boost.
These can be upgraded to have increased effect on the turret built on it.
My runes were actually drawn too large that they appeared so small on the actual map. The funny thing about my previous game was how I always drew things too small, but in this game my graphics are drawn way too large that it became a problem.
I added two new turret types, so the game now has 9 turret types + 1 hero. The game had plans for 12 turret types, but thanks to buildings, there is enough variety in structures. This game is already getting a bit too complex in terms of turret types so I will see how it goes first.
The Gold Turret / Gold Factory will increase gold dropped by creeps in a certain radius. However, if there are more than 1 gold factories, I want it to always take effect of the highest leveled gold turret. So I made each creep stores a list of the gold factories’ gold multipliers, and when it dies, it checks through the list and multiplies its gold only by the highest multiplier.
The turret class was also expanded to house several new data with the introduction of the Booster turret – introducing a new mechanic where turrets can boost damage of other turrets.
It sounds sraightforward to code. But you got to make sure that multiple booster turrets buffing one tower are stacking the way you intend, and when you upgrade a booster turret, or sell it, you have to remember to update the turrets that were previously boosted – to take into account the difference between the new boost and the old boost and add or subtract accordingly. Or rather, recalculate the entire boost amount. The booster must also remember not to boost itself.
Next up is another one of my scripts, the Info Script. It was named that way because of its original use – to display info panels.
However, I extended my simple info panels to be able to include story panels as well, have pictures along with text, and a very convenient class that stores every dialogue available for use to easily trigger when I need to and can be expanded easily:
Adding new panels is literally just typing what you want to read, and what you want to see by setting imageNames to the “picture name”. The field can be left blank if I don’t want to use any picture. I can even set the picture size to “BIG” or “NORMAL” or “NONE”. Most story panels use the BIG pictures whereas information panels use normal sized or no pictures.
Info Scripts can also be queued so I can stream story panels together seamlessly. I also added a fade in fade out effect as a final touch.
I really love the story panels by the way + it’s fun to draw the pictures. I put a lot of effort into the dialogue and hopefully it doesn’t sound too awkward or cringe worthy. I want to go with minimal dialogue for this game to tell the story and I’m pretty happy with it so far.
Monsters that spawn other monsters
I managed to code a SpawnScript. It is a script that can be attached to a monster, to make it a parent. A parent that gives birth to children. So basically in the script, I can set a couple of things just by flicking switches and setting values:
The HP requirement to start spawning
Conditions to stop spawning (eg HP drops below 50%)
How many monsters to spawn and max monsters if any
Any break durations, for example, stop spawning for 20 seconds for every 8 monsters you spawned
The enemy type to spawn
This simple yet complex script is pretty flexible enough that it allows me to create a very unique first epic boss.
The Incinerator has a couple of abilities. For one, it is able to spawn miniature ships. And the first fight with it was pretty epic.
This is only Map 10, but I really feel like making it the final map. This map has a couple of special effects – darkening on spawn, story panels and a very unique epic boss that is challenging to fight. In fact, this map is so special that it feels like a finale to the game already. I really am tempted to make this the final level. That’s how complex this map and boss is.
Sadly, I think I drew a couple of other epic bosses for the future levels, and I have a story script that pans out across 25-30 maps.
Lots of work I guess. Also, more monsters spawning more monsters:
Also, in league with the new epic boss, I made two specialFX functions, which I can use to trigger when a monster spawns, and when it dies. For example, when the Incinerator spawns, it triggers an event to darken the map.
I also did manage to make a very wonderful side-map. In the screenshot, below you can notice a special building – the Control Tower. It is another one of my unique buildings that uses my new Building class script. It was initially non-interactable – i.e. just a decoration , but I programmed it to be an actual turret instead.
I really love this map a lot. I think it’s my favourite map so far. This isn’t a story map, but for some reason I felt like I wanted to put a lot of effort in each of my maps. I think that should be my goal – to make each map special and not just make maps for content’s sake. I have stopped drawing new maps for now and if anything, I have way too many map graphics. I will only draw new ones if there is really strong inspiration or good map ideas/designs.
I also made new enemies unique to this map.
Each map can be set to have a unique array of monster spawns. For example, I can specify that I want Ladybugs, Turtles, and Larva monsters. My enemy wave spawner will then loop these 3 monster spawns automatically.
My maps are getting more diversified enemy types as well. Waves can come in different forms and unique orders.
Multiple Spawn Points!
I was really NOT keen to do this. In fact, there was no need to. My game is super complex already and I don’t want more stuff in it. But I felt obliged to do this because of several reasons. Let’s skip the reasons though.
Making multiple spawn points is NOT an easy task. I want to make my spawn system flexible. And in the end, I managed to make a very robust spawning system. And this is one of the things I’m really happy about. When making games, I learned that you really want to make your game easily modified and expanded.
I can add new paths to my maps just by duplicating a current path, resetting the waypoints, and renaming it Map2A. That’s all I have to do. The code takes care of everything else.
In fact, I even coded a weight system for handling the distribution of monsters to the different paths. By default, all paths have the same weightage. But if let’s say I want like 3x more monsters to spawn from the left, and 1 from the right, I can simply do
“spawnRatio = [3, 1];”
I’m really happy about the spawn system because of its robustness. In addition, I can even enable/disable each spawn point individually, to stop them from spawning monsters at example, wave 10, during special story events, or re-enable them for like an epic wave at wave 20.
A lot of this functionality is barely used in the game though – there just isn’t much maps that need it. But I believe it adds to the cool-ness when you encounter a map that does. It makes that map feel so much more unique.
Also, monsters can spawn in the middle of the map, from special spawn points called Summoning Runes (story-related?):
So monsters do not always necessarily come from the edge of the map. I have plans to use summoning runes as a story element.
Seemingly one of my favourite things to do in any game, and have done so for my previous games: Introvert, Idle Heroes, is to create special effects.
These are specially scripted story events involving camera movement, zooming, special animations and event triggering that do not happen anywhere else in the game. These special effects can take awhile to code, depending on the complexity and the code is often unique – unique as in the code executes stuff specific to this special effect.
The special effect you see above is a combination of two individual special events. First, the monster movement animation. It is actually my first attempt at making a fluid movement animation by using rotation, position and speed. It actually took awhile to do that because I wanted the animation to look smooth. I set keyframes during the animation of where I wanted it to move to, then switched to graph mode to try to fine-tune the values and tangents.
My original intention was to just have it fly from point to point, then rotate at each waypoint to face its new direction. But doing the whole thing as a fluid animation… it was just really special.
NOTHING ELSE IN THE GAME moves like that. So it’s a very pretty special event considering every other creep or object moves on pathways. This is a one-time event that occurs once in the game. I think the animation can be improved though, but I’m still pretty happy nevertheless. It was really exciting to actually try something new and bold (to me at least haha).
The second thing you’ll notice is I incorporated the camera zooming function I coded in Part 4 of Making a TD Game.
I extended my Camera Script to allow it to do two things. First, follow an object I specify, and secondly, lock the camera and disable the player from trying to move it with WASD, scrolling with the mouse, etc.
When this event plays, the camera will automatically and gradually zoom to its desired position and zoom level, which is really, really cool because all this while the game is being played at 1x zoom and you don’t see the camera zooming in or out. The camera is also locked during zooming so you can’t break the zoom.
Here is another special effect of this map that plays once every few waves:
This is actually what is categorized as an ‘Epic Map’ in my game, which is a special map with a unique boss and advances the story quite a bit. This particular map has 3(!) special effects. The last special effect is the river in the center of the map. With each wave you summon, the river turns more and more red until it beomes a river of blood. Creepy!
Game Performances / Lag
So I wanted to test the limits of my game – to see if it lags when I have a lot of monsters on the map. So I multiplied my monster count by 10. But it was a little underwhelming. My turrets were killing too quickly. (I have to have the turret shoot and kill stuff because I want to simulate them shooting and have monster death as potential lag variables as well).
The game didn’t lag above because my turrets were killing stuff at the same rate they were spawning. So in order to test mob count limit, I set all monsters to spawn monsters every second while alive and on death, spawn up to 6 copies of itself.
Worst idea ever. The lag multiplied exponentially. The game ran okay for about half a minute, but within the next half, it dwindled to 4 fps because everything that died respawned copies of itself.
Basically, don’t have monsters spawning monsters spawning monsters. What a horrible idea that was. Oh, notice the two screenshots above are actually the same map, just with different tints?
I actually tint my maps based on the mode you enter it on. There is a ‘Day’ mode, ‘Sunset’ mode and a ‘Night’ mode to correspond with my difficulty modes, ‘Normal, Hard, Hardest’. I really love this small little touch to the game. Nothing major, but it just makes me happy. The tints used to be more obvious, but I made them more subtle because the tint settings in Unity aren’t as advanced as Photoshop – they add color directly to the graphic, which make it look darker. Too much tinting makes the map look too dark and lowers contrast. I actually created a night color filter in Photoshop that automatically makes any of my maps look like night, and looks better without contrast issues, but the problem is that having the game use 3 map graphics means the game size will grow too big. Rather than doing it via Photoshop and saving each map on 3 different filters, I decided it was best to use tints, the tradeoff being that they didn’t look as good as color adjustment settings in Photoshop.
But back to the topic on lag, I think I managed to play around with the Profiler to try and see what are the top contributors to lag. In the end I did Object Pooling for my bullets and enemies. I think whether or not they contributed hugely to the lag, it is a good idea to pool them so they consume lesser resources.
I extended target priorities (options which allow you to customize what kind of creep you want a turret to target specifically). I added new targetting options and you can toggle a turret to fire or not and also, selecting a creep sets it as a top priority target, forcing all turrets to focus fire on it. It’s pretty cool.
I also centralized a lot of my turret graphics. Probably a bit OCD, but previously some of my turrets were a little too much to the left or right, so when the disable icon appeared, it was ugly.
Anyhow, below is a portion of how my recalculateStats() function looks like.
What it does is basically calculate how much damage a turret should do. Looks simple, but consider this. There are many factors that affect a turret’s damage:
Its own upgrade level
Is it built on a special power-upped grid?
Your hero’s skills can increase turrets’ damage (via a stat called Turret damage multiplier)
Booster Turrets – a special type of turret that boosts damage of nearby turrets
Special Upgrades – The sniper turret has a special skill to increase its damage
The same goes for other variables – range, attack speed, and turret cost.
There are other additional factors for damage of course, but they are calculated separately when the turret’s bullet is fired and hits the target. Things like:
Does the bullet ignore enemy armor?
What is the damage type? DOT (burn), A.P (Armor Piercing), N (Normal), INSTANT (e.g. from external sources that do instant damage like -% of enemy HP and possibly spells if added in the future)
Is the target affected by status effects that can multiply damage? e.g. shielded OR burning enemies
So when calculating damage and updating it, you have to make sure you account for all variables and that they stack in the way they are supposed to – additively, multiplicatively, or as percentages if two things stack in the same way.
So yeah, this game is really getting a bit ambitious I guess. It has a lot of things and I really don’t want too much stuff. But *sigh*
Multiple Save Files
Also, I actually made my main menu have a scrollable interface that supports up to 30+ save file slots. This was due to the fact that I have to extensively test and balance progression so I needed a lot of save file to test with. I also fixed a fatal bug in auto save where it did not actually clone itself when you try to load it into a currently empty save slot, but actually loaded itself. It was pretty hilarious when I had 3 save slots of the auto save and playing on one file modified the other two because they were all literally referencing the same thing.
The most boring part of game development to me is probably the amount of Math behind it. I don’t think many people will find it fun doing this, but it’s still something I put a lot of effort into. I just learnt that there’s even an entire module in University that teaches this kind of stuff.
Game balancing is not something common sense that you can brute force into your game. And neither is it something everybody can do well – it explains why some games are made imbalanced, and I think it’s something I might not be able to completely prevent in my game – there are just a lot of variables and different ways players can play that it can lead to unpredictable situations.
The game is pretty big now – the size of the project is about to be as big as Idle Heroes, which is my previous game and my very first game made in Unity, and I think it is about to reach as big in terms of content.
There are lots of problems about big projects – riskier, but perhaps more rewarding. But honestly, I prefer to work on smaller projects. It also gets harder to organize stuff in growing projects. I think it is inevitable no matter how organized you try to be, you tend to feel a little confused sometimes.
For example, I have a SpawnEnemy script and a Map script. The map stores data about the map, while the spawn enemy controls spawning. If I were to define a spawn multiplier, say make a special map spawn DOUBLE the amount of creeps. Do I set this multiplier in the spawn script or the map script? I actually went ahead and defined it in the spawn script because it seemed obvious, but my scripts worked such that all the map data is initialized in the Map script. The Map script contains all information about a map or level, such as number of waves, map health, difficulty, and such. It defines all the variables that make each map unique, and spawn multiplier is one of those variables that should be defined in the map.
It seems like a subtle difference, but considering that the game has a lot of scripts, they all need to initialize orderly, in a specific sequence to make sure all variables of all objects have the correct values when the game starts.
This is more of an organization problem. The code works fine and the game runs correctly whether I put the spawn multiplier in the Map or SpawnEnemy script.
So yeah, there were times I felt there was a better way to organize my code and so I actually spend some time shifting stuff around because I know I will be working on this game for a long time and it is good to at least have a very workable and easily understood codebase, even if I am working alone and I know the game code at the back of my head.
This is part 4 of my journey in the making of a Tower Defense game! (I’m editing this post and adding more pictures as I go so check this post again after a few days and I will have added new updates!)
The game is currently expanding beyond the play area. I have begun adding new scenes /screens to the game!
Mainly, there will be many more screens, but currently, the game has 3 different screens: PLAY SCENE, LEVEL SELECT and UPGRADES.
I also worked A LOT on the map art. I try to only draw when I am really inspired because that’s when I get creative and really bizarre with my map art and ideas.
Above are some of the map types I drew for my tower defense. Although I do not divide my world into iconic areas like I did for Introvert, I do have maps for a Grassland, a rural village, Ocean, and I’m not sure what to call the red-tinted maps – The Burning Lands? The Scorching Plains? I’m bad at names, so if you got any cool ideas I welcome them.
My backgrounds folder is starting to get heavy too.
I try to put as much detail as I can in my maps, touching it up even post-production after I have put them in my game.
The above was one of my earlier maps which I went back to and actually made improvements on. Environment props, lighting and colour improvements are just some of the things that can make your map look that much cooler. There’s also animations but I’ll get to that next time when the game enters the polishing phase.
Also, not to mention that for every map created, I have to do the tilemap array – to set what tiles are ‘buildable’ on, what tile is an environment and what tile is a pathway. I can just use ones and zeroes, but I use different numbers to denote special tiles that I may have use for in future content addition. It tends to get very boring because it’s just (almost blindly) typing 1s and 0s, but it is a very important job.
0 = Buildable
1 = Pathway (you may build traps on pathway in the future*)
2 = Environment / Obstacle
3 = High ground (turrets built here will have increased range in the future*)
*As you can see, although I have plenty of ideas for this game, I have to control myself from going out of scope – time isn’t infinite and for this game to be published, I have to stay within the scope I created for myself. But it’s always good to think ahead of time so you prepare for the possibility of integrating those new features in advanced.
Designing the Upgrades Screen (CONCEPT)
The upgrades screen underwent a few changes and I spent quite a long time deciding how the interface was going to be. I didn’t want the screen to be cluttered with up and down arrows for every skill icon because that is simply ugly. I also wondered if I wanted to do a ‘popup panel’ for each skill, but if I do intend to expand this game to the mobile platform, it would be a bad idea.
Adding Difficulty Modes!
I also added something from the Impossible Scope. Each map can be played on 3 difficulty settings with HUGELY increasing rewards. The 3 modes are NORMAL, HARD and NIGHTMARE. The specific details such as rewards, difficulty multiplier aren’t decided yet at this stage. And yea, the purple ‘night’ graphic is for nightmare. Wordplay!
I figured that since I was doing the LevelSelect, I might as well have done this anyway. It is still a work in progress and I figure most of the work for adding difficulty modes will actually not be the art or coding, but with balancing the difficulty level and rewards for attempting higher difficulty modes.
Level Select, Upgrades, Stats and Menu
As of now, the game has a fully functional level select with map unlocking, a skills page with about 8 working skills, and a stats screen. The stats screen is filled with tons of useless information because I use it to debug hidden stats as well. The stats screen will be cleaned out eventually.
I also used my first ever particle system in Unity – to add some sparkly effects to the map selection. Just like the art, it’s just placeholder fancy effects for now.
I also have a main menu that I scripted in 5 minutes and you can see tell by the screenshot above (the one with the huge blue empty space). It has a working save and load system that’s uses serializable data. The menu was put in place because I foresee I may have to send my game to be playtested soon but more importantly, I need a working interface to load multiple files for me to test variables set to different values in different save files. Again, more for its debugging purposes. For example, I can set a savefile to have extra skill points just to see how it affects progression. This is useful if I want to test variables such as how many skill points each hero level should give.
One thing I noticed while watching the scene in Unity while developing was how much I wanted to zoom in. I have to admit, the turrets look a little too small sometimes. But adding a zoom mechanic meant I may have to do a lot of things. Other than setting the camera to a higher zoom, I also need:
A bounding box
Scrolling the map with WASD
A mini-map if necessary
Zooming in and out with mouse wheel function
This is a pretty late time during development to add such a major mechanic. But I did manage to code 3 of the 4 things in the list above.
I set the game to be fixed at a new 1.5x zoom and it does look pretty sweet on 1.5x zoom. 2x zoom is overkill.
I can actually see more details on the turrets. But for players who prefer to just see the whole map at an overview, then I have to add the ability to zoom with the mousewheel.
I actually went to search for tutorials because I wasn’t confident of my ability. But in the end, I couldn’t find a good camera zooming that fit my game well, so I made one myself!
And miraculously, it worked like a charm. I’m actually pretty proud of this code. Although someone posted a working code of adjusting the bounding box, it only worked if your map is at the origin. You couldn’t offset it, and you can’t use that code if you intend to adjust your zoom real time with the mouse wheel.
So I decided to try and modify his code to make it support dynamic zoom, and I did it! If you’re a programmer, this may not seem like much to you, but I was really happy to have figured out the code to dynamically adjust the bounding box for myself. There are probably other (better) ways to code this, but this was the way I did it.
This whole thing functions in a single script I attached to a game object containing the camera, so I can disable or enable zooming anytime with the touch of a button. I can even modify its min and max zoom level, currently the minimum zoom is 1x, and the max you can zoom to is 2x! It still is very clunky with my custom values, but this script will be very useful if I do make other ‘zoomable’ games in the future.
You can see me test out the finalized zoom mechanic here:
You can see that I kept clicking on things to see if I could select them properly. That’s because I previously used an alternate code and tried to offset the map, which caused problems where the mouse position or screen position does not sync with the map. The turret was built at a different spot from the mouse position when I had offset the map.
I’ve added extra functionality to the camera. Players without a mousewheel can zoom with the PageUp/Down keys or the + and – buttons. You can also use the mouse to click and drag to scroll the map in addition to the WASD/arrow keys.
The mouse dragging was still very clunky in the GIF above, but I added a Lerp code to control the panning ‘speed’ based on how zoomed in you are. It worked perfectly.
Fine-tuning the Controls
This being a TD game, there are several shortcut keys that must be in place for the player’s convenience. As a player myself, I get highly annoyed by games that do not offer me shortcut keys – especially those that were built for mobile and the developers just blindly ported it to PC to reach another audience.
As I played my game, I noticed myself instinctively pressing ESCAPE to cancel my current selection. However, the ESCAPE key brings up the menu, and it was highly annoying. So I made it such that the ESC key cancels your current selection – if you selected an enemy, it cancels the selected enemy, and it works for turrets too.
And only when you press ESCAPE when nothing at all is selected, then the menu appears.
The other control fine-tuning is that if you press the same key on the keyboard, then press it again, it cancels its last action. So if you wanted to build Turret 2, but changed your mind,you can press ‘2’ to cancel your build. ESCAPE also works, but if you are rapidly placing turrets, this is helpful if you are lazy and don’t want to move your fingers across the keyboard, especially for Turrets 6 onward, where the ESCAPE key is far.
Yes, I realized I am one of the lazier players who just prefers to have my fingers over the keys I mainly use!
That said, I’ve also been in the shoes where I didn’t quite understand a particular stat. Some games display helpful tooltips when you hover your cursor over stats, but some games don’t do that and it can really confuse the player – one of the reasons players quit is when they don’t understand what is going on in the game and what all those numbers and stats mean. If the player doesn’t know what your stats do, he doesn’t know what to upgrade, he’ll feel lost and lose interest very quickly no matter how content-rich your game is.
This being a TD game and I have a hero character with an upgrade menu that’s growing by the day in complexity, I know I need to have to display information without obstructing the main gameplay by flooding it with tutorials / annoying popups and such.
Oh and talking about the hero…
The Hero Character (and its problems)
Although I said that I did not want to implement a hero character at this early stage of the game’s development phase, I decided to do it now because having a hero character in the game will greatly affect the balancing and I have to tweak each map’s difficulty. So I want to finalize the hero’s role in the game before moving on to other key areas of development.
There are some features that make the hero special from normal turrets:
He doesn’t cost any gold to ‘build’, but he has a cooldown before he can be summoned to the map.
He can be sold and moved around the map, but with a cooldown so he isn’t exploitable by always putting him in a boss’s range
You can only have 1 Hero character on the map
Now when thinking about my hero, there were a couple of questions I had to ask myself.
Should he be upgraded with gold like normal turrets?
When you upgrade him and he is ‘sold’, does he reset back to Upgrade Lv 1 the next time you place him?
If his upgrades persist, it may cause balance issues where player is able to repeatedly ‘sell’ or ‘move’ his hero to always be in range of a boss or creep
Then there was an even bigger issue was that because the hero can level up, he gets really strong compared to other turrets at the beginning of a game. The turrets start at level 1, but the hero can be at level 10 or 20 in the first wave! But because he doesn’t scale like other turrets, he gets very useless late game because giving him upgrades that scale the same way as turrets makes turrets useless! The player would just spend all their gold on the hero character and ignore turrets. But make the upgrades weak or disallowing upgrades makes the hero useless late game. So either way, I was pretty screwed.
After lots of discussion with my friend, we came up with the idea that the hero will be a special unit that is very powerful, but you can only use him for a short duration and he will ‘disappear’. It was the right thing to do and I loved the idea – there is no point keeping the hero on the map forever when he gets useless toward late game. Better to remove him once he starts to become useless. The hero is still very powerful despite his limited use, and he can turn the tide of battle when you deploy him in a critical wave. This adds strategic depth to the game that I never imagined before.
The implementation for the feature took very long. I spent a whole night finalizing the design and changes, and also pacing around my house thinking of and trying to predict if a change as major as this would cause any issues.
Skills / Upgrades!
One of my favourite things to make in any game is an upgrade system. I love a game that gives me a sense of progression and getting stronger with time, and I want my game to have this as well. To do so, I incorporated the upgrades system. I didn’t want to be too fancy with a skill tree.
Well, the thing about having skill trees is you probably make it for the purpose of unlocking stuff and pre-requisites. But they can get very complex from a balancing perspective. It has its pros and cons.
The last time I attempted skill trees, it didn’t go so well not much because of programming or art, but more so in how the tree was designed. This time, I really want to go as simple as possible, so I just want to use a simple unlocking system – by hero level and displaying all my skills in one screen.
Each of my hero’s skills contains a max level as well up to 3 variables which I define in the Skill class. These variables can function as passive damage, or gold increase, depending on what skill it is. These skills are added to my Hero class and my hero has a getSkill() so that I can conveniently get any data such as interestRate, turretPercentDMG, or any other bonuses from anywhere in the game.
I also spent a lot of time tinkering with what I feel is the final UI. You can hold SHIFT to increase/decrease skills by x10 without having to click multiple times. You can also hold down the mouse button on an arrow if your SHIFT key is spoilt. Additionally, the arrow keys on your keyboard increase/decrease all skill levels by 1. Now nobody can say I don’t have enough shortcuts!
I also love the UI in the sense that there is a bar below every skill that fills up as you increase it. It’s a very visual way to see how much of each skill you have your SP in.
Upgrades aren’t new to this genre, but doing it is not an easy feat either. It is much easier to create a sandbox TD than it is to create one with progression and a leveling / XP system. Not many TDs attempt this I guess because of how tricky it can be to try and blend a bit of RPG into a TD. Most casual TDs keep their upgrade system simple and straightforward.
If I were to make a sandbox TD, it would have been a lot easier. There would be no need to spend so much time on balancing. But because I have multiple maps, multiple difficulty modes and unlockables, the progression of the game has to scale properly. I can’t have an easy level followed by a hard level, or a gold formula where it is so hard to get gold at the start and then by late game you earn so much gold you insta-kill bosses, which is what is happening in my game right now. It’s ridiculous!
So yea, upgrades are a very treacherous territory I’m venturing into, but I will get it done!
Revisiting the Enemy
Other than the stuff I mentioned in Part II, I actually spent very little time talking about the enemy even though it’s probably one of the more outstanding things about this game. So I’ve decided to talk about it! Besides, I’ve made some changes to some of its statuses as well.
The enemy has two important scripts to make it work. A MoveEnemy script controls its speed, max speed and its position along its current path.
The Enemy Script is far more interesting. Here, every data about the enemy is stored and can be extracted. Things from its reward to whether it is immune to your slow turrets. The only thing missing is Health, Armor and Damage Reduction values which are stored in the Health Script, a separate script attached to the enemy’s health bar, which is a component of the enemy itself. I revisit the enemy script every so often to modify stuff – not so much to add stuff any more because it already has everything I need.
But there’s another very important thing in the game – Turrets. And there is one particular turret that is giving me a lot of headaches.
The Sniper Optimization Dilemna
Every turret in my game has two basic scripts attached to it – A Circle Collider component, which determines the range of the turret, and a Shoot Enemies script attached to it. When an enemy enters its range, it is added to its own list, ‘Enemies In Range’.
One of the more challenging turrets I added is the Sniper. Today, I ‘re-coded’ the Sniper’s special ability – it can shoot invisible creeps which hides itself from your turrets. It gets technical here on, so skip the next paragraph if you don’t want to read the programming aspect.
There were so many ways to code this feature, but I didn’t know what the most optimized way was. I decided to code it such that all enemies disable their colliders when they hide, and then re-enable them when they unhide. However, without colliders, sniper turrets will then require an internal function that does a distance check to continuously detect if an enemy is in range. But without a collider, again it meant I had to somehow get a list of all enemies on the map – not just the ones already added to my list of hittable enemies, but also the ones that aren’t – the reason being that without colliders, even the sniper turret has no idea when enemies enter its range. So there was actually a need to consider what was the better way to get a list of enemies spawned – create a List that is stored in the map object, adding enemies spawned to this list…OR… create an empty parent game object within which all enemies are instantiated in. Then the sniper will reference this parent to get the enemy list.
There are just so many things to think about when adding a feature like that. I did however, in the end get it to work.
Balancing Pt 3
Jokes aside, balancing this game has been a pain. As the game grows, there are more and more variables to account for. And right now I spend more time testing than actually developing the game because I want to get the pacing and difficulty of the game correct.
Mobile Porting and Testing (13~18 Dec)
As I was overseas for 6 days, I did not manage to add anything for one week. But that’s not to say that progress was not made in these 6 days. Before I flew off, I managed to port my game to Mobile.
The reason was not because I want to launch this game on mobile, but rather, I needed a platform on which I could readily access my game (and show it to potential employers in the future I guess?).
It was pretty major to me because I know the difficulty of porting a game to mobile. Sure, Unity makes it easier, but if done incorrectly, it can cause problems. I spent about 2 hours trying to get a proper aspect ratio and resolution for an Android build because the game kept looking like this on my phone:
It was a hot mess with the UI jumping about and being in places they should not be. What’s worse that my flight was early in the morning and I was extremely sleep deprived as a result of burning midnight oil trying to port my game. I was EXTREMELY tired when I was doing the mobile porting. I think each time I waited for the game to compile to my phone, I would fall asleep for a few seconds. Seriously, I was just soooo tired.
Thankfully, it worked in the end! Though playable on phone and having the game work much better than I thought, it really isn’t very optimized. Nevertheless, thanks to this, I was able to test my game while overseas.
List of improvements (and some balancing notes) I took down during my playtesting while overseas
The improvement list contains stuff to make the game better – mostly quality of life and better UI / interactions to enhance user experience. I also wrote a lot of code on my phone. By the end of my trip, I had accumulated 40(!) pages of notes on my phone. Apart from improvements, I also had a bug list and other lists for different purposes.
Not to mention, I also wrote code.
Yeah there were apparently more pages of code than I thought as I was exporting all my notes from my phone to my desktop.
There’s code for an Equip class, even a Spells feature from my mega-impossible scope, but most importantly, an extension of my Turret script, for a very new feature I intend to implement very soon – BUILDINGS.
The reason why I wanted to pseudo-code on my phone was because in programming, I sometimes find that people sometimes can jump too quickly into coding a feature only to realize later on that there are better ways to code it. I’m no exception, especially when I am so excited about my game. Sometimes, I don’t think long term enough while coding and this makes it hard for me to expand the game.
Thankfully, having 6 days away from Unity gave me PLENTY of time to deeply think and analyse what I feel is the best way to code certain features in my game.
And I managed to code 4 scripts overseas! Yes, actual scripts that I could use in my game the moment I got back to Singapore. I had access to a laptop there, downloaded Unity and began coding. I didn’t manage to sync my project with Dropbox, so I mostly coded independent scripts that would work without my game – a script for an inventory system and an Equipment class that is able to be extended to house several equipment types like Wand, Robe, Glove etc.
I also have some pages on plans on a ‘Challenges’ feature and on the implementation of the ‘buildings’ feature.
I also drew some mock-ups of some UI and visual diagrams (more for my own reading).
However, the inventory system and equipment script are for ‘impossible scope’ features, which have extremely low priority on my to-do list. I won’t be adding features in that scope to the game until I settle the things in my medium scope. I might even not add them at all but in a sequel because the current game really has a lot of features already.
THAT’S ALL FOR NOW!
So I guess that’s all for now. The next time I write here will most likely be a new post about 1 week from this one. It has just been too much fun but I’ve got a lot of work to do now that I am back in Singapore and I really want to get on with implementing all the things above. I have already implemented Challenges and have a working Building script, which I am super excited to talk about in the next post!
It is now Day 10 of my journey of making a Tower Defense game. Read Part 1 here and Part 2 here.
At last, I am done with the creeps! Everything from coding, implementation and its art/animations are more or less finalized! AT the moment, there are 14 creep variations, each with their own animations and abilities. With creeps in place, the next thing I had to do was the Wave UI.
The Wave UI serves a very important purpose – to display the upcoming wave information – creep type, health, gold, speed, description and its special ability stats (if any).
I first coded the wave boxes to move from right to left.
It was very buggy at this time of this screenshot, but there is a very neat shuffling animation. Basically, instead of ALL wave boxes moving together, they move one after the other. I think this is a really neat effect that though is small, adds that nice touch to the UI.
Everything was not smooth sailing. This wave UI is really one of the harder things to code so far It was deceptively simple, but complicated.
There’s this problem I had was that I never create my enemy before it is needed, so there was no way to obtain information about the next wave of creeps without first spawning a creep!
It would be cheap to simply secret spawn a creep without the player noticing, get its stats, then kill it, but it’s not a very clean approach and very hacky.
Of course, there are many ways to get those information without spawning a creep – like moving the functions that calculate HP value of a creep of a particular type at a particular wave number to somewhere more accessible. But these functions cannot go into my EnemyScript because the enemy isn’t spawned! Sure, I will have to put it in something like the WaveManager or GameManager. But to me it seems like counter-intuitive design because the Enemy will end up referencing another object to get its own HP value. It’s like the enemy doesn’t know its own HP and has to ask another object.
I even tried setting and obtaining values from the Enemy base Prefab and boy was that a horrible idea. For those that don’t know what a Prefab is, it’s like a ‘base’ object which you can create multiple copies of, like bullets or enemies that are created multiple times and destroyed. What happened was that I ended up CHANGING the base prefab, essentially “corrupting” it and every enemy that spawned after it had its values OVERRIDEN. Of course, I did try to set it back in code, but it got really messy and weird shit started happening, so I gave up the idea.
I didn’t know what the best practice was so I decided it was down to preference at this point – I am after all, the game designer and I have to be comfortable and understand my own code.
My style is to use a DummyEnemy. This dummy enemy is actually not an actual enemy, but an empty shell containing the EnemyData class, a new class which I made to store every important detail that is needed for display in the wave UI.
The DummyEnemy can be initialized to ANY enemy type, and it will simulate the stats of that enemy. There may be a better way to code the wave UI, but I think this works very well for my game, plus I even intentionally allowed this ‘dummyEnemy’ to be seen by the player in the wave Info UI:
You can see the dummy enemy at the bottom right. It also plays its walking animation! HOW SWEET IS THAT? I totally didn’t intend to make the wave UI this fancy. Oh and by the way, that screenshot was 2 days after the first screenshot of the wave UI, so most of the bugs are fixed. I even got the wave UI to display the correct color codes of a creep and indicate if it is a boss wave!!!
I was really happy to have not only a working, but very polished Wave UI that may look like it will stick until the final game release.
When upgraded, towers now get a green upgrade animation. This came out of necessity because I couldn’t tell when my towers were upgraded even though I was pressing ‘U’, there was no visual feedback on the tower being upgraded other than the damage numbers in the UI changing.
Turrets also get target priorities – whether to attack the first or last enemy, etc.
I was very reluctant to do this at first, but the variety of towers I have and the creep enemy specials means that I have to give the player the option of specifying what targets he wants his turrets to attack.
The coding ended up being so much simpler than I thought. I already had the script to target the enemy nearest to the exit, so I just reversed it, and made a bunch of if-else statements based on what target priority setting the tower has.
In fact, I was just copy-pasting the if-else statements for the code that it actually got boring to implement this feature. Nevertheless, I’m glad I get something easy to code once in awhile. It was a great break after coding the wave UI.
There are multiple ways to code the creep’s movement path in TDs. From using pathfinding AI to simple waypoints, it all depends on what kind of game you are making.
My game does not require dynamic path generation, so I used way points. It is always better to keep your game simple whenever possible.
Here, you can see that I am already starting to introduce multiple levels into the game (art in the screenshot above isn’t finalized). I started by first ensuring that I can dynamically create map graphics easily. Coding multiple maps is a matter of using 1 and 0, so if I create new maps, the bulk of my time will be spent on drawing. In my first ever attempt at Flash TD, I used tiles as a quick approach to render the map. The result was pretty ugly because it looked so… systematic. And using gridded tile graphics may make your map look artificially generated and repetitive. Nothing bad about that, but I wanted my game to look pretty, so I draw custom maps manually.
But can manually drawing be simplified?
Applying a set of filters and stuff actually makes me able to draw dynamic pathways easily + look good at the same time without having to resort to grids. All I did to draw those paths was literally pick up my stylus and just draw a path on my WACOM tablet, like how I would draw on paper.
I guess that’s one of the really godly things about having your own drawing tablet.
Although it looks easy, drawing maps still take time. The pathway takes a very short amount of time, but the map itself is very tedious – at least 30 minutes to an hour or two. Why? Because I want each map to try to use unique environment art. I mostly try not to use the same trees. No doubt some environment art will be duplicated, but I try to draw different trees and stuff for each of my maps.
Once the art is drawn, I add finishing touches like lighting and shadows to the map and the new map is ready to be implemented!
Yes, manually drawing maps is tedious, but I think it’s worth having pretty maps especially when it occupies 80% of the game screen, plus it is pretty fun! This of course, depends on the game’s design. I don’t intend for my game to have many levels so this design approach works fine for my game.
The HERO character
I have also begun work on an optional feature – the Hero character. The Hero is meant to be unplayable in my TD – just an invisible character, but I may add him in as a bonus playable ‘turret’ on his own!
At the moment, only the art is done and very minimal coding. You can call your hero to the map and hell, you can even put 10 heroes on the map because they don’t cost anything.
I have a HAT graphic that is not shown above. If I do implement equipment (super low priority), the hero hat object has to be stored separately because I will have to swap out the hat graphic when necessary.
I have LOTS of design work made for the Hero. In fact, I have MULTIPLE designs. And I’m not sure what the best way is to make the hero work in this game, so I have disabled the Hero feature temporarily.
I also have a backup sprite and side-view attack animation from Idle Heroes for use in this game.
Though I have about 50% of the hero coding done, and even have the hero sprite and idle/attack animations completed, I want to work on other more important features and the Hero is not a priority. At this stage, the balancing and game’s main reward system is more important.
As the game grows and there are more and more objects and states, many potential problem can arise if you are not careful.
Game Flow (Technical)
Unlike Flash game programming, in Unity there is no fixed order in which your game’s objects are created. In Flash, I create objects as and when I need and doing so lets me determine the order in which things are ‘created’ in the game. For example, I have to first create my map before I go on to create the enemies because the map stores important unique data like ‘number of waves’. Without knowing the ‘number of waves’, other scripts like the WaveManager or enemy spawner do not know how many waves the level has and the game runs awkwardly.
In Unity, Game Objects in the scene are created in a random order. That means if my map is created last, every other object referencing the map will get inaccurate values and the game behaves unexpectedly or worse – crash. But usually it just produces unpredictable results – and people refer to them as bugs.
So it was very important to use something called Awake() to determine the priority and order of the objects I am creating.
Awake() is the very first thing that happens to every game object and by using a single object’s Awake(), I can use it to call other objects in a specific order.
This is how my game flows currently:
Since this is my first TD, I realized that there are some things I could have coded better. If there was one thing I would change, it would be to create my waves in WaveManager rather than SpawnEnemy, which might have solved my problem above about getting an enemy’s stats before it is spawned. It’s a bit too late to change it, so I left it alone.
Here’s how the game works: First, I get my Hero. He has very crucial stats I need to reference for my Turrets, such as turretDamageMultiplier. If he has 150% turret DMG, that means my turrets have to store damage values 1.5x their base damage. These values, once set, do not change when the game runs because they are base values. Any additional temporary multipliers will act on these base values, such as buffs which I may code, like x2 damage for 30 seconds, etc.
Then I create the map where unique data such as ‘number of waves’, background are set. This way, the SpawnEnemy script is safe to start generating the waves necessary for the level.
When all this is done, the game runs START() on all the other non-crucial game objects and the rest of the game flows.
The game has to flow in a very systematic approach so whatever happens is predictable and having a clear flow chart will actually help me in debugging to know what went wrong and trace the problem as close as possible to the source.
Game Flow (Design)
Now that the technical part is over, I have reached the stage where the game is starting to expand outside of its play area. For example, the introduction of multiple maps to play means I need some sort of level selection screen or menu.
For the past week, every thing I have coded, drawn or animated is reflected in one scene(or one screen) – the Play State, a singular scene where all the playing occurs.
There are other ‘screens’ I intended to introduce to the game, but only when the game really needed them. I don’t want to pre-create screens that are outside the current scope. Such screens include:
Main Menu screen
Game Over Screen
Level selection (medium feature)
Skills / Upgrade Tree screen (big feature)
In my previous blog post, ‘Making a TD Game Part 1’, I said that I had 3 game scopes, and now I am starting to actually implement features of the ‘Medium Scope’ – aka the things that are ‘nice to have’ in the game, but not necessary to make it playable. These are mostly content-based features, which are exciting to make, but jumping in too soon without planning can be disastrous, so I charted out briefly how the game states transition from one to another.
Again, I arrived at this chart after analyzing other games and how they flow. It was pretty fun to go to some games I played and restart, looking at how they introduce the player to the different ‘screens’ and what order in the game they appear in. I feel games are better off gradually show more stuff to the player rather than overloading them with so many screens, especially in my game where it may have the potentially to overload players when they finish a level and suddenly there’s up to four different buttons that take them to four different screens. This can overload and confuse the player – which buttons takes them to the next level? What do they press if they want to replay the previous level, etc has to be made obvious.
I did this unlocking design mechanic in my game OldStory and the longer players praised its design, saying that it was great to have more content unlocked as you got deeper into the game. It’s like when they think the game has nothing left for them to do, suddenly a whole new feature and range of options are unlocked and it’s exciting.
The following is just my opinion, but when a player just started, he isn’t interested to see everything your game has to offer. He first wants to learn how to play the game. And only when he becomes good at it does he start to want to explore and want to learn and see new features. Content is best generated only when it is needed. Which brings me to my next point.
Designing the tutorial…if there will be one?
Rather than using words, visuals or even animations are great, but take effort to make. I would normally try to use as little words as possible because the truth is that most players will NOT read your tutorials. Even as a player myself, I skip games with super long text and tutorials. That’s why my game literally has no tutorial. The first form of a tutorial is actually in an optional-to-read text that can be read at any time. I put somewhat useful tips there, but for important details, I make it clearer.
The first compulsory tutorial I added is a quick animated popup drawing attention to key elements of the UI which appears only at the 7th wave, giving the player enough ‘breathing space’ to explore the game on his own.
I also lock and hide unecessary elements of the UI when the game first starts. The game displays only 2 turrets out of the 10 available when you first start the game. The minimalism effect worked really great because I could focus on what was important – the two turrets I can build. (Even the starter Hero character is locked from the start when you first play).
Notice I also color coded the ‘cost’ text to turn red when it is unaffordable, just in case the player attempts to try to build the second turret and wonders why the button doesn’t work / the turret doesn’t build.
Of the two starting turrets, the second turret is too costly to build. I intentionally made it cost 150, and give the player only 100 starting gold. This is because I want the player to build the first turret – Basic Turret – to first understand how turrets work. The second turret has advanced properties (multi-targetting) that the player may not understand yet until he progresses a few waves later and earns enough to buy the second turret.
I somewhat learned this from a Plants vs Zombies video I watched where the designer explained that he made Sunflowers cost only 50 Sun and Peashooters costed 100, which somewhat ‘forced’ the player to build more Sunflowers so he can farm more suns, which was what the designers wanted players to do because he noticed playtesters skipping sunflowers and putting peashooters when they were equally priced, causing them to eventually lose the game iirc.
While my game doesn’t have that kind of penalty where you lose if you don’t build the first turret first, I want the player to first learn the basics before moving on to using turrets with special traits.
So the next time you play a game like PvZ, you might look at the cost of towers and think those numbers were made up randomly by the designer, but watch – some games put a lot of thought into these seemingly ‘random’ numbers.
With the game getting in the process of being balanced, I added a non-quickplay mode which has limited waves and is the foundation for the game’s main mode of play. And what happens when the player wins? There was nothing rewarding the player for the past 10 days! That’s why I need a victory screen!
I adapted it from my Space Shooter game’s victory screen and modified it for this game. I went from ‘concept art’ to ‘sub-par end product’ in like a few minutes, then spent the next few hours with implementation. Based on how the game goes, the victory screen will change to display different things.
Game Balancing Pt II
I spent an entire night figuring out how to make the values in the game work.
I enter my values in red boxes and this updates a very long table containing every single detail about a particular wave. On the top left, the values I can set are enemy base HP, base enemy count, base enemy gold, and powerHPG which I will talk about later. The blue boxes indicate the creep’s base HP increase from the previous wave.
On the right, I set the ratio of DMG to Gold for the turrets, and the player’s starting gold. Starting gold seems insignificant, but watch how it affects the graph below.
Starting gold looks like something that simply affects the y-intercept, but a high starting gold can actually turn the tide from a difficult early-game to a super easy early game. It turns a bell curve into a linear one. It is simply one of the most overpowered values that is used for early-game difficulty adjustment.
But it is a very hacky way to change early game difficulty so I avoid using it.
powHPG is a very important value in this game. It stands for power of HP to Gold. It controls the difficulty curve to a large extent and when doing my balancing, I extensively fine-tune this value because every other variable’s effect is largely based off it.
powHPG goes into my formula for calculating creep gold reward and a tiny change will greatly affect early or late game difficulty. There’s also a staggering effect in the second picture which is not caused by powHPG, but by the enemy count increment variable, which increases the number of enemies spawning in a wave by 1 every X waves:
This staggering effect creates a difficulty bump in the game every X waves that gradually eases back to normal difficulty (because more enemies = more gold, and the effect cancels out the initial additional difficulty boost).
By also adjusting powHPG, I can decide how difficult early game vs late game is. A higher powHPG has the tendency to make early game battles comparably harder while a lower powHPG increases the difficulty of the late waves more.
The problem I had was trying to balance both of them out and it took a lot of value setting and testing. It was such a pain because I was actually discussing with my friend what the best way to handle this was.
Despite having a lot of variables at my disposal to tweak, early game difficulty was always too high. You might think ‘why don’t I just decrease the starting HP?’. Well, decreasing the base enemy HP was a perfect solution for smaller maps, but didn’t work very well on big maps with 60+ waves because the difficulty scales up too fast regardless of how high or low I set the base HP as.
My current solution to fix early game difficulty being too high and fixing late game difficulty scaling up too quickly on bigger maps may be to set powHPG individually based on the map’s size and level. I noticed that a powHPG value between 0.8 and 0.9 work best.
A low powHPG value is used for early game smaller maps because there is a low threshold where gold dropped by enemies falls short of gold required for damage upkeep. This means enemies can afford to grow more in power per wave, and the easy early game is great for beginner levels with very few waves.
A high powHPG value is used for bigger maps which have more waves. A high powHPG eases the growth of enemy difficulty more gradually by allowing late game enemies to drop more gold. This makes it easier to reach and survive higher waves, but can have an added negative effect of making early waves harder – I intend to counteract this effect by introducing skills that increase the player’s starting gold and decreasing the cost to build starter towers. These skills will be more viable late game where I may use maps with higher powHPG.
Other solutions I explored were altering the health Multiplier increment per wave, but I wanted to fix those values at a constant 1.2 (+20% HP per wave) and changing those are a last resort.
The reason why I spend a LOT of time and math balancing was because my previous game had literally no balancing work – I put it off to the last minute and the balancing problems became too late and complex to fix.
After spending so much time on balancing, I hope I do not have to tread this territory again, but I think over time, the game will change and have to re-balanced, but this should keep the game pretty balanced for the moment.
Once I have decided on the values, I think this will be the last thing I will do before I step out onto officially starting implementing content from my Medium Scope!!!
Anyway, I am coming to the end of this post, so I’m putting miscellaneous pictures that I don’t really have much to talk about.
Behind the Scenes
Here are some other behind the scenes work.
(Coming Soon) Skill Tree?
Also a concept idea of what I may be adding soon ^
Time has flown since the start of this game. 10 Days felt like a long time since the game was in its infancy.
I am definitely looking forward to what this game will result in a week from now!