Thoughts on Client-side prediction

The client-side prediction in our game is pretty good at the moment, previously I didn’t have any smoothing for correcting the rotation but merely snapped it to the value. This did lead to a pretty annoying jitter for the clients, with smoothing it is much less of a problem. Another thing I’ve started looking into is what the clients can simulate to improve their predictions. Since we make use of “Hollywood physics” where the resulting energy of a collision is somewhat bigger than it should be ( for player-on-player collisions we double the energy ), previously only the server did this and as a result the clients prediction could fall off. In hindsight there really was no good reason to keep this server side only, so now the clients run it as well. I’m will do a check to see if there is any similar stuff elsewhere in the code.

One thing I have been thinking about is the necessity to store and replay the input, what the input does is mainly alter the rotation or velocity in some manner. One could simply save these changes instead, but I guess an update from the server about your state some time back could alter what the input would do. For example maybe you can’t jump because of some debuff.

And then there is the latency, so far it has mainly been used in a LAN environment. We did make a small test with Unity’s network emulation set to dial-up which means a bunch of added latency and dropped packets, and things worked but the test wasn’t very scientific to say the least. More thorough testing will be required before releasing the game into the wild.

Til next time

Plenty of the good stuff

…but less of the important stuff.

The last 2 weeks most of my time has been devoted to the game and less so to my own project. On the bright side the client-side prediction that I’ve spent some more time refining is progress on both fronts, and the same can be said for many other things. Still, there is a lot of things that I would have liked to finished by now when it comes to syncing rigid bodies, compression and prioritization being the biggest things on my list. Hopefully I will be able to find some time to get those 2 done properly

Bombs away!

I was curious on how the current network physics would work with something more than just the players around, so I set out and created a simple projectile that the player could fire in a rapid fashion. These “shells” rolls around in the world and explode after a set time, pushing nearby objects away but don’t deal any actual damage.

Here’s the result

Now, that was a single-player scenario, but I did try out with 4 players shooting like crazy. The results were not that surprising, the rapid spawn of a crap ton of projectiles did cause the simulation to break apart a little, even on a local connection. One could see some shells blinking to their correct position or taking weird turns mid-air. Part of the issue is that my current extrapolation method is extremely simple, it merely uses the velocity and position of the latest received state to determine where it should be. If the difference is small enough it does a smooth interpolation of it, otherwise it snaps the position. The reason for leaving out gravity was because it lead to bothersome results at higher latencies in my test environment, although the real error was something else which I mentioned in my previous blog.

Still gravity is somewhat problematic since I can’t run collision detection in a good way, and gravity will try to pull objects through the ground all the time. To solve this I’m thinking of saving away the changes in and position velocity caused by objects colliding with each other. This will have to be done in retrospect of course, so before adding a new state I need to alter the last added state. The whole method does sound a little weird, using information from the wrong path to guess how the corrected path should look like. Still the differences are usually pretty small, so I think it will yield some improvement.

Some real nice progress

Since milestone 2 I have been working hard with client-side prediction and trying to figure out some way to make it work. There was one thing that was bothering me and didn’t make sense, with a lot of lag the spheres could “predict” themselves through the ground quite a bit. Now getting through the ground wasn’t the problem, with my simple rewind and fast forward that had no collision detection I knew this could happen, but they got way to far ahead. The gravity was way too strong, but the value for it was right so what was actually wrong? I tried to remove it all together and I still had issues with the clients being way off the server, so I started going through the rewind and replay step by step. Sure enough there was something quite wrong with it, when replaying I didn’t update the time properly which lead to the time delta being calculated as the time difference between the current state and the first state. Obviously it shall be between the current and previous state. I spent some more time to find errors and polishing things up before going to the next step which was adding it to the actual game.

As some would say, “Shit’s about to get real”

Previously I had discovered that forces or impulses don’t have an immediate effect on the rigidbody’s velocity in Unity, this meant I had to rework our vehicle model to work directly on the velocity vector. This was already done and we had game tested the new model and everything so that was all good. After thinking through a good deal about how I should plug everything in and then actually doing it, I pressed play to see what would happen. I don’t recall exactly what the editor said but it had something to do with a recommendation not to use absurdly high floating point values for things like position, the play screen gave me a nice picture of the sky box.

Damn

What was wrong? Previously the server moved the player to the correct spawn point and updated the client about the new state, all very simple. With client-side prediction these sort of forced positioning could be done through an RPC, or you are somewhat oblivious to the situation and are counting on large disagreements between client and server are sorted out by snapping the player to the correct position per normal client-side prediction. The first is probably for the better, but as you might guess I was doing the latter. The snapping SHOULD have worked, unless there was something wrong with it. At the moment I’m not sure if the issue was in the snapping code or if it was another thing I fixed later. You see in my test environment everything was local so I was using the regular time which worked well, when I moved things over to the game and to a network environment I kinda forgot to switch to the synchronized network time that is available. It would have worked if everybody started their game at the same time but that might be to much to ask. I found another great issue where I turned the vehicle etc through the transforms rotation but saved away the rigidbody’s rotation, these are synchronized at set times, this caused some nice issues when rewinding and replaying.

With these issues and bunch of other stuff out of the way it started to actually work, the clients moved on their own and did corrections with updates. At the moment, things are actually looking quite nice. The biggest issue right now actually isĀ  that all the others players are so far behind since they interpolate to the latest received state. This means that they can and will hit you before you even see them šŸ˜›

There is a lot left to do though, for the current version I store the player input and physics state and used these for rewinding and replaying. The internal state of the vehicle is also necessary and I’m also thinking of storing any alterations in velocity caused by the physics simulation. Then there is the whole business of extrapolating the other players behaviour, that should be quite fun.

All in all, things are looking quite good and I’m in quite the better mood regarding the whole situation than I was for milestone 2. Turns out some things are easier to predict than others.

MS 2 Not all sunshine and roses…

…in Unity land. The overall experience with Unity has been a very pleasant one, but through my work these last 2 weeks I’ve started to feel some frustration towards it. I’ve made a document here document where I have summed up my results and explained some of the issues I currently have and how I’m thinking of solving them.PureClientServerBallsPicture of my test environment for a client server physics simulation, this was later added into the game for the player vehicles. Next, upgrading to client-side prediction.

Sharp week

C Sharp week actually. Prior to this project I used UnityScript when I worked in the Unity game engine, it is basically Javascript with a few alterations. It wasn’t that bad for simpler things and experimenting, but it became somewhat of a burden when things got bigger and more complex. Others in the group had similar opinions so we decided to go with C# for ImpactO.

So how is it? It is pretty good I have to say, my main programming language is C++ and the two of them are very (very) similar. Beforehand I had a somewhat negative opinion about C# given that for a long time it was limited to the Windows platform and XNA, I saw little point in learning a language with such a limitation. That went away with the Mono platform though and now you can use it in Unity and a whole bunch of other places.

The differences between C++ and C# are quite interesting at some points, structs and classes being one of them. In C++, the only “real” difference between them is that structs has public membership as default and classes private. In C#, structs are a value type and classes a reference type. The default way to work with classes in C# is with pointers and references, while in C++ it is to make copies of object. Not that pointers or references are uncommon when working with C++ classes, it is how I mostly use them. Same thing with structs, many use them as data “struct”ures without any functions. I guess someone at the C# development team took note of how classes and structs are usually used in C++ and figured that default membership value shouldn’t be the only thing separating classes and structs.

So on a final note, if you are starting out with Unity it can be very tempting to use UnityScript, but I highly recommend to use C# instead. I find it has more structure to it and all these good annoying programming rules that encourages you to think a little extra before coding, which is a good thing in my opinion.

Still rolling!

And so it begins, finally! I have been poking around a little with controls for the vehicle and some other stuff the last couple of months on my spare time, but now I can work on it full time (and maybe a little more). I’m once again in charge of the vehicle model and controls, also I’m going to implement a client-server model with client-side prediction for our networking. In our previous game we had a peer-to-peer model of sort which ended up somewhat messy and unstable, this time around our networking is going to be much much better ( We have had plenty of time to think things through ).

The initial results from the player controls are quite promising, there is significantly less “bouncing” now and we can have a much higher speed without losing control completely. Increasing the speed did make it more difficult to hit each other so we are still keeping at moderate levels. Speed isn’t everything though, we have a lot of exciting ideas in the work that will be presented as the project rolls forward šŸ˜‰

Til next time /Felix
ImpactOBalls