Hi n8gray, The system you outline seems reasonable too. I'm not sure there's much value in splitting out GameState and GameMeta, but otherwise they seem reasonable. My main concern behind not having a separate GamePlayer entity would be a profusion of ListProperties for per-player data, but if you think that's manageable, go right ahead! :)
-Nick Johnson On Fri, Jun 12, 2009 at 12:07 AM, n8gray <[email protected]> wrote: > > Hi Nick, > > On Jun 11, 4:19 am, "Nick Johnson (Google)" <[email protected]> > wrote: > > Hi n8gray, > > > > Excellent question! > > > > Given the amount of information you're likely to store against > Players2Games > > (GamePlayers, perhaps?), and the number of games any one player may have, > > and the likely access patterns, I would suggest sticking with a separate > > model for it. > > Interesting -- I came to the opposite conclusion but maybe my > reasoning isn't sound. Here's what I've got right now (untested, so > it may contain syntax errors and such): > > class GameState(VersionedModel): > # Parent should be a GameMeta > scores = db.ListProperty(int) > other gritty details of the current game state > > class GameTurn(VersionedModel): > # Parent should be a GameMeta > creationDate = db.DateTimeProperty(auto_now_add=True) > player = db.ReferenceProperty(User) > turn_score = db.IntegerProperty() > more gritty details about this turn > > This is the stuff you only care about if you're currently playing the > game. The scores may be better placed in GameMeta -- I haven't > decided yet. > > class GameMeta(VersionedModel): > name = db.StringProperty(required=True) > password = db.StringProperty(indexed=False) > creationDate = db.DateTimeProperty(auto_now_add=True) > isActive = db.BooleanProperty(default=True) > # In case of tie, there can be more than one winner > winners = db.ListProperty(db.Key, default=None) > playerCount = db.IntegerProperty(required=True) > currentPlayer = db.ReferenceProperty(User, required=True) > currentPlayerNumber = db.IntegerProperty(default=0) > gameState = db.ReferenceProperty(GameState) > players = db.ListProperty(db.Key) > > GameMeta holds all the metadata of the game. I moved the players list > in here (despite watching Brett Slatkin's I/O talk on list properties) > because I reasoned that a) the serialization/deserialization overhead > for 4 elements wouldn't be too bad, and b) You're going to want the > player list every time you retrieve the game anyway. If you think > this is unwise, however, I'm interested to hear why. > > > > The main lesson for using the datastore instead of a relational database > is > > simply to denormalize and precalculate. In this case, that likely means > > storing running totals (number of turns, score, etc) against the > > Players2Games entity, instead of calculating them when needed as you > might > > in a relational database. > > Yeah, I was planning to do a fair bit of denormalization. > > > Tony's point about entity groups is an excellent one. Based on the sort > of > > updates you're likely to want to do, and the access patterns in an app > like > > this, I would suggest making the Players2Games entities child entities of > > the related Games entity, and making the Turns entities likewise child > > entities of their Games entity. This way, each game has its own entity > > group, so you can make atomic (transactional) updates across the whole > game > > with ease. > > At least I got that part right! > > Thanks, > -n8 > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en -~----------~----~----~----~------~----~------~--~---
