Home // From Unity tutorials to releasing a RTS game, with seamless cross-platform game play in 14 months.
My story begins 14 months ago. It was August of 2016 and for the first time in my 5 year career I had a real chance to try to create something of my own as the main programmer. I’m part of a small 3-man 5 year old indie development company, which has been on the brink of bankruptcy but managed to pull through in the end. Up to this point I had been taking care of all the marketing,business, community presence and social aspects, basically everything besides coding and creating graphics was on my todo list.
I had previously dabbled and tried to code with Java, but I would always fail to understand how things work together and how I can tie different elements together to create a complete working package. I knew some if/else and for loops, but my knowledge would not extend far beyond that. My brother would always talk about constructors and stuff, that’s when my head would start to fail to wrap around everything.
I had heard a lot about Unity, so I decided to try one more time and use try to use Unity as a tool. I fired up Unity and jumped into the basic tutorials I found on Unitys web site. I created the roguelike dungeon game, and using instructions found online I was able to fire it up on my own Android phone. The feeling was quite amazing! It was almost like the first time we fired up our first game 5 years ago, but nothing can top that.
This was the start of it all, a hope was born inside me that perhaps I could be able to create something of my own, even if it was just a simple game. In the end, I would go and create a game that was far beyond any original scope I had in mind, and along the way I was able to solve some very tough puzzles regarding optimization and more.
I worked relentlessly for 14 months, 6-7 days a week clocking 12 hours every day. This game was my life, I like to sleep too, so I literally didn’t have anything else in my life for these 14 months. Anyway, I learned a lot and wanted to share some of the best ones that helped me in the end.
Fog Of War is your friend and will help you increase performance.
What is hidden the player cannot see, therefore it doesn’t matter if things work a bit different underneath the veil of darkness. I was able to increase performance a lot by:
- Not drawing units underneath fog of war at all.
- Altering unit turret behavior to turn instantly to face targets instead of having a turning rate.
- Disabling any explosion animations or sounds.
- I stripped basically everything that wasn’t needed when the player does not see what’s going on.
This means that when enemy units are fighting each other underneath fog of war everything is simplified. Outcome is not quite the same, but close enough to not make any real difference for the player. When I created my unit scanning scripts I made sure to have a buffer to ensure every time a unit pops out of fog of war it has already been revealed for a little time. The player never notices anything.
Having key points in a map will help simplify the development of your AI.
At one point in development I decided to add capture points to my sector maps, to create more depth and strategy to the game. These capture points would then generate some resources and the player could compete with the AI for their dominance.
I was still very early with my AI development, and noticed these capture points would solve many of my problems. One of my biggest problems was how could I create an AI that moves intelligently around a map and tries to fight a human player?
The answer lie in creating capture points as information points / triggers, which could relay information to the AI allowing the AI to have a better picture of the map situation and counter moves the player tries to do. The capture points scan periodically (once every 2 seconds or so) for units nearby, then relay this information to the AI giving it an overall picture of what the map situation is at that moment. Based on this information, the AI can make own moves.
For example: If the player is guarding some capture point heavily, this capture point will send information of “player unit force” to the AI and the AI can easily calculate what kind of force it needs to send in order to stand a chance. This will give us a much more intelligent AI in a very simple way, creating battles that are fierce and epic. We do not want the AI to always send just one unit into a massive pile of Player units, that isn’t very challenging or fun.
Increase performance by setting scan times and adding random variation to every unit scan.
I created a Performance Controller, which had scan times saved for different types of units, enemy and Player. Different units would use this performance controller script to assign a scan time, these scan times would limit how often different types of units scan their surroundings for other units.
When units check for other units close to them, instead of doing this operation every frame they use scan times with some random variation. Obviously doing this operation every frame would be too costly, we only need to do it once per second or so. We also need to create a randomization time on top of this scan time, to prevent all units from doing this operation on the exact same frame, which would cause hiccups in how the game is running.
I also tweaked the scan times to be lower for player units, and a bit higher for enemy units. We want the player to feel his units are reacting quickly enough to his commands, preventing him from getting frustrated. Regarding enemy units, the player will not care as much as long as the AI seems to be doing something intelligent.
A unified user interface for both PC and mobile is possible, but will be a compromise.
In the end I was able to create a user interface that works on both PC and mobile. It’s quite incredible, the same user interface works on big ultra wide 3440 x 1440 resolution screens and small phones, and it looks OK.
I achieved this by creating menus used to control game play using a reference resolution of 1280 x 800. Why this resolution? I believe it was the standard one in Unity, hah 🙂 Anyway, I would then scale the menus down or not depending on the device. For small mobile devices, I would not scale down at all, for PC screens, the scale would be between 0.5 to 0.75.
I also created some buttons that had an “icon + text” combination to them. Depending on screen size and resolution I could then simply disable the text element of the button, creating icons that are better fit for small mobile devices and open up more space.
In the end, I ended up with a UI that at least looks good on both PC and mobile, but has it’s limitations of course.
Saving and loading, accompanied by seamless cross-platform game play
This was one of the biggest challenges I faced. I wanted to have seamless cross-platform game play, where the player could play on PC and then use a cloud save system to continue on his phone. I had no idea how saving and loading works, but by following this 3-step tutorial I was able to create a system that works really well.
In the end, I simply saved all my unit names, current health, position, player situation etc. To files on disk and then created a levelmaster script to piece these back together when loading the map scene.
One of my biggest problems regarding this was keeping control of the subscribe/unsubscribe events. If I made a mistake here it could cause Unity to throw enigmatic errors, even carshing Unity completely. It took some time to figure out what was wrong. I have quite complicated mechanics in my game, requiring a lot of subscribe and unsubscribe events for my units.
Once I had saving/loading working, it wasn’t very hard to create seamless cross-platform game play. We have our own cloud system, where players can register. We use Google Appengine for this and it works great. The player simply uploads save files from one device, and downloads them to another device. These files are then used to load games.
Updating Unity is a risk , be sure to leave some time to test properly
Unity is certainly a great and powerful tool, it allowed me to be able to create my own game after all! Unity is, however, also accompanied by its own quirks and I had to deal with my own share of trouble. Bugs are present, and you need to hack your way through them. Updating is a risk, something might get broken and you might not even notice. Whenever you update the engine be sure to leave yourself time to test it out.
You have to take the good with the bad, even if there are bugs they have been fixed or I have been able to find a way to hack through them. Despite all of this I can really recommend Unity, and it works great for a person like me needing a lot of visual feedback for what he does.
Hope you found some value in this, and if you are interested in the game I created you can find it:
Click images below to get the game on mobile. Apple image should open up the store page directly on your Apple device.