Client based physics not the same as server

Hi everyone… This is my first post so please be gentle with me…

I’m new to unity, and still trying to find my feet but I’ve done quite a bit of dabbling in other development…

Anyway, after messing about with the networking tutorial, I’ve managed to get a game that connects over the network in a server->client basis. And everything is fine, the cars move around quite smoothly and collide well.

Then I wanted to just add a simple ball… And it’s all gone wrong from there.

I’ve instantiated a ball and applied a network view and set up all the physics, and it seems to work, but when the server collides with the ball it pings around properly. However, if the client collides with the ball, it seems to not react correctly. I’ve tried pretty much everything I can think of, including disabling the physics of the ball on the client. Enlarging the collider, tweaking the network update.

But now I’m out of ideas… Can anyone else help? (I’m willing to host the project somewhere if someone was kind enough to take a look - it’ll probably be easier to see the problem too…)

:frowning:

Is your server authoritative?

I believe so yes… I’m not using a master server, but one machine “starts” as the server and the other connects to it… I then send RPC’s to tell the new client where everything is… then I’m using network views to monitor movements…

likely your network code is incorrect.

did you implement it with the 100ms pushback etc as shown in the networking example or are you pushing stuff through directly?

If you do the later, I’m sorry to say but it will never work. not even without physics it would but with physics it never will. networked physics in general will always be a problem so I would recommend to either not go with physics or invest a lot of time on how to handle it in networked environments cause it will otherwise lead to a disaster

I’m using the interpolation stuff that was in the example, but I’m not sure that’s the problem. When the client hits the ball, even on the server, the ball doesn’t react the same as if the servers car hit it. It’s a shame because I really need the ball to be ‘fair’ to both server and client.

I’m sure I’m missing something that could solve it but I just can’t see what, I really thought turning the collider off on the ball on the client would have done it.

Just to be sure, can someone tell me how they’d turn a collider off? (I think I used, destroy(SphereCollider)

destroying it would actually be the right way to turn it off yeah, they don’t have any other way for turning on / off

It’s just a bit strange… So there must be no games out there that are mp and have accurate physics? I find that a bit hard to fathom…

If you check the game listing you will find out that there no DX9 game that offers multiplayer and that has physic simulation for gameplay relevant aspects in that MP. (newer games might do so but they are DX10 and thats something not even available in Unity nor does PhysX offer hw acceleration on osx to approach it at all)

Simply put, Physics Simulation != Physics

Simple physic MP existed for a long time.
But physical simulation as you have it with PhysX, Havok etc is rather rare in Multiplayer usage of relevant gameplay features and not just decoration like the barrels in the HL2 based MPs
The reason is rather simple: numerical calculation behavior is different between different processors and processor generations which leads to inconsistent outcomes of linear equation systems (-> which is what physics is primarily when simulated). Already this is bad enough but if you now add in a variable latency impacting this physical simulation you are presented with complexity thats hard to impossible to overcome.

Best example is Crysis which requires DX10 to offer physics in MP, the DX9 one doesn’t offer it.

Play garrysmod, which is based on the Source engine (hl2). Physics works just fine. The reason is, because even though they have an authoritative server model, the client does it’s own calculations on where it think items should go. The server merely ‘corrects’ positions on the clients. This is technically how you should do everything in order to add increased ‘responsiveness’, by having the clients do their own calculations, the same as the server, and have the server merely correct any errors in the clients.

Thats how it should be done yes and thats the basic on which any authorative environment works.
but to do so reasonably, you need networking that is more or less safe against latency and alike so giving the networking example a go etc is important.

But at the same time it also shows problems.
In addition, unity does not expose 2 fundamental physx functions to do networked physics in a much more reasonable way, those are the simulate related calls to drive the simulations manually for a given amount of virtual time for example to react to the spawn or impact that happened XXX ms ago but especially to explosions. you can’t use time stamped events for this as unity does not allow your client side prediction to work fine against the server and other players due to the lack of simulation control access

it will be a tricky thing to get things done. just doing “corrections” and assuming that will be all you need to do won’t work out, not with physics simulations at least, thats something I can say from experience with Unity based MP networking and physics

but it heavily depends on what you do in detail, there are things that are worse and things that are easier (shooting something for example is easy. stacking stuff works rather well too)

also keep in mind that physics can be rather cpu heavy if you don’t opt for lightweight, in which case you can get in trouble if you meant to have more than 4-8 players. unity calculates all in 1 thread, no offload of physics

hmm… true about “real physics” and all that, but I’m not after that…

My problem is that even just controlling the client, and watching it on the server, the collision on the server (with a ball) by a client is not the same as the collision as if the server collided with it. (It’s hugely noticable) - it’s not lag or latency or anything like that, I’m saying the clients clone object collides with the ball on the server in a different way… (and as the servers ball position is authoratitive, it’s not doing any “funky updates” and placing it in the wrong place) - least, not to my knowledge. It’s just simply wrong… (i.e. the server/ball collision, the ball “bounces”, and client/ball collision the ball doesn’t bounce at all)

I’ve just found the autoratitive example in the network tutorial, I’ll take a look at that and see if I can get any better results…

Okay I played around with the authoratitve scripts in the networking example and they seem to produce better results, but still the problem persists… (and I can’t get the client to sync for some reason) -
I’m now convinced that it’s me missing something though…

I know this generally isn’t the done thing but I’m running out of options here and i’ve been banging my head against the wall for days now… I’ve uploaded my project for some kind soul to take a look and point me at where i might be going wrong…

Networking Test Case

You’d need to set it up to 127.0.0.1 port 25000 to get it to run on a local machine.

Problem: If you start a server, and then start a client, observe how the ball bounces away from the server collision. Now observe how the same collision with the clients car results in the bull responding in a “dull” fashion (i.e. not bouncing away from the car)

thanks in advance…

I’m working with something quite similar right now. My guess is that there’s a certain lag which produces the following effet: two spheres are moving around on each client (or server, whatever). When they collide, due to the lag, they do it first on one machine. The collision is properly computed using physics, locally. However, they may have not collied yet on the other machine. So this other player updates its position, which reaches the machinewhere the collision occured and updates its position, altering the collision effect.

Does it make sense?

I think I have a solution for this. I’ll implement it this afternoon…

Clients should be configured to ignore collisions with other players. But not the server. In the server, they will collide properly. When this happens, the server will send an RPC to the colliding clients with the velocity after the collision (relative velocity).

EDIT: It works much better this way! :smile:

Hi guys, I dont´want to get out of line of what you are discussing, but maybe what I need as answer you already figured out easily.

So, I´m setting up my server/client and I would like to have a character controlled by the client (basic translations of position).

What I have is a character already in scene, with NetworkView. So, for both for client and server the character is there when scene starts, but in the scripts to move the client I use if Network.isClient to move it.

So when I connect client-server I can move the character around (in client side) but in the server it doesn´t move…

My question: how do I control client-side character and have server update his position?

Thanks in advance for any help!