Simulating physics collisions across isolates
A bit tangential to Deno, but since Deploy uses v8 isolates, it seems that a multiplayer online game that involves collision detection and resolution that runs on Deploy would need to do things a bit differently. Wondering if anyone out there has delved into this before and wouldn’t mind sharing their discoveries?
29 Replies
hope you don’t mind the ping @ndh3193 but I thought the previous thread was getting off topic and this seemed to warrant a new thread.
What is your use case? If you're broadcasting position change events, then the client should detect collisions locally. On my apps, all clients maintain synced state locally, and each only send state-change events to peers.
well, my understanding is that the industry standard is the authoritative server with client side prediction, reconciliation, lag compensation… but that assumes there’s one server that’s authoritative about every aspect of the game, including physics collisions. With the way Deploy works, it seems like all the isolates would have their own instance of the physics simulation, which can be intermittently sync’d via BroadcastChannel, but handling collisions seems tricky because detection is a qualitative thing and seems like each isolate would be equally authoritative.
My use case is typical of arcade/platformer games e.g. player hits a baddie and loses health, entity hits a static object and bounces off… and would like to be able to prevent cheats with modded client code.
I've only ever used servers to serve game code and assets, and then act as a state-synchronizing service. I can't see Deploy as ever being able to run non-trivial game logic continuously. Perhaps someone else has more experience with this. 😊
yeah, that's kinda what it seems like to me too. Will try more traditional hosting for now but will keep an eye on Deploy
it's definitely possible
the search term you're looking for is "resumable physics engine" or "deterministic physics engine"
lots of cool tech around that
in the best case scenario gives you the advantages of everything
everyone calculates the physics, the server just verifies that the physics calculations match up with what they should be
rapier is what I would recommend
I guess I’m overthinking it, perhaps. If one isolate detects a collision and the state of all isolates are being kept reasonably in sync and protected from modded clients then we can assume that’s really a collision… it seems like too much to manage, trying to come to consensus if there’s disagreement between the isolates.
The magic of deterministic physics engines is that there cannot be a disagreement in the state
sure, but can’t network lag and other things outside the physics engine introduce discrepancies?
There are some tricks you can do to prevent discrepancies without allowing exploits from clients
One of the big problems is "how do I handle user input"
like local lag, I guess?
sorry?
local lag?
it’s a technique I just read about where you delay processing input locally just enough so that the server can process it at the same time
Ah no, the magic of resumable physics is that you don't need to do that. Let's run through a little demo on how that would work.
Client 1 presses the forward key. Make sure to record the physics engine timestamp when this action happened. The physics on the client will immediately react. Send the action along with the timestamp to the server.
The server receives the action. First, it verifies that the action happened within some interval (the last 100 milliseconds or something). It then broadcasts this to all the other clients connected to the game.
Unfortunately for the server (and the other clients), it has been simulating without this action. Fortunately, with deterministic physics engines, you can simply run physics in reverse until you hit the physics step before the action was going to happen. After you go back in time, you can play the action and then quickly recalculate all of the physics steps to bring you back to real time.
As you can see, this would scale across multiple isolates
The state of the physics is also serializable so one could store it in KV. When an isolate boots, it could read the last authoritative state stored in KV, and the quickly recalculate physics to catch up with the current global timestamp.
This is definitely overkill, but is a fun project to implement.
how is the server’s time sync’d with the client? I mean, say the server starts at T0, then at T1 receives request 1 from a new client, and sends response 1, which the client receives at T2. If the server includes the time in its response what time does it send? the time it sends the request or when it expects the client to receive it?