With the new networking structure in place, making everything look nice is important. In my last post, I explained the idea behind how our network code works. In this post, I will explain the details that made everything come together.
First off, a quick recap. We are sending data from the client to the server on a 20Hz frequency, whch means the client is sending data 20 times each second, or roughly once every three frames. The server grabs this data and relays it on to all other clients. Ignoring latency for a moment, that means that each client is receiving new position data every third frame. Between these updates, the other tanks will just sit on the map and then jump to their new position. This is really ugly. To solve that problem, we did two things:
- Introduce velocity
- Use velocity to move the tank in lieu of data
I am well aware that this post is late. I was out of the province for a few weeks and hadn't the time to write. I rewrote the networking code several weeks ago and it works pretty well! Let me explain what I did.
So first off I want to explain my old networking code, and why it sucked. My first ever attempt at writing network code started a few years ago. What I ended up doing was serializing data every frame and sending it to the server. I serialized everything in a text-literal way, which is to say, I used a big ol' JSON string as my packet. Yeah. When I realize this was sending copious amounts of data over the network, I decided to try a "smarter" approach which was then copied over to LÖVE und PANZER. This approach was event-driven. Instead of sending data values
I have some good news, and some bad news. Which would you like to hear first? The bad news? Okay. The bad news is... we broke it. However, the good news is we added several new features and fixes, so let me explain those first!
First off, we felt it was important to add bounding boxes to all of our objects. Bounding boxes are very useful for things like collision, be it two players ramming into each other, or one player shooting another. We decided right away that it was important for each mesh to have its own bounding box, that way shooting the air between the cannon and the hull wouldn't cause a hit. The way we created the bounding box was quite straight forward: While loading the IQE model, we looped through each vertex and checked if that vertex had a larger or smaller x, y, or z
Over the past few weeks, development has slowed down a bit while both Colby and myself had several other obligations to deal with. While development slowed, it did not stop entirely and we did manage to squeeze out several new features and fixes, both big and small.
After I added multiplayer support to our game, I decided to crack open Blender and rescale our tank model to be appropriately sized. I jumped on Wikipedia and looked up the size of the hull on a Panzerkampfwagen IV and scaled our tank up to match the length. This of course broke everything.
With the tank now a realistic size, the camera was in the wrong place, the terrain was too small, and the bilinear interpolation no longer worked smoothly. The quickest fix for the camera was to simply multiply the offset position by the tank scalar. While this worked, it didn't quite
A few months ago I started working on a commercial game for Binary Cocoa called BOCO. BOCO is a simple 2D puzzle/board game designed to be played with friends. One of the main problems I was faced with when working on BOCO was for each face on the gameboard to be aware of its neighbours. I wrote a blog post about solving this problem over on Binary Cocoa's dev blog. You can check that post out here, it's a good read.
TL;DR: Winged Edge is super useful and I wrote a pure Lua library for it.