The idea: every client sends out the actions it wants to do to the server; the server schedules commands from all players into 'ticks'; the clients receive tick information and call world:update() with a fixed timestep, therefore ending up with the same result as all other clients. If new players connect (they can connect and disconnect whenever they want), the game state is serialized and synchronized on all clients again.
Cross-platform network play sadly doesn't work, unless someone builds a gcc version for Windows... not sure if Linux<->Mac works, but it should if similar flags are given to the compiler. Workaround for Linux is to run love through wine when connecting to/from a Windows client. The problem comes from floating point calculations, they tend differ from CPU to CPU (unless the right compiler flags are used), and from compiler to compiler (different optimization styles end up in different calculation orders).
And finally, why I do löve this approach:
Tiny bandwidth! Only commands are sent on the network... it averages out to something like 0.5 kilobytes per second.
You can debug the network stream by simply connecting to it (e.g. telnet or PuTTY to localhost port 12345), or see the bandwidth used with something like "wget 127.0.0.1:12345" (I know, it's cheesy, but hey... it works!)
You can save a log with a command like: telnet 127.0.0.1 > replay.log - and you can then replay it later! (possibly on a different machine, too)
The server right now is simply a command relayer, it doesn't need to know anything about physics... so you can even put it in a different thread (or process)
The license is public domain; feel free to take and use any parts of this example in your own project. No credit needed. What I'm particularly proud of is the marshaller/RPC system... a client can use the syntax: sendCall.someFunction(1, 2, 3) and the function called "someFunction" will end up being validated and called with those parameters on all connected clients... what I'm not proud of is main.lua, don't look at that please.
Like I said, there's no real game yet, but if you feel like testing it, here are the keys:
- w/a/s/d - move
RMB (hold) - guide vehicle's angle with the mouse
LMB - fire laser, or unhook grapple, or materialize the selected item. Click near an existing object (including yourself) to weld to a point on it.
1/2 (or click on the bottom bar) - select stuff to materialize (deselect by choosing an empty item)
mouse wheel scroll - change the connection point used when welding objects
r (hold) - click on an object in the world to remove it
e - fire grappling hook (pointless right now, but great for testing synchronization levels among clients )
o - serialize and send the game state to all connected clients (in case someone gets desynchronized somehow)
q - quit