I have developed a multi-user game using GWT, and I would like some feedback on how I implemented it. It works OK but it isn't perfect so I'm trying to work out the glitches.
Here is a summary of the key features of the game:
- Multiple independent games can be happening concurrently within the app
- Each game can have an arbitrary number of players
- Each game is broken up into timed "turns", and a turn can be initiated by any player
- All players can create input to the game during a turn, and all players should see any input by other players in the game right away
- A player can be anonymous or can log in
- A player can chat with other players while playing
- At the end of the turn, the game state is updated with results from the turn, and the game waits for a player to initiate a new turn
- Players can come and go as they please, entering or leaving a game in the middle of a turn, between turns, or just shut down their browser or the computer can go to sleep
- Players can leave one game and go into another game at any time
I implemented the game using Channel and Task Queue APIs from AppEngine. It is a GWT app using the MVP model, but is based on the original History model (no Activities/Places) and I have not used UiBinder or RequestFactory.
Here are my questions and issues:
- What is a good way to generate a Client ID for the Channel? Right now the app creates a persistent Player object for each new player, and uses the JDO-generated ID as the Client ID. It stores the ID in a Collection of Players in each Game object to update all the players in the game "real-time". I use a cron servlet to delete old Players when I don't need them anymore, but I feel like there has to be a way to do this without creating a persistent object that I am going to get rid of later.
- When the computer goes to sleep or the user logs off the computer, a Player may not be removed from a Game object properly, and has to be removed later by a clean-up process. Is there any way to ensure proper removal of a player when the computer sleeps or the user logs off? (I'm thinking about using the new channel_presence feature in the Channel API)
- The way the timed turn works is with a Task Queue object with a countdownMillis property. This seems to work pretty well, but if the Task Queue does not fire on time it can result in odd behavior. Can I trust the the Task Queue object will fire on time consistently? Is there a better way to implement a timed turn feature?
- Minor issue: Right now the app does not store any state between visits to the web app site, nor when the user logs in or logs out - the app always enters at a default location. What is the best way to store state. Cookies? Persistence objects on the server?
I am in the process of re-writing the app using UiBinder, RequestFactory, and Activities and Places. I would like to improve some of the above implementations in the process. Any help and ideas would be much appreciated. Thanks!