War Commander: Rogue Assault

App Icon

  • Product description: Free-to-play War game for iOS and Android by KIXEYE.
  • Release Date: December 2016
  • Website: War Commander: Rogue Assault
  • Product history/genesis: An IP based on their successful browser game
  • Team: Subcontracted through ClutchPlay Games, LLC
  • Core Technologies: C# in Unity3D with a .Net based server
  • Most proud of: New Unity5 based Asset Bundle system with per-device optimization and Jenkins CI
  • Responsibilities: Optimization

After shipping ModernCoalition and waiting for players to join, I was contacted by ClutchPlay Games. They are developers who used to work at the same studio I previously did. We hit it off, and the rest is history.

Their major project at the time was subcontracting for KIXEYE to work on their upcoming battle game War Commander: Rogue Assault. Up to that point, the majority of development focus was on the iOS platform while they tuned the core game. I was brought in to improve the play experience on Android devices in general.

Unity5 Asset Bundles

In Unity3D, the simplest way to publicly download additional content like models and textures is to add them to a Unity-specific container called an “asset bundle.” At the time they were using the pre-Unity 5 asset bundle system. It worked, but was plagued with duplicated content, which was taking forever to load and filling up memory with unnecessary junk.

With my previous experience with asset bundles, I was able to improve their situation to a degree, but realized an overhaul was going to be needed to tame the asset soup. I considered re-using the system I’d previously written for other games, but realized it would take as much work to patch in my old system as it would be to write a new one based on the recently released Unity 5 bundle system. Rather than update to a legacy API, I set to work writing a new system with my knowledge of the old.

Starting with Unity’s sample code, it didn’t take long to get something that worked. However, as one might expect, I found several places where the sample code fell far short of the needs of a production-ready game. Eventually I ended up shoring up their sample code with pieces from the my prior generation system, which resolved many of the issues faced. Content duplication was cut to a fraction of the previous levels, and we were now on Unity’s preferred ‘future’ path.

Texture Formats

World Map SnippetThe other major issue that was stalling the Android builds was texture efficiency. Currently, there is one ‘basic’ texture compression format that all Android devices are required to support, referred to as “ETC1.” It has acceptable compression, but it’s not the most efficient for all devices. In fact, there are four other formats that compress better with higher visual fidelity.

One of the benefits of Asset Bundles in general is that the game code doesn’t have to care about the specific content that it loads. That is, as long as all the assets are there and in the right places, the game code is the same no matter what size or format the assets are in. I made use of this fact by creating multiple sets of asset bundles. Each set represented a single texture format and overall texture size combination. This meant that each device would get the texture that is the most appropriate for the hardware in the player’s hand, without loading anything they don’t need.

Jenkins Pipelines

There is a catch to these combinations of texture size and format is that you must build them all. There are almost thirty combinations! To make matters worse, Unity has to reimport each texture that changes. They are not stored in a cache of any kind. (Yes there is the Unity Cache Server, but it is fickle, at best.)

As any decent project does, we use “continuous integration.” This is where a server, separate from your development machine, checks out a copy of the project, builds it, and tests it. This is highly useful to catch little mistakes that can blow up into big deals, long before it harms anyone else on the project. This group was making use of the excellent Jenkins server.

Having Jenkins build all these texture combinations was time consuming. Initially we had separate copies of the project for every texture format, but we realized that reimporting the texture for each desired size was taking a significant portion of time. I reasoned that keeping one copy of the project for each combination of texture format and size would minimize the amount of reimporting Unity would have to do.

Up to this point the Jenkins tasks were step-based. As in, “do this, this, then this.” We started with ten complicated Jenkins tasks with a large amount of duplicate logic that was a nightmare to maintain. Recently Jenkins added support for a scripting language style of defining the jobs to be run, called “pipelines.” I felt that switching to a code-based solution would allow us more freedom to optimize the tasks at hand in whatever ways we deemed necessary. And indeed this was true. Those ten jobs reduced to three, with a significant portion of logic shared between them.

Wrapup

game logoThis project had some of the biggest technical hurdles in my career, which I was able to overcome. In the end, I have even deeper knowledge of Unity3d asset bundles, and additional insights into what works (and what doesn’t!) when implementing an asset heavy game on mobile platforms.