Tuesday, April 27, 2010

Game 101: Menus

I talked with a buddy and we lamented that most newbies to game dev seem to make the same mistake as other newbies did. If you are a newbie, and want to avoid the mistakes your ancestral newbie brethren made, I hope this series will help.

This is just my opinion, based on my experience, and I am not a god-king of game dev. Take it with a grain of salt, and read the comments (if there are any) for other opinions.

SO!

This is an article on a basic part of game design/programming that's often overlooked: the menu.


...

Every time I go to XBLA, I see the indie games. I look at their screenshots. Invariably, the screenshots include at least one image (frequently two or three - out of five!) of their menus.

I think this is because a young developer completes the menus and says, "hey, that was hard! But now it's a real game, not just a toy! I'm so proud of my menus!"

So, here's some advice: your menus are not important. Or, rather, they are important in the same way that a house's structural beams are important. They need to be there, but nobody really cares. A few games (like Riddick) have very flashy menus, but they don't make the game any better and are essentially programmer wank to give the coders something fun to do when chasing down the damn rendering bug has finally gotten to them.

Because menus are both fundamental and somewhat difficult for beginners, I thought I would share some basic advice for how to get it done.

Zeroeth, before anything, I need to make it clear: your menus and your gameplay screens need to play nice. I generally make them the same top-level class and control them in a predictable manner from the main game object. Trying to hammer menus in when you've created your entire code base to blitz right to the gameplay makes your life harder than it needs to be. If you start right up front understanding that menus and gameplay will be trading off control, you can save yourself a load of pain.

Okay, next and first I'm going to cover the basics of menu design. Later I'll cover the basics of menu programming.

Menu design is something that most games do fine, but sometimes you'll stumble across a game - even an AAA game - that does menu design poorly.

The first thing to consider when making your menus are the outside requirements you must adhere to. Most indie devs probably don't have any outside requirements, but sometimes you'll run into something like "in order to be published on the XBox, you have to do X and Y in the menu, and always default to 'no', etc, etc". If you do have these sorts of restrictions, make sure that you take them to heart, even if they are sub-par. In this case, being uniformly sub-par is much preferable to being erratic.

With that said, the actual contents of your menu will depend mostly on your game. Don't feel the need to stick everything on one screen: generally, you want between 5 and 10 options on an "options" screen, 3-6 on a non-"options" screen such as the main screen. Save menus, stat-level-up screens, and score screens are their own special cases, since they have loads of nearly identical elements and only a few real "menu" choices. Anyway, if you need more options than you can really fit without crowding, think about splitting the screen into two or more tabbed/scrolled screens.

Modern games are split between the older "change, then save/cancel" style and the newer "save instantly when you change" style. Personally, I think the save/cancel style is obsolete, and I think you should change the options the instant that they actually change, or as soon as that option loses focus, if the change takes a moment to propagate.

Including a "reset" button is generally a good idea, as is a dedicated "back/exit" button. I don't think I've ever used a reset button, but like the high-priced menu item at a restaurant, it makes all the other things the player could experiment with seem reasonable. So have one.

Even if your game is completely simple, you should save your options settings to a file so they remain true between plays. It's surprising how irritating it is to have to change the settings every time you start the game up. Similarly, even if your game is dead simple, you should have some options to set. Volume, at the very least. Only the most primitive games don't have options menus, and that's only fine if that's what you're aiming for.

When it comes to flashy layouts, the basic answer is "don't". You can theoretically get away with very flashy menus, but in practice it's much too much work for much too little return. Keep your menus simple: menu name on the upper left, game logo on the upper right, menu options striped down in a column, back/exit on the lower left, reset on the lower right. This works for 99.9999% of all indie games.

You may, of course, have a background image that makes it look slick. If you're really feeling your oats, you might have that vertical column of options drift slightly, but keep it a column. The days of fifty options spattered at random across the screen are over.

I hope.

Your main game menu is an exception in two ways. First, it generally doesn't have the menu name, back, or reset: it's normally a single column with the last option being "exit". Second, it can be quite artsy-fartsy if you like. I don't recommend it, but you can use a radial layout, or dodgy positioning, or even scrolling-fading choices. This is all fluff, but it can be worthwhile if you want to make an impression. Just don't do that in the various sub-menus! Keep anything that actually involves complex options or choices as clear as possible. Either way, never include screenshots of your menu as ad copy.

As you develop your menu, you may find you need really complicated menus. For example, if you're building an RPG, you may have to have fifteen stats, ten skills, a portrait, an equip-dummy, an inventory, etc, etc, etc.

Your maximum complexity is going to depend on you. With an in-game menu that the player will access a lot, you can be more complex because it's more important that the data be right there rather than hidden behind a click. On the other hand, even then too much complexity is a bad thing.

Depending on the nature of the game, I frequently use multiple, dockable menu windows instead of a single, really complex one. For example, my equip dummy and my inventory wouldn't usually be a single window: they would be two distinct windows that happen to be up at the same time.

It's really surprising how much easier this makes things. If each dockable menu is "simple", you can create very complex but easy-to-program and easy-to-use interfaces by combining these simpler modules.

...

Second is the actual programming. There are loads of ways to do menu programming, and if you're using middleware that has built-in menu support, this next part won't matter to you. Just do it like your middleware says to: there's absolutely no reason to reprogram the wheel.

If you aren't provided with a decent set of menu tools, it's relatively easy to make your own. I generally make a set of menu libraries for every language I program in. Because menus just have to be functional, not awesome, you can re-use even poorly programmed menu libraries.

If you search on line you may be able to find a menu library for your language. You can also make one yourself. Generally, I do the latter, and here's the technical structure I use:

I make a main game object that wrangles all the rendering and IO. Usually this already exists, and you can just inherit from whatever the object is, or make your own and simply reference it from the existing main object.

The main game object contains a stack of "screen" objects. Depending on the situation and the language, this might be a simple array, or it might be a few explicit members and you have special code for each. Either way, some of those screen objects can be menus, some might be your game screens where the play really happens. The main game object then updates, paints, and sends control objects to those screens: the active screen gets the normal update, paint, and control, while the secondary (but still existing) screens get a special brand that keeps them visible but usually grayed out and frozen.

Remember to paint in the right order: most languages will paint in front, so you have to paint from the rearmost passive screen up to the foremost menu/game screen. If you are using a mixed 2D/3D system, this can get pretty messy, so be careful to understand how, say, a SpriteBatch will screw up a 3D GraphicsDevice.

Each screen has events it can fire, and the game object can catch these events and interpret them. This allows the game object to get rid of a menu screen and create a new active screen, take actions based on your selections, etc. Generally, I have an "empty" event that simply passes the screen object when it fires, and I also have a generic string event that passes the screen object and a string. The former I use for clearing away a screen, the latter for making a selection on it. You may also need one that contains a number as well, for things like changing the volume or the difficulty.

Nearly every language supports an event-driven system like this, and it makes extensibility very very easy. For example, we can easily create a member for the screen class that contains a screen object. Instead of making the main game object control every screen, we can have custom overlays for each screen. This is very handy if you have special menus, huds, or maps that pop up on top of a game screen and depend heavily on the game screen's information.

The fact that the screens are "agnostic", just firing events into space, means that it's also easy to rearrange them. I frequently have very different menu layouts between development, demo, debug, and the rare "release" menu layout.

If your game has complex menuing, such as an RPG, you'll probably need draggable, dockable menus. Some engines have a dockable window system built in, but if you need to make one on your own, it's not actually very hard: there are dozens of tutorials for any language. Just be aware you may need to do it.

If you're using an XBox controller, the player may not really be able to drag your dockable windows. Use them anyway. You can manually place them using your code, and it'll be a lot easier than hard-coding complex, monolithic menus.

Actually rendering the menu text shouldn't be terribly difficult for you, but it is generally better if your menu screen class has an array of options that you can arbitrarily add to, instead of painstakingly scripted line-by-line menu placement. The menu screen should understand how to navigate through them, highlight the one you're on, and throw an event if you select one. You may want to make your line-by-line menu items small classes that render themselves, so that it's easy to do radio buttons, sliders, etc. Often, your development environment will include such items already: no reason to make your own!

This is all very basic, but it's hard to know how basic is basic enough, so there it is. Post additional advice or feedback to the comments.

2 comments:

Isaac said...

I always love things like this that make me reexamine my blind spots. While I whole-heartedly agree that getting menus right is important, I haven't had the experience to cover all the ground you went over here. So, thanks.

Craig Perko said...

Well, in the unlikely event it actually gets read by any significant number of people, I expect the comments mostly to be about how crappy my suggestions are. So keep in mind there are probably better ways to do all this, this is just my way, and it works pretty well.