Efficiency in Complex Mobile User Interfaces

In freemium games, presentation is everything. The game itself can almost seem secondary to all the screens these games need. Your typical game has a couple menu screens for adjusting options, a main Heads Up Display that stays (fairly) consistent during your game, and that’s about it.

But this article is for the games that have an inventory to manage, a store to buy stuff from at any time, ‘on sale’ offers, custom game modes. And this isn’t limited to freemium either! We will be discussing in terms of the Unity3d game engine, most of the underlying concepts apply to any game engine, including home grown.

I’ve had some experience with this, where I learned someone else’s system. And this, where I built my own. Two, in fact, since there was a major redesign just before release. Oh, and this too. I’ve been designing and implementing user interfaces for games on desktop for twenty years, and since the original iPhone.

Users are fickle. This is not a bad thing – it is purely a thought to keep in mind. You might have a great game with thousands of players but scratch your head why nobody is willing to pay money in it. What is often overlooked is how easy or hard it is for the player to pay you! The player does not have a mental tally in their head about whether they want to pay you. It is emotional, not logical. They don’t keep a list of bullet points in their head: “Is this game snappy? Does it act the way I expect it to? Is it leaving a small memory footprint so I’m not looking at a loading screen after I get off this phonecall?”

Players just have a feeling that this is a “good game”. Your job as a developer is to lower the “barriers” between players and the game. But I didn’t come here to tell you how to design a freemium UI. I came here to keep you from tearing your hair out after realizing what not to do.

In games, user interfaces are typically an afterthought. “Check out this great game!” Press “New Game”, and you’re off. The typical coding style behind most game interfaces reflect this. You start with a single “New Game” button. Then you add an options menu. Now add the player’s bought gold on every screen. Oh, and we want to be able to buy stuff with that gold. Wait, how do we get the gold? Another store area! Pretty soon, you’ve got this gigantic, complicated code that reflects a gigantic, complicated user interface. But there is a better way!

We can instead borrow from the kind of thought that has gone into decades of desktop application user interface design. And the neat thing is, it boils down pretty simply, you need only to keep a few rules in mind while writing your code.

Just the basics, Ma’am

The first thing to remember is to make separate chunks out of what you present to the user. If you’re showing a counter of how much gold the player has, you should be using the same visual language onscreen in every location. Otherwise the player will get lost, looking for it! Likewise, you should use the same code to display it in every location. The shift in code organization is subtle but important. Instead of a screen manager class saying “set this text to the player’s gold count”, you should instead have a consistent block of UI that knows how to set its own gold count when it is given a player record. Why does this matter? Because two weeks later when you decide you want to show the count in red, but only when the player is out of money, you need to change it only in one place – the code for that block of UI. Not all over your codebase.

Inconsistent Visual Language

Simple and Easy

Another often made mistake is to make each block of UI know how to find the ‘source of truth’, typically requesting values from a singleton. Because you’re always going to have just one player, right? Then the boss says “Social gaming is the big thing now. We want to see them on a leaderboard with their details.” Well guess what – you have to rework all the places that use an internal ‘source of truth’ to be able to use an external one. More time wasted and complications created.

Now to consider the next level up. We have these chunks of interface. In the desktop world, you can fairly easily classify each application’s display based on what will be shown in it. A typical application has only one “window” for each document, and then “dialog windows” for asking more detailed questions, when needed. If you consider your game as a “document,” then you will only have one “window.” This means that your settings screen is actually a “dialog window”. Like a desktop dialog, the settings ask more detailed questions, eventually to close and put you back on your main “document,” the game.

This seems simple enough on the surface. Until it’s not. What do you do when the boss says “we want to offer a sale after playing for five minutes.” Who knows where the player might be at that point. They could be in the main game. Or the leaderboard. Or the store. Then I have to save what screen I was on before I showed the sale, and return to it when I’m done. Oh, and then I have to tell that to the store screen where to go back to after it finishes the sale. Sure hope I made these all some consistent superclass so I don’t have to know how to reopen each and every screen. How do we make the boss happy, and not go crazy working out where to put the player after they “close” the sale display?

The Navigation Stack

It sounds complicated, but this is where desktop UIs have solved it for us. It’s called a navigation stack. Every new screen is a new entry on top of the stack. In the desktop world, when you close one dialog, it re-shows the last item that was hidden when you opened the new one. You don’t even have to think about what it was you hid, you just “go back.” A simple concept, easy to implement, and saves you loads of trouble. In fact, on Android devices there is a requirement that you must always support the hardware “back” button. If you have a navigation stack, you always know exactly what you’re going “back” to.

In this day and age, everyone wants everything “now.” It amuses me to remember back when I started that computers were advertising “no wait states”. That is, they will go so fast that you will never have to wait for your computer ever again. So many years later and we’re still waiting.

Unfortunately, most user interfaces still presume everything happens instantly. In reality, loading takes time. And even if it is truly instant, animations by definition take time. Those little flourishes which bring life to your game have a habit of moving pieces of your interface to unexpected places when you presume things are ready instantly. Take that navigation stack for example. You start loading your settings screen, and at that moment it’s time to display an offer for the “Newest stupendest game piece that gives you 50% extra damage!” But you don’t want to show players offers while on the settings screen, you don’t want to be that intrusive. So what actually happens is both screens load and try to show themselves at the same time! Worse, who do we go “back” to?

There is another easy solution to this. When making changes, like showing a new screen or closing the one you’re on – make those changes instant. But wait, I just said nothing is instant?! Make your navigation stack instant by having the stack entries be completely separate from the actual onscreen displays. This way you can ‘instantly’ show a new screen and make reasonable logic decisions, no matter how long it takes to actually load or animate that new screen for the player. (For those of you playing at home, this makes the stack entries behave like “models” of the MVC pattern.)

Here we are going to put some pieces together and get an unexpected but highly useful result. You wanted that consistent “player gold” display on most of the screens of your game, right? Well, we don’t need every screen to have a copy of that, do we? Just leave it up for the next screen. But then how do we know the next screen wants it or not? Guess what – the navigation stack entry for the new screen knows. The new navigation stack entry has already been added because it is instant; it knows that it has to start loading and animating a new screen, and it knows if it needs the player gold displayed. So while one is animating in, it can animate away the piece it doesn’t need. The whole thing looks slick and smooth to the player, like you meant it that way.

Same Dog, New Tricks

You’ve made it this far. How about one more trick up the sleeve? There are always special cases in user interfaces. An example: a dialog offers a reward for connecting the game to a social media provider. If the player accepts, you want to take them to your normal screen that actually does the connecting. Okay, fairly obvious. But we really want to drive the idea home by flashing the buttons that actually do the connection, and only when it comes from this reward dialog.

One implementation would have the buttons look on the navigation stack to see if that reward offer was on the stack, and flash the buttons when it sees that. Fair – it would work. But then the connect dialog would need changes to know the offer dialog exists, and then embed custom animations that have nothing to do with the core purpose of the dialog, complicating later improvements.

But what if… each navigation entry could accept a list of commands to run after the dialog loads? Now the offer dialog pushes the connect dialog on the stack, and the registers a command for when the dialog is done loading and animating into view. Once hit, the offer dialog finds the buttons in the UI by searching for a special tagged object, and adds the flashing animation to those tags. With that, the connect dialog doesn’t need to know anything more about the offer dialog other than a simple string to let designers know that the offer dialog does some custom stuff, and needs to be considered when making changes.

There is so much that can be done to make your life easier when building your games. Even in the simplest ones, adhering to these guidelines will save you untold headaches in the future.