Game Design
From MobileDesign
The design of games is different than the design of productivity or information applications. Non-game applications are focused on efficiency; games are focused on enjoyment.
Despite this, portions of a game application should be efficient; phones and PDAs are not game platforms and play time will frequently be very short. A user might be sneaking a play as a break from work, or perhaps engaging in a long session of play while waiting in line. Further, game play may be furtive.
Contents |
[edit] Architecture and Navigation
The heart of any game is, of course, the game screen. But several other screens are necessary to make any game fully functional. These supplemental screens do not add a lot to the game experience, but they can detract from it.
|
Note that, except where noted otherwise, commands labeled “Done” and “Save”, as well as the highest priority command of type BACK, should all move the user back one screen. The suggested game architecture will certainly be unpopular with some developers. After all, it says that the main menu, and most other screens, should be implemented with high-level components rather than a cool, branded, Canvas. However, users will be quite accustomed to using high-level components, and they can start using your game without having to learn how to use the Main Menu (or high scores, etc.). Further, as this suggested architecture is commonly recommended by carriers and device manufacturers, it is implemented by a large number of existing games. As most games are used fewer than 5 times per user, users won't take the time to learn your special main menu or architecture. Save your creativity for the play of the game itself.
[edit] Screens
This section details each of the screens illustrated above. While your Game Screen may actually be several screens, you will likely need each of the other screens in the form described below.
[edit] Splash Screen
The splash screen is used to brand your application and start the user experience. However, please recall that users can not leave the game running all the time (they need to use their device for other purposes, such as communication) and thus will re-start the game frequently. Further, users are likely to only use the game for a few minutes, and applications are likely to take a while to load. In general, be conservative with your splash screen.
- Respect the user's sound settings upon game launch. If the user has turned off sound in the past, don't play sounds here. Please see the section on Sounds (page 109) for details. Users may be trying to be discrete.
- All key events, except the “End” key, should dismiss the splash screen. One way to implement this is to define a keyPressed method that performs the same thing for any keyCode. Don’t forget to cancel the timer as part of this method.
- Dismiss the splash screen after 3-5 seconds. Users may not think to manually dismiss the screen, and the screen should not unduly delay access to the game play.
- Implement the splash screen as a Canvas. This isn't strictly necessary but it is standard practice and enables brand recognition. It also gives the user confirmation that the correct application was selected from the device's application menu.
- Include application version information. This allows your support staff to troubleshoot, if necessary.
[edit] Main Menu
After the splash screen is dismissed, the main menu appears. While this is the “main screen” of the game, it is not where the user intends to spend any time. The main menu is the launching point of your application.
- Your game’s name should be the title of the Main Menu. If the user has ignored the launching sequence, this will give feedback as to which game is being played.
- Contents of the Main Menu should be as follows:
- “New Game” or “Play Game” – the user can simply press the OK (or similar) button to launch game play.
- “Instructions” – if your application does not display instructions upon each game launch, the second item on the Main Menu should be Instructions. Avoid the term “Help”, as users may believe it to refer to game play hints.
- “Options” – if there is only one or two options items, substitute controls directly. See “Options Screen” for details.
- “High Scores” – if appropriate for the game, the High Scores list should be accessible from the Main Menu.
- “About” – displays information about the game. Re-displaying the Splash Screen is appropriate.
If your game naturally requires additional items, such as selecting from two different versions of the game, these items likely go before Instructions.
- Add “Quit” as an abstract command to the Main Menu. This should be a low-priority command of type EXIT.
- Do not add background graphics. This makes your screen less readable.
- Left-justify text. It’s easier to read, matches users’ expectations, and allows the user to quickly scan the items.
[edit] Options Screen
While every game can have different options, most have at least volume settings. This section assumes that you have few options the user can choose; if you have more than can comfortably be controlled from a single screen, implement the Options Screen as an Implicit List leading to smaller Forms or Lists.
- Save and use the user’s previous settings upon launching the game. If the user didn’t want anybody knowing the game was launching a few minutes ago, he likely doesn’t want anybody knowing it now.
- Implement the Options Screen as a Form.
- The primary abstract command should be “Save”. This saves changes and returns the user to the previous screen.
- The secondary abstract command should be “Volume.” This will call the device’s volume control screen. Be sure to set a flag indicating the volume was changed so you can prompt the user to change it back. Note: when incorporating options into the Main Menu, include Volume there as the second softkey.
- Include a low-priority abstract command labeled “Quit.” This should be a low-priority command of type EXIT.
- Include an abstract command of type BACK labeled “Back.” This should cancel any changes the user has made and return the user to the previous screen.
- Control sound settings as a single-choice group (radio buttons). Label the group “Sound Settings” and have items “Sound + Vibrate,” “Vibrate,” and “None,” each on their own line. Alternatively, use sound “on” and “off.”
- Include other settings as single- or multiple-choice groups, as appropriate. You may have no other settings.
- Left-justify text. It’s easier to read, matches users’ expectations, and allows the user to quickly scan the items.
[edit] Miscellaneous Screens
Your game will have a variety of “service” screens, including About, Help, and High Score screens. These are screens that the user will not spend a lot of time on, and should not take a lot of processing power, memory, or user knowledge. For example, many developers use a Canvas for a High Scores screen, continuing the experience of the game onto the screen just like older arcade games. Unfortunately, these screens are generally afterthoughts in game design, and they end up not working (if the developer has not used careful multiple-device design) or hard to use because text entry is not obvious or fonts or graphics make the screen difficult to read. Here are suggestions:
- Use high-level screen types for About, Help, and High Scores screens. The appropriate screen might be a Form or Alert.
- Left-justify text. It’s easier to read and matches users’ expectations.
- Use abstract commands, not key codes, to solicit user input if using a Canvas. If your screen looks like a high-level screen, it should act like one.
- Define the highest priority SCREEN command as DONE, sending the user to the Game Screen or Main Menu, as appropriate. . Users will understand that this clears the screen and returns to a default state. Exception: The High Scores screen will always return to the Main Menu.
- Include a low-priority abstract command labeled “Quit.” This should be a low-priority command of type EXIT.
- Define secondary actions with lower priority. For example, there might be an option to “Erase” high scores or see “More” instructions.
- Indicate what the game action A, B, C, and D buttons do. Use the method getKeyName(int keyCode) to determine what the device’s name for a button is.
Arcade games historically use the high score screen as an opportunity to have game-related graphics in the background. What was appropriate for arcade games is not as appropriate for mobile devices. After all, the high score screen won’t be used as a screen saver or to attract users to the application. We therefore have some simple recommendations for the High Scores screen.
- If the user has earned a high score, use a TextBox to enter name or initials. Add an abstract command labeled “Save” to complete the entry.
- Save user's name or initials for the next earned high score. Requiring extra text entry is unnecessary.
- Add a low priority abstract command to clear scores, labeled “Erase.” Ideally, the label would say “Clear Scores,” but as the command will likely be rendered on the softkey, this is not appropriate.
- Consider integrating the device’s high scores with network-based high scores. To do this, you must give the user access to the network scores using an additional abstract command, and you may also want to indicate where in the global standings the top scores rank.
[edit] Game Screen
Of all the screens, the Game Screen (or screens) is the most likely to be implemented as a GameCanvas, and the recommendations in the chapter on Canvas Screens apply.
- Provide a one-touch method for pausing the game. This could be a high-priority command labeled “Pause”. A better design would be to have a single softkey on the Game Screen to access all non-critical game controls, with the command labeled “Menu”.
- Stop all sounds when the game is paused. Users will need to know they can silence the device.
- Implement a game screen with a GameCanvas.
- Provide the ability to control sound and volume from the game screen. Use abstract commands or simply place the sound and volume controls in the Play Menu accessible from the game screen.
- If the user earns a high score, prompt for name or initial entry using a Text Box. Be sure to save the user’s previous entry and display it as the default text. Set the maximum number of characters for the Text Box, as appropriate. The primary abstract command should be “Save” and you should include a title.
- Implement a low-priority BACK command labeled “Back.” This will take the user back to the main page. If desired, display a Form screen asking, “Stop game?” with commands “Stop” and “Play.”
- If the user may progress to another game screen at any time, provide an abstract command to do so. Usually, this command should appear on the second softkey.
- Use an Alert screen to allow the user to progress to the next level. A timed alert would be best. You can provide appropriate graphics for it.
- Draw content to the off-screen buffer before displaying the GameCanvas. The GameCanvas will display an array of white pixels when first displayed until content is drawn to it; this “blank screen” will flicker and could be perceived as indicating a broken application.
- Display the High Scores screen after the play of the game is complete.
- Use full screen (unstructured) mode for the game screen. You may not want to do this if your Ticker provides game status, especially for multi-player games.
[edit] Tiles, Layers, and Sprites
MIDP2 introduced tiles, layers, and sprites to control foreground and background graphics. Now you no longer have to calculate repaint regions and to what to revert the changed region. Sprites are used for things moving across the screen and have collision detection. Tiles are used to build backgrounds by repeating a block of pixels; these can move to animate the background.
A Sprite is a collection of pixels that are drawn on the screen, that can be transformed about a point, have multiple images, an have collision detection. Consider the “BrickBreak” example. The paddle and the ball would be Sprites. The ball would also have collision detection with both the paddle and the bricks. Because all of these have very simple shapes, collision detection would be based on their collision rectangles, not on opaque pixels. Collisions can be detected between Sprites and Images, TiledLayers, and other Sprites, but only when they are visible.
A TiledLayer is intended for backgrounds, and allows you to create an area that is larger than the screen or your defined viewing area on the screen. It contains a grid of tiles, any of which may be animated. In BrickBreak, a separate TiledLayer could contain all the bricks, with all other pixels transparent. Thus pixel-based collision detection could be used.
- Use Sprites and TiledLayers for animation. Do not create your own animation code. The built-in code will run more efficiently and will already be optimized for the device.
- Design your background and any repeating graphics using tiles in a TileLayer. By repeating only a few pixels, the application memory footprint will be much smaller. You can even design several difficulty levels simply by rearranging the same tiles, making the amount of data stored per level quite low.
- Avoid use of pixelLevel = true for collision checking. Checking for collisions based on a simple rectangle will be more efficient than checking each opaque pixel for collision. Of course, for oddly-shaped Sprites that need complex logic based on collision, use pixelLevel = true.
- Do not code your own image rotation code. Use Sprites instead, as they already have image rotation and mirroring built in. This code will run more efficiently and will already be optimized for the device.
- Put game status indicators, such as “level,” outside the viewing area. Reading characters on a background with varying – or even animated – background is difficult. Set your layers such that any tiled layer leaves some space for status information.
- Ensure that your viewing area is no larger than the screen. Unpredictable device behavior may result. Most devices will clip your viewing area to fit the device, but some of your size-relative calculations will not work.
- Do not use getKeyStates() (key latching) for applications with user-controlled panning. With key latching, each game loop sets the button-pressed value back to 0 and the user has to press the button again. Users will get sore thumbs repeatedly pressing a button just to pan across the larger display.
- Keep panning images reasonably small. If your image is large with respect to the display, users are likely to get lost, trying to shine a small spotlight on a large object. Further, remember that panning is annoying, even when the user does not have to control it directly.
[edit] Graphics
One mistake we see repeatedly is developers handling graphics the way they would on a desktop application. Once they’ve decided that the screen will be a certain size, they design all their graphics for it. Unfortunately, the variety of screen sizes can make your game look strange on larger devices, at least if you target your graphics at the smaller devices. Follow these suggestions for portable, usable applications.
- Use PNG or JPEG format for images. Other formats may work, but PNG and JPG formats are the most reliable across all handsets.
- Keep images high-contrast. Recall that your users will be using a wide variety of screen types in a wide variety of conditions, including backlit, full sunlight, and indoor lighting. Subtlety will frequently result in obscurity. High contrast among colors makes it easier for users with color deficits to distinguish everything in the image.
- Do not anti-alias text in images. The resulting image will look blurry on small devices.
- Trim palettes to the minimum appropriate size. Your application will run faster.
- Draw backgrounds and primitives as relative portions of the screen. Do not draw a game board using fixed sizes; it will be larger than some screens and look inappropriately small on others. Use the getHeight() and getWidth() methods of the Graphics class to determine display size. This increases cross-device compatibility.
- Place graphics on the screen at relative, not absolute locations. Distributing graphics across a large screen reduces application awkwardness. Use the getHeight() and getWidth() methods of the Graphics class to determine display size.
- Consider using scaled graphics instead of bitmaps. Different devices have different screen sizes. A bitmap graphic will appear large on some screens and small on others. Scaled graphics will be the same relative size on each device.
Whenever your application needs to redraw a portion of the screen, it calls the repaint method on a particular rectangle. The device does not necessarily redraw immediately. Instead, it collects the repaint requests and the overall rectangle (clip region) they represent. It then calls the paint method of your application.
Some developers experience more reliability and/or precision with bitmaps than with scaled graphics. Like most things, the best choice depends on your game. We just want you to consider your options.
- Repaint as little of the screen as possible. This should minimize flicker and increase perceived application speed. Do not assume that the region used by the most recent repaint request matches the paint request; repaint requests may have been batched.
- Use tiles and sprites to keep repaint management overhead to a minimum.
- For devices that support double buffering, draw primitives to a buffered image, not directly to the screen. Because rendering an image to the screen is faster than drawing primitives, screen updates should render more smoothly. This is especially true for animations. Don’t forget to override the paint() method to draw your image buffer.
Compatibility note: To achieve a fast frame rate on a device without double buffering, one developer recommends drawing just the backgrounds to a buffered image. That is, the background is pre-drawn and blitted first in paint(), then the sprites are blitted directly on top within paint().
- Do not double buffer your Canvas if the device already does so. Implementing double buffering in your application uses more memory and will slow down the overall application. Check the Canvas isDoubleBuffered() method.
[edit] Game Actions
All J2ME MIDP devices will have at least the equivalent of the DTMF keypad, namely 0-9, * and #. MIDP devices also have "Game Actions", abstract controls for UP, DOWN, LEFT, RIGHT, FIRE, GAME A, GAME B, GAME C, and GAME D. The PalmOS MIDP implementation requires the user to display a virtual keypad for access to 0-9, *, and #. Additionally, you may use device-specific keys in your application.
- Build application logic based on getGameAction(int keyCode), not getKeyCode(int gameAction). The MIDP specification only allows for the getKeyCode(int gameAction) method to return one key code, even if the game action is mapped to more than one button. If the user uses another valid key than the one returned in the method, your application won’t work.
- Use game actions whenever possible. They’re most likely to work with future devices that may not have DTMF keys.
- Avoid game actions in games that require fast reactions. The buttons mapped may not be readily accessible.
- Use logical game actions. That is, the user should use a “fire” game action to fire a weapon or perform the most likely action, and an “up” game action to move up. Your game will be more likely to be compatible with future devices.
- Avoid mixing key codes and game actions A, B, C, D in the same screen. It’s possible that some game actions will be mapped to the same keys as the key codes, making some part of your game uncontrollable.
- Provide a help screen indicating what the game action A, B, C, and D buttons do. Use the method getKeyName(int keyCode) to determine what the device’s name for a button is. Note that this method works better on some phones than others, and not all phones return the same value for the same button.
[edit] Key Input
Your game may require controls beyond what the game actions can provide. The only other standard buttons available are the DTMF keys (0-9, *, #), which may or may not be in the standard layout. However, add-on game controllers may not have the DTMF keys available, so realize that your use of DTMF keys may not allow users to use these extra devices.
- Use extreme caution when relying on keys to have a specific spatial relationship. Some device manufacturers have chosen to abandon the traditional 4-row by 3-column design of keypads. If you want a “move up and right” control, the 3 key would be appropriate on most phones, but the 3 button is on the left on the Nokia 3650! You can see the 3650 in Figure 8 on page 84.
- Document your use of DTMF keys for the user. This makes it much easier for the user to figure out how to play your game. Example: if you have a card game where each pile has a DTMF key assigned to it, then label each pile with the appropriate number or symbol.
- Design your game to accommodate simultaneous keypresses.
- Ensure your target devices support simultaneous keypresses if your game requires them. This is an optional part of the MIDP 2 implementation.
- If you can not use game actions, use DTMF keys spatially if appropriate. This will vary across application. Examples include:
- Diagonal movement. If your application requires movement northwest as well as (or in addition to) north, use the “outside” DTMF keys (1, 2, 3, etc.) to move northwest, north, northeast, etc. Do not mix this type of movement with game action movement.
- Multiple sideways actions. A fight game might require both “block left” and “hit left,” or perhaps “block left high,” and “block left low.” In this case, use the left three keys (1, 4, 7) to use the left actions and the right keys to perform right actions. Use the spatially higher numbers (1, 3) to perform “high” actions (e.g., punching instead of kicking), and the spatially lower numbers (7, 9) to perform “low” actions.
- Generally, use the buttons closest to the screen. It might make sense for your game to use the corner buttons (*, #) for rapid actions, but do so with care. In normal use, the user’s attention is on the upper buttons, which are typically up/down. of the phone has the user’s attention on the upper buttons such as up/down.Further, some phones, such as the Nokia 3650, will not have the expected spacial arrangement.
There are several other buttons available on various phones, although the buttons are not standard and do not return standard key codes. The best way to use these is to ask the user to define what buttons are used for:
- Consider allowing the user to define keys for specific actions. This is a cheap way around the device detection problem, and allows users to use the buttons that make sense to them.
- Set suppressKeyEvents to true when your game is not using game actions. This will prevent your application from having to process irrelevant key events, making your game run faster.
- Use getKeyStates() to determine which keys have been pressed. This method simply detects whether each button has been pressed since the last game loop; it also sets all button statuses back to unpressed. This is the most efficient method of managing key input, and will also allow handling of simultaneous keypresses.
[edit] Play Menu
The Play Menu is a list of management actions that the user can perform during the play of the game. It is displayed whenever the user pauses the game.
- End all sound and vibration when the Play Menu is displayed. The user may have pressed pause to see the options, or to hide evidence of goofing off.
- Pause the game loop, including any timer, when the user displays the Play Menu.
- Provide access to the Play Menu from the main game screen. Users will easily be able to get to commands that are supplemental to the play of the game, without taking up screen real estate. Title the high-priority abstract command, “Menu.”
- Implement the Play Menu as an Implicit List. This will be very portable and easy to use.
- Title the Play Menu “Game Paused.” The user will see that the game is not continuing while this menu is examined. Of course, the game needs to actually be paused.
- Contents of the Play Menu should be as follows:
- “Continue” – returns to the game screen and un-pauses the game. “Resume” is a good alternative word.
- “New Game” – allows the user to give up the current game and try again (if appropriate).
- “Options” – displays the options screen (same as from Main Menu); if there is only one or two sets of options, include them in the Play Menu directly. See “Options Screen” for details.
- “Hint” – displays a hint for how to complete the current task in the game (if appropriate).
- “Instructions” – displays instructions screen. Avoid the term “Help,” as users may believe it to refer to game play hints.
- Left-justify text. It’s easier to read, matches users’ expectations, and allows the user to quickly scan the items.
- Include a low-priority abstract command labeled “Quit.” This should be a low-priority command of type EXIT.
- Implement a low-priority BACK command labeled “Back.” This will take the user back to the game, as if the user had selected “Continue.”
[edit] Sound and Vibration
The game experience is frequently enhanced with the use of sounds, and this is true of mobile games. Remember, though, that although some MIDP devices are targeted at gaming, others are targeted at a more general audience – or possibly even a business audience. So, don't expect every user to use a Nokia 3650!
Different audiences also have different needs with respect to battery life. A person relying on a phone for communications would be quite upset if the battery were drained due to game play and the phone could not receive an important call or message.
What this means to the savvy developer is that some users will happily have their devices make lots of fun sounds; others will be at a library or a meeting and would rather be more discreet. So, unless you are targeting only game-focused devices, consider the following recommendations:
- Provide a method to quickly turn off sound from the game play screen. Users will therefore be able to quickly become discreet as their boss walks by. This method should be visible; an abstract command or an item in a game menu accessed by an abstract command is an excellent choice. A game action or key code is less obvious.
- Provide four modes of play: sound or sound + vibration; vibrate only; none. The vibrator, if it exists, will rapidly reduce battery life. Do not assume that users who do not want sound instead want vibration. If desired, four levels of play are possible.
- Save the user's sound settings. They are likely to be consistent preferences for the individual user.
- Respect the user's sound settings even at application launch. A user who prefers quiet will quickly become annoyed if the splash screen always plays noise when the application launches.
- Use vibration sparingly. It quickly drains the battery.
- Use MIDI rather than WAV or AAC for sound when possible. While WAV files may sound more realistic, MIDI will use less storage and may be more discernible.
[edit] Multiple Player Games
One of the great promises of J2ME games is the ability to play against others, anywhere in the world. It shares this with Internet gaming, with the added advantage that users do not have to be glued to their computers. When a game is played in a competitive, time-constrained manner, users are more likely to stay with the game until its conclusion. To achieve this, they will generally find a place where they won't be distracted for a few minutes – that is, they will act more like users sitting in front of a computer.
Games may have multiple player functionality in one or more of three ways: Local turn-taking, Network live action, Network turn-taking
Each of these methods have different issues. A live-action game, for example, needs to account for issues of network lag. If a game is shared amongst two people, timing and information obstruction issues need to be carefully designed.
Clearly, the architecture described above will need to be modified for multiple-person games. At a minimum, different modes of play need to be added to the Main Menu, player names need to be identified, and some mechanism needs to be put in place to find network players.
If your game supports both online and local play, have the first two items of the Main Menu be “Play online” and “Play offline.” These clearly replace the “New Game” item in simpler games. Adjust these items to best represent the play options in your game [e.g., “Play offline (solo), Play offline (two), and Play online”].
[edit] Local Game Sharing
If two or more friends gather and decide they want to play a game, they may decide to share a game on a single device. This has the advantages of not requiring network access or air time, plus the players won't have to navigate using the phone or device to find other players.
The disadvantage of multiple people sharing the same device is that they have to pass the device between each other – live action games are not possible. It is also not a good idea to expect players to be able to look over each others' shoulders at the screen; it won't be possible in many situations (imagine sharing a game between 2-4 players sitting on a bus or train together).
- Do not make a live-action multiple-player game playable with two players on the same device. There just aren't enough controls to go around.
- Don't assume that the next player has seen all the action of the previous turns. It may not have been possible for the new player to see all the moves. Display any necessary information on the between-turn screen.
Communicating the distinction between single-player, multiple local players, and multiple networked players to the end user is difficult, and your game may very well have all these modes. The difficulty is even greater on a very small mobile screen than it is on computers or game consoles, as the space available for labels is very small, especially in the Main Menu. The labels “New game: one player”, “New game: multiple players, local”, and “New network game” are awkward on large screens and unreadable on small.
Thus, unless your normal method works very well on a small screen ...
- Distinguish between single-player games and local-share games by adding a “number of players” screen after the “New Game” item in the Main Menu. Default the number of players to 1 (if your game has a single-person mode) and have the highest priority abstract command accept that number. This will add a short pause to a single player instance of the game, without having to confuse the user with additional (poorly labeled) options in the main menu.
Other considerations include the fact that the time to pass the device from one player to another will vary; it could be as long as 30 seconds. If you allow for passing the device between players in a meeting or a classroom, the time delay could get even longer. Clearly you do not want to require such a long delay between turns.
- At the end of a turn, display a “between-turn” screen (Form or Alert) with no timeout. Instead, the user must press a key to proceed.
- Display the name of the next user on the “between-turn” screen. This could be “black”, “Player 2”, or “Bob”. A good label would be “white ready?”
- The between-turn screen should have a softkey to launch the next turn. This abstract command (a priority 1 command of type SCREEN) likely would be labeled “Go,” although some games will have a more context-appropriate label.
Finally, for a long game or a game in which several players may be playing, people may forget in what sequence turns come. This is especially possible for long-term games such as chess.
- Store the game state after each turn. This allows users to pause the game, perhaps for long periods of time.
- For games with a variable number of players, have the first screen after “Play offline” request number of players. This could be easily done with an Implicit List with the title “Number of Players” and items labeled 1-6. It’s unlikely that a mobile game will be shared amongst a large group of people using a single phone.
- Avoid requiring each player to type a name. Typing is particularly challenging on mobile devices, and you do not want to require an onerous set-up time before play can begin. An alternate method to personalize each player is to have them select a “game piece” or other virtual presence that is used to prompt each player for their turn.
- For games that require each player to select a name or icon, have the first screen after “Play offline” prompt the first player for personification. Avoid this tactic when the game is likely to be single-player, as it adds extra steps. For variable-player games, the primary softkey would be labeled “OK,” taking the user(s) to an Implicit List with items “Play Game” and “Add Player.” For games with a known number of players, the primary softkey should be labeled “Next” (except on the last player). A secondary softkey on each of these screens, “Cancel,” would take the user back to the Main Menu.
- Keep a record of all players who have entered their name on the device. Then display them as options when prompting for player names. This will lower the barriers to playing the game again.
- If a player must indicate when the turn is over, ensure that one of the two softkeys allows the turn to end. This abstract command (a high priority command of type SCREEN) likely would be labeled “Done,” although some games will have a more context-appropriate label.
[edit] Network Game Sharing
Networked games are one of the most exciting things about J2ME (especially MIDP 2). Some developers may even have visions of some people sitting at their computers, and others playing with or against them playing on their mobile devices.
As with the rest of mobile design, there are several factors that make mobile networked games different from wired games. Most of them will look familiar:
- Device screen size/speed: while desktop games are notorious for needing high-speed machines and large monitors, there are very few mobile devices optimized for games (Nokia's N-Gage is the exception, not the rule).
Connection speed: unless you are targeting a device that has local wireless connectivity and a MIDP implementation that supports it, you are stuck with data transfer at cell-phone speeds. While this has been steadily increasing (especially with 3G networks), expect it to be an order of magnitude slower than land-line connections.
- Connection lag: many wireless devices will drop their wireless connection if it has not been active for a while. With modern 3G networks, this means an additional 3-10 seconds to establish a connection before the data transfer can occur. If the connection has been active in the past several seconds (implementation varies by provider), the connection lag does not occur.
- Control set: Desktop machines have full keyboards, mice, and possibly game controllers; game consoles have game controllers and possibly keyboards; mobile devices have 12-key keypads and possibly a 4-, 5-, or 8-way rocker.
- Distraction: Mobile users may not be able to devote their full attention to the game.
We therefore recommend:
- Live-action games should be played only between users with similar devices. This will allow fair competition. N-Gage users will have an advantage over non-game mobile phone users.
Online competition introduces an extra bit of complication: discovering and selecting other players. In any online gaming environment, there is a social as well as a competitive element. Some players will want to choose any competitor, as long as the competitor is at roughly the same skill level; others will want to want to play with friends. Your competition-finding system should support both styles.
In the online bridge world, for example, users may select from one of a few rooms: “Novice,” “Intermediate,” and “Expert.” In some implementations, a user must have earned a certain number of points before being admitted to the “Expert” room, or must otherwise be invited. Once in a room, there could be 100 “tables,” each with 4 “seats.” Anybody entering the room may select an empty seat at any table. Once the table is full, card play begins. Users may also chat with each other. If two or four people wish to meet online, they generally select a time, room, and table to meet. They usually select a table “far from the door.” That is, they choose an arbitrary large number where they are unlikely to have others randomly discover them.
Migrating such a system to the mobile environment is certainly possible, but requires some adaptations. Users will be unlikely to scroll through a large number of tables, and they will not focus on their phone without distraction until their game fills up. Some recommendations:
- Separate games into categories meaning “anybody can play”, “by invitation only” and “game in progress”. Display these categories separately; you may not want to display the in-progress games at all.
- Consider automatically assigning players to the next available game if they do not have a pre-arranged game. This allows rapid entry into games and prevents having two partially-filled games delaying several players from playing. However, if your game community members are likely to select a game based on who is already in it, disregard this recommendation.
- Alert users with sound and/or vibration when the game is ready to start. This is obviously only necessary when play does not start right away.
- For slow-paced turn-based games such as chess, alert users with sound and/or vibration when it is their turn. Games that are fast-paced in the PC environment may become slow-paced in the mobile environment. Users may be playing while sitting in a meeting or otherwise distracted, and are unlikely to focus attention on the phone screen the way they would focus attention on a computer screen.
- Make your application responsive by minimizing network use. Avoid sending graphics over the network. Send graphics only when they have a real purpose in the game. Gratuitous graphics will only slow the online experience.
- Display pertinent user information such as name and handicap in the competition-discovery system. Information could be high or average score, persona, etc.
- Save the user’s name on the device. Since most mobile devices are used by a single person, this name is unlikely to change from instance to instance. You can also save user data either in your online system or on the local device.
- Allow users to specify a specific table, room, etc. This allows friends to arrange a meeting.
- Display games sorted by number of available slots, not by ID. Users won’t have to scroll through 15 full games before finding an available game.
- Provide online chat capability, but understand that users won’t type. Instead, you could have a list of typical phrases appropriate to the game. For some games, “trash talk” might be appropriate, whereas for others the talk may be chattier or highly game relevant. In bridge, for example, users may ask and respond about bidding conventions being used.
[edit] Miscellaneous
- Save the game state often at logical times. A good time to save the current state of the game is just after the user completes a level.
- Encapsulate lengthy operations such as network activity in their own new threads, avoiding synchronization. This will allow the application to continue providing user feedback, rather than lock up. Provide user feedback – perhaps an animation in a separate thread – for operations longer than about 1-2 seconds. Of course, avoid lengthy operations wherever possible.
- Re-use existing threads in lieu of creating new ones. Using an existing (currently unused) thread is faster and uses less overhead than creating a new one.
- Re-use existing objects in lieu of creating new ones. Object creation and destruction uses a lot of overhead. Design your application so that objects will be reused and referenced, not created and destroyed.
Use local variables instead of fields. Accessing local variables is quicker than accessing class members. Use function calls only when necessary. Assigning a function call to a local variable is faster than calling the function each time in a loop.
- Use StringBuffer instead of string concatenation. Concatenation requires object creation and garbage collection.
Create an indexed, 256-color palette for your application. By using a single palette, your application will require less memory.
- Implement error screens as Alerts of type WARNING or ERROR. These should be modal (not timed) alerts and should inform the user of what is wrong and how to fix it. See the Style Guide for further details on error screens.
- Use high-level components rather than Canvas where possible. Each Canvas you use is just one more screen that has to be designed for cross-device compatibility.
Also see: Scroll & select interfaces, Applications, Java ME


