Something that was new to me when I started Unity development was the vast quantity of third party plugins. In the years I spent developing games with custom in-house engines, third party code did exist, but it generally existed in the form of either plugins for artist tools such as Maya, or larger scale technology like Havok physics and Scaleform. Between Unity, mobile platforms that are almost always connected to the internet, and the rise of free to play development, the demand and creation of third party plugins has risen.
Unity plugins come in a variety of types, and are built to address every possible step in the game development process. Some cover gaps in the Unity feature set, such as UI toolkits. Some exist to improve workflow, such as visual scripting tools. There are packages in the Unity Asset Store that are just full of raw content: 3D models, textures, and shaders. There are plugins to help you integrate third party SDKs, for things like in app purchasing and analytics tools.
The Unity asset store does a great job of emphasising the feature set of these plugins, but provides no information on the performance cost. This is unfortunate, but not an easy problem to solve. Even if a developer were to take the time to measure the increase to build size, the runtime memory costs, and the runtime CPU costs of their plugin, those numbers would be purely in a vacuum, there’s no telling how the plugin would actually interact with your game. It is easy to just look at a list of plugins as if you’re at a buffet, and ask for one of each, and maybe go back for seconds on some like advertisement plugins. This gets out of control quickly, and you will discover that there is actually no more room left in available memory for your game, instead you’ve just created Frankenstein’s Monster out of plugins, lots of parts glued together in something that might resemble a game, but it’s not quite human. The village full of gamers are going to recognize that the thing you created isn’t actually a game, and will be at your door with torches to burn it down.
How can you achieve a balance of using some of these helpful plugins, but still leaving enough runtime memory and CPU time to actually build a game? Build strict budgets, measure the cost of individual plugins, keep a clear understanding of what each plugin does and why you need it, and build a pipeline that lets you disable and remove plugins on low end platforms. Yes, this is going to be a lot of work, but it is the only way to reach that sweet spot of maximizing the number of plugins you can use while still building the best game you can.
The first step is budgeting. This does not happen at smaller developers too often, and even professional developers tend to start slipping on this step. The two primary budgets you need to build are runtime memory during gameplay and app download size. Depending on the design of your game, you might want to build memory budgets for other moments, such as menu flow. Many disciplines contributing to the game are going to want as much memory and app space as possible. Your sound engineers are going to want the best quality audio they can get, and will want a variety of audio. Your environment artists are going to want high resolution textures for their backgrounds. The animation team is not going to want to spend time tweaking compression settings to shrink the size of their animations. Once you implement a plugin, it is going to be difficult to convince management that you need to remove it from your game if you want that memory back. If you are in the full swing of production and have not made a budget, you will quickly find that you are no longer an engineer, you are now a diplomat, arranging trade agreements between the nations of game development. You will go to the environment artists and ask them if they can give you any runtime memory back, all of their 1024×1024 textures are just so big. They will respond that “It’s been like that in the game for months no problem! Why don’t you go ask someone else! I bet it’s the audio engineers eating up all the memory!” After a week of back and forth, begging in people’s offices, you might be able to arrange a trade: the environment artists will drop textures to 512×512 on even numbered levels, and the sound team will make the audio mono on odd numbered levels. No one is happy with this. Also, this isn’t even a realistic solution, what you will usually end up with is 512×512 and mono on all levels.
Hopefully I’ve scared you into wanting to actually make a budget, but how do you begin? First, you need to figure out what your memory target actually is. On modern platforms, memory is shared between many apps running. I covered some information on targeting platforms and memory available on iOS here: https://josephstankowicz.wordpress.com/2013/06/04/ios-device-consideration/. Even if you are only targeting iOS for release, you are still making a multiplatform game, and will have to make a set of budgets for each memory level of devices. Because of this range of devices, you will want to figure out what your flexible, and fixed memory costs are. You can always use lower resolution textures on lower end devices, which makes texture usage fairly flexible. The memory overhead of the Unity engine is very static, as well as memory used by your C# code. You are still going to have to do some diplomatic negotiation at this point, to work with content contributors to lock down their limits. UI artists, animators, environment artists, audio engineers, and whoever is asking you to implement plugins are all going to ask for more more more, and you are going to have to work to keep people as happy as possible, while still making a game that can actually run on your target devices.
At this point, you have somehow made a budget, and have not realized a budget is useless if you have no way to measure and audit everyone’s memory usage. Spending engineering time to build performance measuring tools is vital to making a game intended to push the limits of iOS hardware with Unity. With game content this is a bit of a time consuming endeavour, but not very difficult. Unity provides some useful functionality, like the ability to get the memory size of an asset at runtime in development builds http://docs.unity3d.com/Documentation/ScriptReference/Profiler.GetRuntimeMemorySize.html. Using functionality like this, you can measure the size of the content in your game at runtime, and compare that information against your budgets to make sure each discipline staying within the boundaries you gave them. It might take some time pasting this data into a spreadsheet and sorting it, but it will keep your game under control.
Unfortunately, tracking and managing memory of third party plugins is not as easy. These third party plugins are usually black boxes, and you have no control over their memory and other costs. Sometimes, you’ll be lucky and there will be configuration options, such as disabling videos for an ad service on lower end platforms. The easiest way to get an idea of the costs of a plugin is to find someone else who has already measured it. Maybe it’s another person within your company, or maybe you just have to post online and ask people. You probably will not be so lucky, so the next way to find the cost of a plugin is to profile your game before and after integrating the plugin. You might be able to do this in an empty Unity project, or you might need to do this within your game. Now you know the memory cost of that plugin, and can keep it if it fits, or drop it if it doesn’t! Or what will more likely happen is your producer will tell you the new plugin needs to be put into the game, and you need to get that memory back. If you did not actually build any budgets, you now get to go beg between disciplines asking for people to reduce memory usage to get that back, or begging your producer to let you remove a different plugin. If you did build a budget, you have much more leverage here, and can try and hold people to it, share it with your producer and explain that all memory is already accounted for, and work with your team to juggle memory around to fit the new plugin, such as removing a different plugin to make room for the new one.
This brings you to the biggest problem with using third party plugins: removal. The ideal Unity plugin would feature some sort of on/off switch, and when off would behave as if it was not in your game in any way. I don’t think I have ever seen a plugin that was even close to this ideal. Every Unity plugin that we have tried removing / disabling has been a time consuming endeavour, and we were often still finding files related to plugins we had removed over a year after the initial removals. You might think that you’re a clever engineer, you will just build a custom wrapper for every plugin you integrate, to provide an easy on/off point, so you don’t have to search through your codebase for calls to the function. Very few plugins are simple enough to wrap up like this. Many plugin developers are going to make use of the power of Unity, and the plugins will come with custom components and editor scripts. This will provide many points of entry to a plugin, and a first attempt at a wrapper might end up just as complicated as the plugin was in the first place. Keeping this information in mind can help you build a partial wrapper, to at least ease the process of removing a plugin a little bit. Properly documenting how the plugin is implemented in the first place, what all the pieces and files are, and how they fit together is going to be your best tool for plugin removal later. You will also want to let your producers and managers know that removing plugins is going to be a lengthy task, and why. Letting people know this ahead of time helps keep schedules manageable, you don’t want to surprise people when they assume that removing the plugin will be a quick task, only to be waiting on you for a week or longer.
The conclusion you might jump to after that is “I will never remove a plugin then. What I put into the game will be what I ship with. If I want to switch ad services or something, I will do that between projects.” Unfortunately there are many valid reasons to remove plugins during game development. The biggest one is Apple’s constantly changing requirements and recommendations for iOS development. You might have a plugin you have shipped multiple games with, and find out that the features of the plugin are no longer allowed under Apple’s latest iOS development rules. You’ll find out that not only can you not ship a new game with that plugin, but you will have to go back and update all of your previous releases to remove the plugin, or they will be removed from the app store. Another big cause of removal you probably have never dealt with if you have never used third party tools before, is factors related to the third party company, or your company’s relationship with them. A big cause of these problems is the plugin or SDK provider getting bought out, or going out of business. OpenFeint did not last long after Gree bought it a few years ago, and once Gree shut down OpenFeint, you could not release a game with OpenFeint, forcing you to remove the plugin before you can ship your game. Another thing to note you might not realize is many of the third party plugins are written by a third party from the SDK the plugin is wrapped around, so you need to keep up with both the status of the SDK, as well as the plugin. This becomes a problem if the SDK requires an update, to ship a game, but the plugin developer is either too slow to update to the latest SDK, or not able to update.
Hopefully that is enough information to make your game development life working with plugins easier, and under control.