Skip to content

romanchekashov/MultiplayerGames

Repository files navigation

Multiplayer games

Authoritive server

  • Client sends inputs, keys pressed (commands) to server (prefer: UDP but care about reliability)
    • Each UDP packet contains new commands and replicates previous commands (so, even if some packets are lost, the server should be able to process all the client commands)
    • Client sends inputs with a timestamp (to calculate latency)
    • Server acknowledges client about received commands so client can remove them from the buffer
    • Client-Side Prediction: Client predicts the game state based on the commands it sends to the server. So client can move or take an action instantly!
    • Received game state confirms that the client predicted it correctly. But if client made miss-prediction, it's state will be corrected and user may see that!
  • Server calculates game state(whole world state (snapshot) should be sent in 1 UDP packet: use delta compression) and sends it to all clients (prefer: UDP)
    • Because everything inside 1 UDP packet there is no problem with packet loss
    • Client interpolate between snapshots to smooth movement (minimum 2 snapshots are needed to interpolate)
    • Server has current (present) state! But clients see previous (past) state!
    • Server has a Snapshot Buffer to store latest snapshots (0ms, 50ms, 100ms, 150ms, 200ms, 250ms) in order to improve Hit detection accuracy! For example: User hits an object in frame 42. Server takes 2 latest snapshots (0ms, 50ms) and make same as client interpolation to frame 42 and process a hit detection at that frame! So user can hit the target which they actually see.

System design overview:

  1. Game Server
  2. Middleware Communication Server
  3. Game Client

1. Game Server

Defold headless game

  • On server game should have collision object without sprites
  • https://forum.defold.com/t/dmengine-headless-all-flags-list/73914/3
  • Also, it’s also probably likely that you want to use a bundled game, in which case there are no loose file, but a few archives (.arcd, .arci)
  • And for content, I would probably scale down all textures to e.g. 2x2 size.
  • All in all, I would use a separate .settings file (same format as game.project) to setup the server settings (you can specify the server.collection as the bootstrap there):
java -jar bob.jar clean build --archive bundle --settings headless.settings --bo bundle_headless 

2. Middleware Communication Server

Communication protocols:

Websockets:

WebTransport HTTP/3 + QUIC (datagrams over UDP):

./install.sh # python dependencies
./run.sh # webtransport_server.py
Resources

Lua language 5.1

Python language 3.10

python3.10 -m venv venv # set virtual environment
python3.10 -m pip freeze > requirements.txt # manage dependencies versions

python3.10 -m pip install aioquic
python3.10 -m pip install websockets
python3.10 webtransport_server.py # run
Resources

Deploy:

docker-compose --env-file .env.local up --build -d # build and start Dockers
docker-compose --env-file .env.local up -d         # start Dockers without rebuild
docker-compose --env-file .env.local down          # stop Dockers
Resources

Resources:

References Papers:

References from Godot Engine: