Sure -
Sure -
The Durable Object handles websocket clients for a multiplayer game using a deterministic physics engine. The physics are executed on both the clients and the server. Serializing the physics world costs up to a few KB per player.
To join games, I have a
lobbies
table in D1 with a game_state column: 'waiting' | 'playing' | 'finished'
. I need to set the game to the finished
state when it's abandoned, so if the player rejoins the websocket later, it won't re-initialize the DO.
Because the transactional storage API is so expensive, I want to treat crashed games as permanently dead and show clients an error when they reconnect.16 Replies
Moving this to a thread btw.. keeps the channel cleaner for other people
👍
Hmm. I do already have a tick_index that gets incremented, so if the client detects that it's decreased it knows it's broken?
seems really hard to get right
I mean when the DO is reinitialised, it wont have any state.. so that might be a clue?
When the DO gets a regular gaming message when it doesn't have any state, it knows something is up I would imagine?
that might work
But then I am letting my clients dictate when I've crashed
Also they don't send heartbeats
But I guess they would auto-reconnect... or maybe not?
because if I'm using the Hibernation API, when the DO crashes they would stay connected
or is that wrong?
I guess the foolproof solution is to store some "game_started" boolean in transactional storage, and then if that's set to true when the DO is constructed I know it's in a bad state
However, the flaw with that solution is that I only detect the crash once the clients reconnect - it doesn't detect abandonment
The clients would try to reconnect yes. So you would receive a message. Now I don't know your protocol obviously, but I can imagine that the messages you receive during a game are different than before a game?
My only concern is a malicious client here.
Just kill that client? And if all connections are killed clean up and let the DO die?
I am not sure if you can set a timeout on the hibernation API? I haven't used it myself.. but otherwise you will want to use an alarm for that
I mean if my metric for detecting a crash is if a client sends the wrong type of message, a malicious client could send that message intentionally and kill the DO
Don't kill the DO.. kill the client connection.
I need to write to D1 that the lobby is dead
And if all connections are gone, the DO will die
I guess that would work, but now we're back to needing a way to detect when the DO dies naturally
You mean when all clients stop playing?
Hmm.. so I just realised that in your case the DO can still be unloaded, even though gamers are connected right?
There are 3 cases for the DO dying:
1. Game ends, I kick all clients and update D1
2. Game is abandoned, all clients are disconnected - I guess I do this on a
close
event + a timer? Still impractical
3. DO crashes, client almost certainly instantly auto-reconnects, I detect that the DO is being initialized in a bad state and update D1
I only want to hibernate in the waiting
state - during the playing
state I'm broadcasting 10 ticks per secondok.. that makes sense. So how long can the
waiting
state take?Until the lobby fills