Hello,
I got a client/server game where my server is running at 10 updates per second. Testing stuff today, I noticed that moveWithCollisions is not running as expected. I replay all client inputs on the server again and call moveWithCollisions. It seems that moveWithCollisions is batching all displacment vectors and doing them all at once in the next scene.render().
As a consequence my character is running through the wall. This will not happen if I increase the update rate on my Server.
If applying multiple client inputs on the server implies moving an object multiple times in between scene renders (which is typical for network programming) then yeah that sounds about right. There are a few ways to think about the problem and solve it.
Strictly speaking from the perspective of network programming and having clients run at faster tick rates than the server, then processing multiple client commands (however many have been sent) per frame on the server is going to produce the closest simulation between the two (possibly perfect, depending on the actual movement math). This sounds like what you’re doing. To get the equivalent behavior of moveWithCollisions but as multiple smaller steps outside of the actual scene.render() you can use the function mesh.computeWorldMatrix(true)
after moving it, and then check it for collisions after that. You’ll probably end up doings this ~6 times in a row per client per server tick (b/c 60 fps vs 10 fps). It won’t be exact thanks to lag, sometimes it’ll be less frames sometimes it’ll be several (packet loss).
If your object is still capable of moving through objects after that, research “tunneling” and “continuous collision detection.” If the delta or input time is part the data sent from the client to the server (it probably should be) and a lag patch on the client allows them to tunnel, then inspecting delta and breaking up movement into numerous smaller steps programmatically can offer a quick fix without having to go all the way into programming continuous collision detection.
Sorry for getting right into the technical weeds of the network stuff, but it sounds like you pretty much have it very close to working already. I can go back and explain any of the stuff in more detail if you want, I just made a networked first person shooter with predicted movement and all that stuff. I will note that I did do my own collision stuff b/c moveWithCollisions was not quite a match for what I wanted.
Hey timetocode I follow you on twitter. I love your game, library and youtube channel. You’re a huge inspiration for me.
adding mesh.computeWorldMatrix(true) after mesh.moveWithCollisions did not fix the issue. Are you sure this function does collisions too? The object is not fast, it seems to just ignore my collision cube. As if it still adds the full client movement in one and then checking collision.
I wanted to create my own collision too but I dont know how to create a collision resolution function.
Thanks for your detailed answer
Thank you I’m working on an open source release of a lot of networking code in the near future.
So back to your issue, I looked at my old code form the start of the babylon+nengi project, and I think what I said about is wrong about moveWithCollisions
. moveWithCollisions
is already continuous collision detection b/c it moves the object along a vector (instead of teleporting it forward in one big step) specifically to avoid tunneling through an object.
Do you think you could make a bjs playground of the issue? It won’t be networked and there won’t be variable tick rates… but it would come out pretty close to have an example of the client inputs and then some code that applies them (or just one input multiple times) and manages to move an object through another. The pg is going to run at 60+ fps, so it might take a loop that repeats movement 36x before it is similar to how much movement a 10 tick server performs in one tick when receiving input frames from a 60 fps client… or just some larger numbers somewhere in the mix.
I’m going to tinker with moveWithCollisions a bit, too. I need some material for a bjs+networking tutorial, and I’d definitely rather show moveWithCollisions being used if possible than some custom collision stuff.
Here’s a PG to get things started:
https://www.babylonjs-playground.com/#EL9APM
I can’t get a cube to tunnel through another cube, but depending on the speeds/repetitions etc they will slide past each other.