Using Code Architecture to Build Reusable Prototypes
February 11, 2019 | 9 minute read
Games, and especially mobile games, are a hit-driven business — the faster you can get a game out there and test it, the faster you know if it will be successful or not. If your game turns out not to be successful, well, at least you didn’t waste a lot of time coming to that realization. At Kolibri Games, we develop our games following exactly that approach. When developing a new game, we try to build a “minimum viable product” (MVP), which is a broken-down version of the game, reduced to core mechanics, as fast and as cheap as possible. We set up a small task force (one product manager, one engineer, a game designer, an artist, and a QA tester) and give them eight weeks to brainstorm, find core gameplay mechanics and develop a first playable version.
How do you even make a game in such a short amount of time? By saying “NO” to a lot of things. Like all game makers, we come up with plenty of amazing ideas for our game during development. If we were to pursue all of them our “viable product” wouldn’t really be “minimal” anymore, which means that we have to constantly remind ourselves to only focus on what’s necessary for finishing the MVP as quickly as possible.
Development of Idle Factory Tycoon, starting with an MVP
After the eight-week development phase, we soft-launch that first MVP, focusing entirely on Day 1 retention (the percentage of players that return to the game the next day). There is barely any late-game content — all we are doing is trying to figure out if players are going to return to our game. We are also leaving out all the other fun stuff: no social features, no monetization with, for example, IAPs and no Cloud Save. Additionally, we pay attention to the number of organic downloads, user experience and feedback. After all, we want to create games that players are looking for and for which there is a demand on the market.
MVPs — a life or death decision
After that initial soft-launch testing period, we gather all the numbers and make a life or death decision: We decide if we want to further develop the game, or discontinue it. Here, we base our decision entirely on whether we are able to increase Day 1 retention with little effort. If we deem it possible, we expand the team, add new features to the game that we had to say “NO” to at first, and do user acquisition (short for “UA”, which simply means gaining new users). With both Idle Miner Tycoon and Idle Factory Tycoon, we reached a Day 1 retention of 75 percent — three out of four players liked our games so much, that they came back the next day. Those numbers made us choose “life” over “death” and we have been developing and improving both games ever since.
Start your engines!
On the technical side of things, this approach to development is quite a challenge: not only does the first playable version have to be available after eight weeks, but it has to be built in a way that allows for future iterations. Like many other gaming companies, we use the game engine Unity to make this process a little easier for us. Unity helps us to build that MVP in a short amount of time: development is fast and easy, games can be ported to almost all platforms, and the asset store and other third-party services save weeks of work. In addition, other built-in services, such as Unit Testing, analytics and performance reporting make the life of every developer much easier. However, the one thing that allows for successful implementation of this approach to development, is following a code architecture. Architecture in code will help to write code with better quality, to maintain a product with fewer bugs, and to write independent features that are easy to iterate on and easy to test. The architectural framework we use at Kolibri Games is called “Model View Controller” (MVC) — an easy architecture that allows us to completely separate our logic from our engine Unity. Our models contain the business logic and our data and are both written in plain C#. Our controller handles some of the view logic and navigation, likewise in C#. Our view is the MonoBehavior that is attached to a prefab (a pre-configured game object), which is our only point of contact with Unity. Adhering to this architecture, a typical workflow will look like this: A controller is reading the model, taking that data and updating the view. At some point, the user will give input and interact with the view. The input gets sent to the controller, which takes that input, modifies it and, in turn, uses it to update the model.
An overview of our code architecture, Model View Controller.
In addition to simply producing cleaner code, MVC helps with development in a number of ways. Unit Tests, which usually take a lot of effort when done on MonoBehaviors, as it requires them to be located in a scene, attached to a game object, become much easier: With our architecture, we can substitute the Unity component, or the view in this case, with a “fake view”. Like that, our Unit Tests can run in plain C# and be executed on the server and everywhere else.
How MVC helps us with Unit Tests.
Further, when scaling up a project and working on it with multiple people, modularity becomes increasingly important and MVC helps us to implement it — by keeping all of our systems as isolated as possible, we ensure that multiple people can work on different parts of a feature or different features at the same time. In Unity, we enable modularity by starting with an empty scene in which we create all models, controllers and views in C#. Only one person can work on a single scene at a time, which is why we don’t collect multiple features in one scene. Just like prefabs, they can’t be merged with source control, so keeping prefabs as small and granular as possible is key. Prototypes — they are a great quick fix and often discarded after they have fulfilled their function. However, at Kolibri Games, we build MVPs that are tested and scaled up, and our MVC approach helps us with that. For a simple prototype, you take a scene, throw in a game object and attach a bunch of MonoBehaviors to it. Each game object here has its own start method, their update loops and whenever you want to access another system, you simply go for the dirty “gameObject.findobjectsoftype” move. While this approach is totally fine and appropriate at game jams, it’s completely unsuitable for our professional work processes, where we are looking to continuously improve a first version instead of throwing it away. Eventually, prototypes are less testable, have less quality in code, are less changeable and take longer to iterate on. Although prototyping is super fast in the early stages, MVC enables us to sustain a constant speed later on when improving and developing our games. Even though it is quite contested, and outright refused by many, lean development with MVPs has allowed us to ship updates to our games on an almost weekly basis, keeping what worked well and improving what didn’t. We have created and maintained games that our players love for about three years now, and are confident that our approach will allow us to do so many years from now.
Interested in working in our Product or Technology team?