Facing the multiplayer physics conundrum

Hi monkeys :).
I’m facing the multiplayer physics conundrum… and it’s hard on my lil head.

I’m wondering how do I find, on the server, where a spatial (with a controller) ends up, depending on the delay?

  • client tells server what it wants to do
  • server calculates direction and velocity
  • server needs to check where the mobile would end, depending on the physics environment

But how to do that last point using bullet? I mean, I don’t want to start raytracing and calculating all the movements myself… bullet is more suited for that than I’ll ever be.

If I receive a message to go forward (with no speed change for simplicity) that was issued a 10th of a second earlier, what should the server do with that? Is there a way to immediately know where the vehicle would end up?
Or do I need to “play” the movement on the server for the duration of the delay to determine where it would end and only then send the new position to the client? Or play it for the duration of the delay and send new locations every interval of time? Or a’m I missing a nifty method?

Sorry for such a basic question, but I want to avoid going all the way and end up seeing it was a stoupid way of doing it :D. A little pointer would be great ^^.
NB: single player physics was easy due to jme features.

“all you have to do to avoid the “snapping” is ramping the tpf for the physics space”.

Found in a jme thread. This is interesting. Oooooh, may be my solution, or part of it.

Not directly related but these articles may be useful:

They usually require a few read-throughs to really get it. I would offer that if you don’t understand the concepts in those articles that real time networking is probably too hard at this stage.

I read those articles a long time ago and was reading them again before checking for an eventual answer :D… yah, they are really great material.

I get the concepts… somewhat haha. I agree with you that I am over my head here… I’m still gonna try :D.

But it opens whoop cans of new questions.

Developing a lil game about vehicles running around tubes (mixed with models of passages made in blender). Aiming for a seed system that would allow random circuits to be generated. Ofc, non-random circuits would be available too.
I’m currently thinking see if I can resolve move actions when received (using big tpfs) and remove them from the queue immediately, sending back a location to the clients (+current acceleration and direction).
Means those vehicles would continue moving on the server (and clients) and server would only send new positions to clients following it’s calculated results from move orders from clients. Valve doesn’t extrapolate opponents movements, but guess I need to do that with vehicles?

I guess I’d need screenshots with locations and move orders, at least for every issued action, but those articles seem to point towards needing more than that.

Maybe I’ll start with a simpler system where the server treats vehicles as non tangibles and simply directly resolve all orders immediately and sends the results to all clients.
I’ll add screenshots and dealing with the other vehicles later on… if I manage the simpler approach.
Mmmm… that would mean the server would be always telling the client that it is less far than it is. Bah, we’ll see.

Anyway, thx for your answer :).

As the article describes, the clients are rendering at a period some milliseconds ago (game time). The server is authoritative. All physics happens there and state updates are sent to the clients. The clients interpolate between the known state based on that time delay.

Extrapolation is a million times more complicated and ultimately buggy than interpolation. You will have no end of glitches. Just interpolate between known state and you should be fine.

1 Like

Networked games are ten times as hard to write as non-networked ones. And that’s for people with experience…

I strongly suggest your first few games be single player until you have more experience…

1 Like

I had kind of forgotten about the interpolation going on on the client because I was planning on doing such stuff later on, but thx, it does nicely correct the delays.
By extrapolate, I meant: letting the other vehicles follow their direction until further notice. Which is probably the opposite of what that means.

Trying to put my first ES up at the same time… I agree, this can only end up in tears :D.

@loopies said: By extrapolate, I meant: letting the other vehicles follow their direction until further notice. Which is probably the opposite of what that means.

That’s what it means… but generally in reference to the client. So if the vehicle was driving 80 miles an hour north it would continue doing so even if network state wasn’t arriving. Then you have to figure out what to do with it when network state catches up and it turns out the vehicle turned sometime back.

Versus interpolation where you have already two known good states and then just interpolate between them… you aren’t trying to extrapolate some predicted state.

If writing a networked game is 10x harder than a single player game… writing a networked game with prediction is 10000x harder.

1 Like

Well, got my multiplayer and entity system in place.

By that I mean people can connect to a lobby that displays players present, cars and maps available (and able to choose which) + chat and a player can start the game and the circuit is built and player cars are added.

Players can give orders to their car, that are transformed into components the systems use to move the car around.
Everything is in place to start communicating move orders to the server, but I’m still reading those valve documents and trying to understand them… will take a while :D.

Anyway, here is my architecture in case it helps someone or someone wants to point to something wrong in it:

Why is anything other than the network layer updating your components?

Sometimes that’s necessary for responsiveness…but make sure its an informed design decision and aware of the consequences every time it happens…

1 Like

My systems remove components and could potentially add components. Not adding components through systems currently but thought it would be ok from what I read here?
My app state listener adds components representing move (or other) orders.

Oh, you meant the play game app state listener should instead send move (and so on) orders to the server and components would only be added when the server sends back those move orders? Ooooo crap, more questions :.

Back to valve documents… really need to grasp them :D.

I don’t know if that’s how valve do things. It’s about keeping a clean architecture though.

You have command processing->message to server->server

Server is authoritative world state.

Server->message to client->client displays world

Now the ideal scenario has the server running the authoritative state and then the client just displays what the server tells it too. That gives you the simplest and cleanest architecture. You may have temporal displacement ‘lag’ but the world is consistent everywhere. The only variable is “when” players are, you know at least that their worlds are all identical for a given “when”.

Unfortunately that’s not always possible though as latency means your client becomes unplayable. At that point you have to “short circuit” your architecture and connect client inputs directly to your clients displayed world. But now you have a difference between what the client is displaying and the authoritative state.the server is maintaining.

So in the first case you need only lag compensation (One of the lag compensation articles from valve is all about looking at people shooting and saying “when they shot based on their view they hit so we should give them a hit”. ), but movements may feel sluggish etc as you have to wait for a server response for each move. Depending on game style that may or may not be a problem.

In the second case (with the shortcut) you solve the lag by running at least part of the simulation locally - however now you have difference not just in time but with actual world state - and that becomes a much bigger job to resolve.

For example your client reaches door, opens door, sees the other side. Server on the other hand says “didn’t quite reach door, can’t open door, door is still closed”. How do you resolve that? Do certain actions wait for server responses? Does the door slam closed again? etc, etc.

1 Like

Thx for the answer (and all others)… I’m pretty much out of my area here :D.

Anyway, from the valve documents I got that they partially combat latency on the client by having the player update it’s position every x by taking the last position/rotation given by the server and adding to that the results the commands the client issued in-between would modify it by. I was thinking that maybe I could immediately (by the ES), apply those commands and every x, take the new position sent by the server and apply the commands to it and update it’s position then. Tbh, I’m still not comfortable with those valve documents, but they are indeed great… so I’m going step by step.

Anyway, currently, all it does is every x send the new position to the server that sends it back to all clients.
Have only tested it on the same computer and it goes very well. Not choppy at all and only consumes less than 3% of my cpu (on an average computer (2 years old))… while playing music though a web radio. Jmonkey seems to be begging for me to throw a ton more at it.

Ofc, through internet, which I am aiming for, the latencies will probably become a real problem. The server is not authoritative currently and collisions are resolved on the clients… so still got quite a path to go. But I’m slowly understanding what I need to do.

The ES really makes all this easier and cleaner… even though ES strengths lies elsewhere. I’m very happy of Artemis. Only regrets I have is that it doesn’t allow multiple components of the same type and setting the entity ids.

I’ll stay quiet for a while, promised :D.

FYI: you don’t need multiple components of the same type on the same entity. It’s almost always a sign that you are missing an entity.

1 Like

Also, really the essence of an ES is so simple you just want to implement it yourself instead of tying yourself to the limitations and ways of artemis :slight_smile:

1 Like

Depending on the style of game non-authoritativeness of the server may not be an issue - but in any sort of PvP situation you really need to consider both that and things like map hacks etc. Getting the architecture right in the first place can massively reduce the impact of map hacks, ghost hacks, etc. For example if the collision detection is done on the client what stops a hacked client flying or running through walls?

1 Like

But if the server is running on one of the player’s computers then the server is no more trustworthy than the players are…

Thx for your answers, I’ll keep them in mind :).

I’ve tried my lil start of a game with a friend through internet and didn’t notice any latency problem. And currently, I’m only sending updates 6 times a second. Think I’ll forget about latency problems for now.

Also, I wanted to protect my code from tampering/looking into it.

I’ve tried obfuscating and the exe way.

Need to be able to launch a server and a client.

I managed to make the obfuscating work in JME by echoing the run.classpath variable, correcting it manually (":C" -> “;C” and ":smiley: -> “;D” + removing the part about the assets) and setting the new paths to a new variable and feeding it to the -create-library-property target instead of run.classpath. I would have automatized that process, but seems ant doesn’t offer me lots of tools for that.

Problem is that then, Proguard, while not renaming the classes implementing ScreenController (which is good), ended emptying them for some reason (I used JD-Gui for checking their content), so the nifty interfaces can’t react anymore. Didn’t find a way to tell Proguard not to mess there.

Exe, generated by jme:
The resulting exe seems to be special in the sense that you can’t double click twice on it and have two applications running.
Also seemed to not be able to use arguments when called as follows:
arguments[0] = “MyGame.exe”;
arguments[1] = “server”;
Process p = Runtime.getRuntime().exec(arguments);
Actually, neither seemed to get them when called by a bat file.

So currently, I’m compiling twice the code, once with the client as main class and once with the server (projet properties/run). Since all the big files are contained in the assets, it adds less than 300k to the whole, so not a real problem.
Works fine, but it does mean that I can’t launch two clients on the same os from the .exe’s while I’m able to do that in dev mode.

Any idea why the exe doesn’t seem to get the parameters it is called with?
Any idea why I can’t launch such generated exe’s twice?

Nothing really blocking here… but would love to get that fixed.

On the bright side, did some refactoring and can now mix different cars and different hovercrafts.

Just remember that obfuscating will slow things down. It won’t stop anyone who really wants to hack your game…
…and the more popular your game becomes the more people will be trying to hack it and the more determined they will be…

1 Like
@zarch said: Just remember that obfuscating will slow things down.
Quite the contrary actually. Definitely not slower. I agree obfuscating is silly though, you don't stop the people you want to stop.
1 Like