Be aware, if you're passing data in a structure, you obey alignment rules. So, have your 32-bit variables on 4 byte boundaries, 16-bit variable on 2 byte boundaries.
You can just set packing rules also to get rid of that. The overall effect on performance isn't that big of a deal.
I prefer binary writers and readers for handling packets. They allow for the concept of packet construction in a very clean way. I recommend reading the article for an introduction.
Now I need to worry about synchronising and controlling a stable tick rate to synchronise the nodes with.
Much easier than it sounds. Server needs to send a ping packet and create a timestamp. Then the client will get that and immediately in the receive callback send a pong packet. The server will get this and generate a timestamp and subtract the sent timestamp to receive a two way latency. When you send an update to the client send along this latency once in a while. Perform pings every few seconds to get an updated latency. (
You can perform statistical analysis on the latencies over time to grab the average if you want). When the client gets an update packet it can use the last known latency and simply divide that value by two to get a rough one-way latency. That means when a client gets an update packet at time t then it knows that the server updated at t.
Here's an example. Server sends a ping at 200 ms and receives from the client the pong at 273 ms. The latency is 273 - 200 = 73 ms. The server updates at 500 ms and sends along the 73 ms value. The client receives this packet and it thinks the server is at 480 ms lets say. It can calculate the current time in the server by doing 500 + 73 / 2 and get 537 ms. Lets say you were using extrapolation in your server code. The client could snap the entities to the current data in the packet which would reflect the time of the entities 73 / 2 = 37 ms ago. In order to directly correspond to the server's expected positions you'd do something like position + velocity * 37 ms to extrapolate the entities. (naive extrapolation. Works good for objects with inertia like space ships).
If you read up on the source networking article you'll see that not everyone uses extrapolation though since it can cause snapping effects. (You're assuming a unit keeps on a constant course for a few ms between the next reply).
Oh and I can't stress this enough. Draw ghost objects showing the object's server-time. Update it exactly whenever you get an update and extrapolate it to match as closely to the expected current location on the server. Performing simple interpolation is usually enough to correctly match the expected position. The problem occurs as you might imagine when the object is changing positions a lot. Also I've tested this and performing client-side collision detection and response makes a massive visual difference than just letting the server deal with it. (Other than the player walking into walls and snapping back). Ideally you should be extrapolating any interactions with the world you can.
Also I imagine for testing you're forced to add fake latency into the problem? I mean over LAN the latency is around 1 ms. How are you accomplishing that?