Thus spake george973:
I’ve read the API and have a few questions.
- I assume that GET /games///… will if it hits a subtree
(eg /games///state/pieces) will send the whole subtree in
response. If this is not the case then bin the design:
My understanding is that one generally expects to get a collection
of the children of a node when you request a node in a REST design.
a) the time to load over the internet will be enormous - Case Blue with
2000 pieces each having at least eight properties (with a value) would
require 34,000 request to get piece data = 68,000 to do in twice with 10
msecs response (which is fantasticly fast) = 680 seconds = 11 minutes.
and that allowing zero time for data transmission just turnaround time.
Any client fetching all the properties of all the pieces one at a time
would be terminally stupid. I wasn’t intending for clients to keep
current by sending requests to the state part of tree. Clients should
be doing that by processing the changes the server sends out.
b) It would be impossible to fetch a guaranteed consistent state of the
game. Since the state could in theory change between each fetch you do.
So you could fetch the list of pieces and before you fetch a piece’s
data it could have been deleted.
There should be a way to request the full state at once—I didn’t
include it in the draft. It’s unclear to me that GET on
/games///state is really the right way to do that.
2)The only useful fetch is GET /games// since it’s the only
one that gives you a complete consistent game state together with the
hash value which lets you make changes to it.
No, that would just get you “state”, “players”, and “history” back,
following the usual REST paradigm.
Unless other GETs are
intended to be used to get changes to the state.
No, GETs are nullipotent. A GET having a side-effect violates RFC 2616.
- POST / games / < gid >/ < pid >/ history / current - this changes the
hash value. What use is that? Unless the server is supposed to deduce
the required change from the change to the hash value?
Nothing about the input should be deducible from the hash value if we
are using a cryptographically strong hash.
The other thing is why does the
client calculate the new hash? Does the server validate the new hash?
Yes, the server calculates the new hash from the old hash and the change
the client sent. If the new hash the server computed does not match the
new hash the client computed, then either the client and server started
with different old hashes (likely) or the change sent by the client got
corrupted in transit. In either case, the change should not be applied.
There’s a lot of requests going on here. Each request in itself may lead
to an invalid state of the game (eg consider a stack of two pieces one
in position zero and the other position one) changing the their order in
the stack means changing the first to position one - two pieces in
position one now and none in position zero - and then the second to
position zero - state valid again.
This would be one change, not three.
The server must calculate new hashes
for all the other players if the changes are visible to them. How do the
other clients get told the has has changed?
There needs to be a URL (not in the draft) which clients can long-poll,
over which they’d receive changes from the server.
- GET / games / < gid >/ < pid >/ history / < hash > -this returns the
change at hash visible to the player. How is the change packaged?
The payload of the reply would be some XML representing what changed.
It makes sense for this to be the same XML which would appear a game
log (for player ).
By the way using pid for player id and pid for piece id is a
recipe for confusion.
Yes, I’m aware of this, as is reusing n as an index. At this point,
being scrupulous about that would not not make the diagram clearer.
I assume the change sent is the change from the
previous state.
No, the change is the change named by . It need not be the case
that == the value of current.
- POST / games / < gid >/ < pid >/ history / < hash >
[snip]
I’m not sure if I understand this. If the hash an existing value in
history in which case this is an undo or is it a new value in which case
this is a new move and the has will become the current value - in which
case why was there a post to change the current hash?
If is already in the history which the game server has, then
the request will fail. must be new.
LIGHT HAS DAWNED - current does not represent the latest game state but
where a client is stepping through it.
“current” is just that—it’s a pointer to which state is the current
state.
In which case the design allows
players to go back to a previous point and change history. In an email
game it’s a CHEATER’S CHARTER since you can do a die roll and if you
don’t like the result you can step back, delete it and do it again until
you like the result.
You can do the same now in an email game. I don’t see any way to
prevent such a thing in a game where the turns are conducted without
the assistance of a trusted third party, regardless of the design.
Also it’s dangerous. If I’m stepping through a log
file and accidentally do something in the middle then the rest of the
log is deleted!!!
I’m not convinced that it should be possible to make changes in the
middle of log playback, at least not without something warning you that
you’re about to truncate your log. Anyway, you could always reload your
log.
I would say as a design principle: no history is deleted. If a player
takes back a move then the move and taking it back are both recorded as
events.
This will make for intollerable logs, I’m afraid.
Also if you are not deleting things you don’t need hashes. A simple
incrementing state number will do.
A state id which is not a hash can’t be used for checking history
integrity.
- Many requests to the server are not changes but requests to run
scripts (eg if a piece has a menu item “Flip” then client does not know
what to do -it just asks the server to execute the attached script). The
changes will all be made at the server so the client cannot calculate a
hash as the result is not known to it.
This can be accommodated as follows: The hash sent by the client has the
script identifier as part of its input. The server can still verify that
the client had the current state. However, the server need not add
anything with that hash to the log—the server can update the state
using the actual change produced by the script, store that change with
its hash in the log, and both the change and its hash to the client.
- The server understands the game structure. If the structure changes
in 4.1 you’ll need a different server.
I don’t see why you think this. Can you explain further?
–
J.