Advanced Java Game Development: State Data
Sounds great. For game universes where security is key, such as casino games that bet with real money, this is the only way to run the show.
The real boon of a well-designed Java system is that you can migrate from one server architecture to another with relative ease.
However, for more casual gaming, there are loads of reasons why this type of architecture sucks. First of all, things couldn't possibly be slower. Every time you click your mouse you'll need to wait for the server's feedback before anything happens. Granted, the client can be written so that it guesses what will likely happen. But you're still talking about one far-off authority that must dictate all actions. On slow Internet connections, that makes for a pretty horrific gameplay experience.
In addition, the server will work up quite a sweat. It must store every game's state, calculate all moves based on game rules, and constantly accept and fire off a hailstorm of network traffic. A server that does all the work will obviously get overworked more quickly than a more streamlined system.
Husky Client, Husky Server
What about sharing the work between client and server? A server, after all, is a good, warm, central place to keep game state. Think of the server like a vast vault that holds all the stuff you don't want to mess with. As long as the server has the latest game state, you'll be able to help out-of-synch clients get back on track. You'll also be able to recreate the precise game state for any observers that pop in during the middle of play.
The client, on the other hand, is very people-oriented. It's great at reacting immediately to user input, handling game rules, and drawing snazzy graphics.
Specifically, the PlayLink server handles the following:
- Chat messages.
- Who is in the game, and what each person's status is player, waitlister, observer, or AI. If a new person jumps into the game, the server alone determines whether there is an empty slot for the person to play at. If not, it puts that person on the wait list.
- The gametable's options.
- An array of bytes representing the game state, such as the current score, whose turn it is, and the exact arrangement of the game board.
The real work involves deciding when to update the state. In general, the sooner a client can send the state to the server, the better. Every time a player makes a move even before the move is animated the client should figure out how it affects the state. It then sends this state change to the server, which stores the info and broadcasts it to the other players and observers as quickly as possible.
Now, this solution is not a perfect one. It's still relatively easy for a dishonest client to cheat by implementing illegal game rules. But for a casual board-gaming system such as PlayLink, this compromise seems ideal.
Serve Me Now!
No matter what client-server architecture you choose, you'll always need to make further choices such as: whether to use TCP or UDP, what your proprietary gaming protocol should look like, and whether to encrypt the network data for added security. You'll also have to decide how to distribute tasks among different clients, and if you really want to think big, you'll need to figure out a way to balance load between multiple servers.
In any case, the real boon of a well-designed Java system is that you can migrate from one server architecture to another with relative ease. Just swap out a few communication listener classes with a new messaging protocol, move around your game rule classes, and recompile. Is it ever that easy in practice? Heck no. But one can always hope.
About the AuthorDavid Fox is vice president of Games at PlayLink, Inc. He's also the author of numerous books and articles about cyberculture and technology.
Page 2 of 2