Patrick (he/him)
Patrick (he/him)17mo ago

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
Patrick (he/him)
Patrick (he/him)17mo ago
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.
NDH
NDH17mo ago
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.
Patrick (he/him)
Patrick (he/him)17mo ago
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.
NDH
NDH17mo ago
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. 😊
Patrick (he/him)
Patrick (he/him)17mo ago
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
ioB
ioB17mo ago
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
Patrick (he/him)
Patrick (he/him)17mo ago
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.
ioB
ioB17mo ago
The magic of deterministic physics engines is that there cannot be a disagreement in the state
Patrick (he/him)
Patrick (he/him)17mo ago
sure, but can’t network lag and other things outside the physics engine introduce discrepancies?
ioB
ioB17mo ago
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"
Patrick (he/him)
Patrick (he/him)17mo ago
like local lag, I guess?
ioB
ioB17mo ago
sorry? local lag?
Patrick (he/him)
Patrick (he/him)17mo ago
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
ioB
ioB17mo ago
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.
Patrick (he/him)
Patrick (he/him)17mo ago
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?
ioB
ioB17mo ago
I'm confused, I assume you're asking about server-initiated events and not client-initiated events here?
Patrick (he/him)
Patrick (he/him)17mo ago
well, I’m overall asking about fast-paced multiplayer online games with collision detection and how that could work with isolates. The commands that update the game state would mostly originate from clients. The problem I was just asking about seems to apply to isolate-isolate communication as much as to client-server communication since both are subject to lag/latency
ioB
ioB17mo ago
I'm confused on how latency matters outside of making sure to not trip the 100 millisecond limit you set on accepting actions
Patrick (he/him)
Patrick (he/him)17mo ago
I mean, I assume there must be latency between isolates at least if they’re in different regions I mean, how do they sync their clocks?
ioB
ioB17mo ago
Like... new Date().getTime()? Also, ideally for real time games you do not communicate across regions. I would probably set up zones which communicate with each other in the same region.
Patrick (he/him)
Patrick (he/him)17mo ago
that’s not necessarily the same. Maybe on isolates it’s safe to assume but not on clients and it has to work there as well
ioB
ioB17mo ago
that’s not necessarily the same
? Not the same as what? Also, I'm not understanding the need for clock syncing the "timestamp" is the physics engine timestamp, and not real-time Ah I think I understand what you're asking about How do you know what the current "timestamp" is that you should be at.
Patrick (he/him)
Patrick (he/him)17mo ago
yeah how do the instances of the physics engine have the same timestamp at the same time?
ioB
ioB17mo ago
That's the challenge of time-syncing protocols. I think in this case you can just use new Date().getTime() to derive what physics engine timestamp you should be at.
Patrick (he/him)
Patrick (he/him)17mo ago
depends on OS’s time, which is set by the user
ioB
ioB17mo ago
In this case, the user's actions will be rejected 100% of the time and I don't really see a problem with that. http certificates breaks pretty badly if the user sets the OS time I think the collective internet has agreed that if you mess with the operating system time, that's on you
Patrick (he/him)
Patrick (he/him)17mo ago
hmm ok, you’ve given me some new ideas to tinker around with. Thanks!
ioB
ioB17mo ago
👍 Always here to chat
NDH
NDH17mo ago
If implement something like this in Deploy, you'd better get your checkbook out 50ms is pretty short for so much work!