Hi Nick,

On Jun 11, 4:19 am, "Nick Johnson (Google)" <nick.john...@google.com>
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 google-appengine@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to