Server Sided Physics

Hey,
So basically, I’m trying to make physics work server sided. My idea was to have each map region (a map region is fairly large, it contains 4 64x64 maps) on its own thread, and as a result, its own physics space object.
I set this up, however, the only way I could get it to actually move was if I added each object to the scenegraph. Understandably, this is because it needs to be on the scenegraph to be part of the update cycle, but is there any way that I could have multiple scenegraphs running at once, in parallel? The reason being that if the server is handling, say, 1000 players, it’s having to handle each of those 1000 players falling on 1 thread.

Or… Is the actual physics calculation executed on the thread that created the physics space? Because if that’s the case, then there really isn’t a problem as the main update cycle is only queuing something on another thread.

Thanks,
Fabian

1 Like

Server sided physics is a bad idea. too much information would have to travel from the server to the client. Even on a socket, any more than a few players and it will will obliterate the data throughput. Instead, you just track the position for example, or whatever else is necessary. In a production game you would be exchanging as little data as possible. Pushing entire physics states is just plain irresponsible.

Server side physics is a very common way to handle multiplayer so I’m not sure why that would be a bad idea?

I think OP is saying that a server-side scene graph was needed to get the physics simulation running on the server.
Maybe setting the threading type to parallell would help although I haven’t tried so just guessing:

https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/bullet-common/com/jme3/bullet/BulletAppState.java

@jayfella said: Server sided physics is a bad idea. too much information would have to travel from the server to the client. Even on a socket, any more than a few players and it will will obliterate the data throughput. Instead, you just track the position for example, or whatever else is necessary. In a production game you would be exchanging as little data as possible. Pushing entire physics states is just plain irresponsible.

That’s when you get teleport hacks, noclip hacks etc. Also, at the end of the day, it’s actually sending less data, as it’s only sending the player rotations from Client A to the server, then the server sends client A’s position to A, B, C etc, where before it would only send to B and C.

@jmaasing said: Server side physics is a very common way to handle multiplayer so I'm not sure why that would be a bad idea?

I think OP is saying that a server-side scene graph was needed to get the physics simulation running on the server.
Maybe setting the threading type to parallell would help although I haven’t tried so just guessing:

Google Code Archive - Long-term storage for Google Code Project Hosting.

I’ve done that, but what I was hoping to have was it running each iteration of the scenegraph on a per-region basis.

Sorry, I was wrong. I have no idea what I was talking about.

you could run multiple headless instances of jmonkey.

i think you could also do this by running multiple instances of bullet app state (with a little trickery).

you could also look inside the code of SimpleApplication and see what “the” scene graph is. and just create your own rootnodes.

@icamefromspace said: you could run multiple headless instances of jmonkey.

i think you could also do this by running multiple instances of bullet app state (with a little trickery).

you could also look inside the code of SimpleApplication and see what “the” scene graph is. and just create your own rootnodes.

That’s possibly the most useful idea I’ve heard / had so far. It’s simply a node that has the following in the update cycle:
[java]rootNode.updateLogicalState(tpf);
rootNode.updateGeometricState();[/java]

Even still, If I have it set to run in parallel threading mode, will that mean that the main update cycle itself will still be running at atleast 60Hz? If they’re all attached to the root node?

Seems a little silly to have a scene graph on the server just to do physics since the real physics calculations are done independent of the scene graph anyway.

@pspeed said: Seems a little silly to have a scene graph on the server just to do physics since the real physics calculations are done independent of the scene graph anyway.

Yeh =/ Can you think of any workaround?
At the end of the day, a scenegraph would probably be useful anyway.

actually, are you sure you need to actually add the physics objects to the scene graph? you should try just adding them to the physics space and then print out their physics locations and still see if they move. i THINK the physics controls that you add to the scene graph are just for polling the state of the physics simulation for display.

Ive not actually tried this, ive only daddled with bullet app state in the past. but i think bullet is created such that you could do it that way, because the simulation itself can be run on an alternate thread, so that should mean it doesnt require anything on the scene graph for doing the physics simulation.

Yep, you can directly create PhysicSpaces and add rigidbodys to it, without using the higher layer jme interaction stuff. Basically jme is one necessary for easiyer loading and for the jni wrapper in this case. You would not even need an application.

Hey, exactly the thread that i wanted. Sorry to hijack a bit your thread Fabian but i’ve encountered a very similar problem (client server project…authoritative server and of course, server sided physics like you…but my server has only data managed by an ES, Zay Es made by @pspeed…i love it by the way ;))

I currently use some hacks to mix jbullet with zay es but i search a real solution for physics…i have some artifacts…
Do i have to reinvent the wheel with my own physic state (i’m afraid that the answer is yes ^^)

The server has 0 spatial…only position and collision shape info(mass, radius…) in components…ghost controls can only report collision with getUserobject which is normally a geometry (no geometry on the server i have only physic controls that i move manually cause update loops doesn’t run without spatial attached)…i’ve to iterate along all my players Entities to find which is inside the radius of that ghostControl with a check between control position plus radius and entity position…and it’s a bit painfull to collide with the world (terrain) too.

@pspeed How do you handle physics in Mythruna?

I believe one of these functions is responsible for triggering update on all of the controls on all nodes in the scene:
rootNode.updateLogicalState(tpf);
rootNode.updateGeometricState();
Someone fill me in on this?
If this is the case, then I could trigger these on the regional nodes directly on a thread-per-thread basis, accomplishing the multi threaded physics calculations that I required without having to do it sequentially per region.

@fabsterpal said: I believe one of these functions is responsible for triggering update on all of the controls on all nodes in the scene: rootNode.updateLogicalState(tpf); rootNode.updateGeometricState(); Someone fill me in on this? If this is the case, then I could trigger these on the regional nodes directly on a thread-per-thread basis, accomplishing the multi threaded physics calculations that I required without having to do it sequentially per region.

Well, one calls controlUpdate and other calls controlRender but neither of them do anything with physics calculations other than copying the values back to the Spatials for rendering. If you don’t need a scene graph on the back end then there is no reason to have one. The physics is done separately and then copied into them during controlUpdate.

That’s what I was getting at. When you are doing physics, you don’t need rendering, you don’t need parent/child relationships (physics won’t pay attention to the scene graph for that anyway), and now you have an extra set of stuff to manage that you could just have easily ignored.

@haze said: The server has 0 spatial...only position and collision shape info(mass, radius...) in components...ghost controls can only report collision with getUserobject which is normally a geometry (no geometry on the server i have only physic controls that i move manually cause update loops doesn't run without spatial attached)...i've to iterate along all my players Entities to find which is inside the radius of that ghostControl with a check between control position plus radius and entity position...and it's a bit painfull to collide with the world (terrain) too.

@pspeed How do you handle physics in Mythruna?

It’s… complicated.

Real time networking is… complicated. :slight_smile:

In Mythruna, the physics is sort of done outside of the ES because bandwidth is your enemy here and most of the state data is obsolete after the next message. It collects state per zone and then sends a highly compressed state message 20 times a second (with 1/20th of a second of history) to clients interested in that zone. Clients use this data to rebuild history and send the server a message saying what state level they are caught up to (part of the data compression). Since these state messages are sent unreliably I have to send state multiple times for objects until I know the client has received the information or the state is now obsolete. For moving objects, this isn’t actually duplicate information since the position/rotation likely changes several times a frame anyway. The resend happens for ‘left zone’ and ‘entered zone’ style state updates.

On average, I can send updates for about 80 objects in less than the size of a standard MTU (1400 bytes is where I clamp it). Each time a UDP message spans an MTU you increase its chances of getting dropped on a poor connection. Since my state can already be split up, I try hard to stay under this size so that the UDP messages go in one packet. Some state is better than no state in my case since it will shrink the amount of data that needs to be sent the following frame.

The old Mythruna engine (the one in the last public release) doesn’t have real physics at all so the only things tracked with that level of fidelity were the players. And in that case, I just blasted UDP messages with 50 ms of data and hoped for the best. (When players dragged objects then I just spammed ES Position updates which were on a different channel anyway.)

Once received on the client, I reconstruct the ‘history’ (still future to the client) and fill a thread safe component on the Entity. It’s one of the rare cases that I have a component that is mutable and internally handles its own multithreading. The rendering side then asks for position+orientation at a specific time and the component interpolates based on the data it has received.

That part is pretty textbook from the Valve articles:
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization

The client renders at a 100-200 ms delay or so. It’s actually rendering near (really near) history.

Aah, so I can use getPhysicsLocation instead?
I am currently using BetterCharacterControl, which doesn’t seem to have this method exposed. Any idea why this is?

its not a rigidbody, but a complex logic stuff around one.

the fact that it doesnt have a getPhysicsLocation() is a little weird though. if its not attached to a scene graph how are you supposed to know where it is located?

@icamefromspace said: the fact that it doesnt have a getPhysicsLocation() is a little weird though. if its not attached to a scene graph how are you supposed to know where it is located?

[java]public class MyCharacterControl extends BetterCharacterControl {

public MyCharacterControl(float radius, float height, float mass) {
    super(radius, height, mass);
}

public Vector3f getLocation() {
    return rigidBody.getPhysicsLocation();
}

}[/java]