After numeruous experiments and tweaking, I've achieved some really nice, experimental latency hiding for multiplayer physics!



This was recorded with 100ms worth of ping and 1% packet loss.
Sure, the boxes happen to jump back and forth (due to corrections of mispredictions), but it is still perfectly playable.
You can have dynamic shells, twisting motorcycles, monstrous trucks, erratic players - movement of all is smoothed out nicely.
The hits from my perspective are also more or less counted as they touch the other bodies.
I can assure you that the clients controlling other characters see the bullets hitting their bodies exactly, and not some wall elsewhere.
Also notice how there is no twitching at all when hugging other players (even though they are completely unpredictable).
The other characters are automatized clients with randomized movements (sigh sigh my artificial friends).

Okay then, somebody wants to 1v1 me in my game?

I will write a thorough article about the guts of my netcode in some future if the project receives enough attention.
Important are the pros and cons of my architectural decisions:

+ Making new gameplay features work through the network requires no effort. Praise component-based design, metaprogramming magic and input-based networking.
The exception to that is physics - here, you'd definitely want some dedicated lag concealment techniques. Well, it would still *work*, but reconciliating physical mispredictions without further care looks ugly on the screen.
+ Minimal bandwidth, owing again to determinism of the simulation. 99% of the time, only client inputs are transported.
You could have 10000 continuously moving crates and bullet shells and you'd still be perfectly able to host a server for a dozen of players on an average home network.
- Private state (for example inventory of remote characters) is hard and ugly. This is because to preserve determinism, the client needs the whole state of the simulation.
It will be easy to peep into somebody's backpack, at least in the early versions. I will someday come up with a nice workaround.
+ Impossible to cheat otherwise, unless you write hacks that roughly predict the future state of the simulation and direct the shots accordingly. I guess such hack would be very hard to get right,
but if somebody comes up with one, I hope they publish the source code so I can make it into a badass boss.
+ The player with less ping has the advantage, which I believe will come in handy in an MMO setup.
We totally don't want absurd bullets hitting us because a certain somebody with terrible connection is authoritative over his bullet hits.
- Some bullets however noticeably miss remote players, but it is only the case with bad connections. In particular, that effect is not proportional to the victim's ping, but to yours (the shooter's) only.
+ Exact extrapolation when the client inputs stop changing for RTT worth of steps. It means that if your victim keeps the move-forward button pressed for a while (perhaps escaping in panic),
your hit is scored exactly as it happened on your screen. This also means that if two or more friends ride trucks next to each other whilst continuously accelerating (so just holding one button without interruption),
all see the exact same positions/velocities as they happen on the server in the present (again regardless of the network conditions),
in particular when the cars are more ballistic (like trucks totally are) the players are easily able to align the fronts so as to ride in a formation.
+ Lagless experience (and I mean completely undistinguishable from local single-player) whenever remote players are far away from your character. Even with 3000ms worth of ping.
That's right, embrace flawless gameplay (including grinding with the deterministic AI) when playing alone at nights on the server (or when the others are somewhere completely else).

For now I will stick to these tradeoffs and will now just go about implementing new gameplay features.

Obviously, this also concludes my struggles with client-side input prediction.

Due to how Box2D manages state, that task seemed impossible halfway.
Imagine that the library does not provide a way to clone the physics world exactly, that is, along with all contact information, broadphase trees etc.
Sadly, I need this functionality because of what client-side prediction does: it takes the known, server-time game world (which is a bit in the past),
clones it and simulates it forward with the yet unacknowledged client commands in order to produce immediate response to the player's input.

I had no choice but to start hacking the inner workings of Box2D, [resulting in this monstrosity].
That *should* clone the b2World successfuly; in fact, it's been working well for a while, but it is one dangerous piece of code.
Notice I also had to write copy assignment operators for b2BroadPhase and b2DynamicTree. Hell of a ride.

Now while in theory I could simply clone all bodies and assign them the same velocities and positions,
it turns out (not exactly to my surprise) that simulating the clone yields completely different results than simulating the original.
Bottom line, glitchy as hell gameplay because of drastic mispredictions even with non-existent jitter and packet drop.
Contacts mean business.

Lastly, take a look at blueprints of experimental stuff we're working on. Straight from the developers' laboratory (excuse the captions in Polish, I guess they add to the enigmatic feel of this):



Stay tuned!