The project is approaching its deadline and MS3 with its related presentations and deliveries is to be held on Friday.
I have decided to stop working on the application and begin working on the report. The draft can be viewed in the MS3 repository, or by saving this link here. Any feedback is welcome! The draft will probably be continually updated until Friday at least.
As it seems to be customary, I’ve been sick a few days again, but it doesn’t seem to have affected too much this time around. I would have wanted to get more done, and I should probably have performed some more tests, but I feel that the project has gone on long enough now and that shifting to gathering all ideas and putting them into the report will be a good change of pace.
Might update this entry if I recall anything else later on, but if not I’ll just keep on typing ~
So, I just got some help from my pal Karl to test the game again. The tests were mostly to compare the new implementations of the interpolation/extrapolation and extrapolation with collision correction, but also to see if there were any apparent differences between TCP and UDP when using the respective techniques. Results can be seen in the form of sloppy notes here.
I’ve also made available a .ZIP archive of the game so that you may download and try it for yourself! Download it here.
As I might have mentioned earlier, I’ve moved my handling of the source onto github, and thusly also created the new page View the source in case you are interested in the code and underlying structure of how I’ve implemented it all.
EDIT: Just compiled a decent linux build (tested on 2 debian machines), and also updated the download .zip, so it should work for you linux-users too!
– I’ve added a new somewhat working extrapolation mode featuring collision-correction. It seems to be doing something, but it behaves a bit jerkily (which I had anticipated to some degree). The question is if it’s possible to improve it much more. I doubt it, but might look into it at least a day or two again.
– Added a proper new minimum update setting for the host, which sets minimum amount of milliseconds between each position-update. Using this I then tried out all modes I’ve been working on and noticed some more .. issues, or rather inherent requirements to my implementations which I was not entirely aware of before. For example both the Interpolation and Extrapolation will NOT work/look good if the synchronization delay is within a certain range. For Interpolation it should be positive or at least above the minimum update delay of the host. Similarly but inverted for Extrapolation, the sync delay has to be negative or at least below the minimum update delay of the host.
For a concrete example using Extrapolation consider the following:
– The Host has set minimum update delay to 200 ms, meaning we should get on average 5 updates per second.
– The time adjustment is set automatically on the client to -54 ms (This game-time concept has made me more confused than it probably should, not sure if it’s affecting anything really as this is just a visible indicator of a change it has done, not anything dynamic).
– Recommended sync delay (which in this case translates to the time we want to estimate in the future) should thus be around -200 or below for the extrapolation to work decently. With a sync delay of >200 ms it will detect a mismatch and only display static updates. At 150 ms the static updates will have a few extrapolation updates mixed in, giving erratic camera movment. The lower you go, the worse it gets, and at 0 ms delay the camera jumps each other frame. At -50 ms the algorithm manages to arrive at infinite numbers, requiring a hard reset in the code (which I added after discovering it now). Naturally that also means that the camera is rendered useless, trying to follow a player the estimator thinks is waaaaaaaay off from the map and all relevant entities/game content. -100 and -150 yield similarly unusable or erratic results, and only when reaching -200 does the camera and player entity return to where they should have been (after a few seconds of “correction”. Using a value of -200 causes visual artifacts and if lowering the value even more the errors will become even more obvious, but the movements also become a bit smoother.
A similar description of the above is also valid for the interpolation, except that the errors are not nearly that dramatic, but still not pleasant, and the interval is instead around 0 for static movment up to full interpolation at a sync delay of around 200.
Not sure if that made sense, but it serves its purpose of me documenting the tests anyway. Next up I will look through my plan and start evaluating what I’ve done so far vs. initial expectations, try and do some tests with simulated distance/lag and maybe try and investigate if I should try to improve the collision-correction or not (scoping issue, really). Anyway, I feel that I’m slowly starting to really understand what I’m working with. Have had a bit of a hard time keeping track of all numbers I threw in for the quick iterations, and some are maybe not used anymore (like the “Extrapolation smoothing duration” I had earlier with the erroneous previous solution).
Due to the last post, I wrote a unit test for the function and class in question, which made the errors painfully obvious, as can be seen here. I really should have gone this approach when we first noticed apparent bugs with the extrapolation, but I never thought it would be such a major design flaw.
Anyway, I figured the old code was not really usable, so I took and inspired myself from the picture I had devised for my initial presentation for how one could solve extrapolation and wrote new code, which seems to work as it should. Test results for the new code can be seen here.
The solution I use now uses a base vector for the extrapolation, which is set every time a new state is inserted into the Estimator object. Using this base and an estimated velocity (based on previous values), new estimations can be made. The trick when setting the estimated velocity is to take into consideration both the differences between the two latest inputs (the distance which would have been used for e.g. interpolation) but also the difference between our current/last estimation and the new input (which kind of symbolizes our error offset). It’s not a perfect solution, but it works, which the previous solution did NOT.
Next up is client-simulation in some form…
And because pictures are nice, a small update of the new level and ship that Andreas has made! Had to re-write the ObjLoader (last touched in 2013-07) for some reason because it failed to read the ship, but eh, yeah! :)
Decided to move my project source onto GitHub, so it is now publicly available for viewing:
After messing around with a new project, updating camera system and throwing in some improved synchronization of strings in the GUI, I realized that my little Estimator-class which handles all inter- and extrapolation was not working quite as intended.
The estimator classes are planned to have a cyclic array of states, where each state contains a vector (e.g. a position) and a timestamp. The thing with cyclic arrays is that when you reach the end, you are supposed to just restart from index 0. I had stupidly enough forgotten to mark a little boolean required for this to take effect properly (there were some other issues too, like which index to start at). Anyway, with that fixed both the static updates and Interpolation are now rid of the random off-frame issue which was one things I noted in the last playtest, but at that time attributed it to the testing software.
The extrapolator, however, requires even more work. I had been naive enough to think that just estimating a position would be enough. Or, well, I had some kind of interpolation/smoothing between the estimated values. The only issue was that the smoothing was poorly constructed and not working in the slightest bit as intended… Currently trying to add another interpolator for the estimated values, which I think should solve the problem…
Since I was unsure about if I had done UDP right, I wanted to get hold of a good testing tool. Got linked this little awesome tool by Johannes (cheers!) that seems to be exactly what I’ve been looking for!
All tests were conducted using two clients on localhost, and applying all settings on all ipv4 sockets, both inbound and outbound.
Results are a available here as a raw .txt file since I cba to format it in html for now. Further tests will probably end up in the same directory later on, so I might add a link to it on the right below the MS links.
TL;DR of the tests is that UDP is working significantly better than TCP using certain options, proving that the implementation is working to some degree.
The tests also made a point that client simulation and control is needed to overcome the greater network issues.