To get the boat, players, and any other physics objects to sync cleanly between clients, I had to learn all the different ways you can go about doing this. After looking online, many people agreed that this was the de-facto blog series on how to do networked physics in video games. He gives a couple of different strategies, many of which are still used today.

I ended up coming up with the following strategy that took pieces from some of the strategies he listed. The host is the single source of truth, and any information that needs to be synced to the clients, must first be given to the host or already be calculated by the host, and then sent to the clients via the host.

The velocity of a given object from the host is synced to the client as often as possible, with no buffer. Then, the client performs physics on the object just like the host would, using the linear and angular velocities given from the host, so this acts as client side prediction. Finally, if the client's objects get too out of sync with the rotation or position of host's objects, then the player's object LERP's (linearly interpolates) to the position that the host's object is at. If the client stops receiving packets from the host for any reason, they will still continue to perform the physics calculations on the object independent of the host in an effort to 'predict' where the host's object is, and will sync back to the host if needed when the next packet is received from the host.

The following GIF is showing off the host at the top right, and the client at the bottom right. The network synchronizer that syncs the boat's rotation, velocity, and position, has been set so that there's a 1 second delay between each packet being sent. With that delay, we end up with a rough simulation of very high packet loss on the client. Notice how when the boat hits the rock, the boat on the client's window (bottom right window) seems to stutter momentarily. That 'stutter' is the client's boat receiving the packets from the host's boat, and syncing its position to the few data points the host is sending to the client.

As you can see, it's hardly noticeable on the client, and this is a pretty bad networking scenario too! This method works really well with our game, due to the fact that the majority of the interactions that occur on the boat can be 'predicted' since they're mostly physics interactions with the world. Where this method doesn't work as well, however, is when a client isn't reviving packets, and one of other players start rowing or move the boat in some way. This will make the bad-internet-client's boat get out of sync with the host's boat, and it will not be able to sync back until the host sends a new packet. However, the LERPing code that I wrote will cleanly sync the client's boat position to the host's position. So while this method allows desyncing when player behavior occurs, I'm not sure what method can predict player behavior.

For syncing player positions and rotations, I do basically everything the same as I just explained for the boat, but make sure to have players report their states to the host, and the host distributes that information to the rest of the clients. This way the host stays as the source of truth, so there's always a source for clients to fallback to and use to determine when they're out of sync.