I think I might’ve gotten slightly hooked to this blog-like approach. There’s something to reporting about your own progress and having it “ready-to-share” at any time. To be honest, it feels quite liberating, motivating but also scary at the same time. Anyway, have some music:
It’s a track I rediscovered from Supergiant’s Bastion. It’s not even the best track on the soundtrack. But I think this goes well with the rest of this article.
Yesterday, while I was working on an updated version of my “death ball” code. I kept banging my head into weird behavioural glitches on the client side which for the life of me I couldn’t figure out.
The problem was mostly due to a different approach I took when writing this behaviour. This time around, I’m actually trying to use client-side prediction, and unity’s physics engine is suspect to messing up my prediction results. But everything I’ve observed so far is way to erratic to just allow me to point the finger at Unity. No, I’d made a big mistake, and I couldn’t figure out where the fault lied.
I started out naively, attempting to swap some variables, or by giving the client object an alternative configuration. I actually spent some time frustrated, not solving the problem. I finally came to my senses when I started writing some code visualising as the data I was working with. Data isn’t always as deceptive as your eyes, and they allow you to study things case by case, rather than just “when they happen”.
This mess of lines and arrows is the info I need to determine where the flaw in my model lies. I’ve got a few more of these in store, but this one will serve as a reference and it has given me great insight in what my program was actually doing.
I have a simple scene in which a ball is bouncing around a canvas. My server sends the position and direction of that ball to all clients at a rate of 20 times per second. ( A modern FPS has a send rate of about 25 IIRC ). The difficulty is that these little data packets take a small amount of time to reach the clients causing them to lag behind by default. A problem that is currently inevitable.
This forces me to take action on multiple fronts to have the game APPEAR to send things instantly ( I’m not going to go into detail about this at this point ).
My client, that is updating about 60 times per second, receives only 25 packages per second. That means that my client has to fill in the gaps in between packages itself.
To visualise what was happening I’m drawing the following things:
1. White crosses with yellow arrows:
These represent my packet buffer. I draw every packet in my buffer ( I keep all the packages of the last passed second for the moment )
2. Cyan arrows
Representing the translation the ball would like to make in its update cycle.
3. Blue lines with white segment markers
The path the ball is actually following, segmented by white marks, so that I can identify update cycles.
4. Red Lines
Contact point & normal of a collision. Though in the image above, one is missing. ( Already a clue to the cause of the problem )
I made sure that these lines don’t overlap. From the image above you can easily deduct a few problems. I’ve got a reflection normal that points DOWN for some reason and I’ve got an update cycle that wants to JUMP way too far forward.
Armed with this info I can now more easily track down bugs.
Now I guess I have learned something from this, although I thought I’d already learned this lesson before.
Visualising the data is a great tool to understanding your program’s behaviour. Secondly, you don’t want to clutter up your scripts with debug drawing code. If at all possible, you should have a separate entity observe your object ( or model ) and draw the debug info FOR it.
Not only does it make your code more flexible, it also keeps your coding files clean.
I hope there is some coherence to this rambling,