Example Projects
2D Bomber (Godot)

This guide requires access to the Rivet private beta.

Request access here.

🚧 This documentation page is a work in progress 🚧

This guide will walk you through creating and deploying a multiplayer game with Godot 4.

If you are using Godot 3, please be aware that some details may be different.


Overview

Godot provides great multiplayer capabilities out of the box. We’ll be using Godot’s built-in networking to build a server-authoritative multiplayer game on top of Rivet.

Godot supports ENet, WebSocket, and WebRTC transports. We’ll be using ENet for this tutorial, but it’s easy to swap out.


Step 1: Initialize project

Make sure you have installed the Rivet CLI here.

Clone https://github.com/rivet-gg/example-godot-bomber

Configure Rivet

Copy the following to rivet.version.toml:

rivet.version.toml
[matchmaker]
	max_players = 12

[matchmaker.regions]
	lnd-sfo = {}
	lnd-fra = {}

[matchmaker.docker]
	dockerfile = "Dockerfile"
	ports.default = { port = 10567, protocol = "udp" }

[matchmaker.game_modes]
	default = {}

Run the following command to link your game to Rivet. If you haven’t already, create a new game at this step.

rivet init --recommend

Step 2: Install the Rivet plugin in Godot

Installation instructions

Step 3: Update game code

Add the following to the top of _ready in gamestate.gd:

gamestate.gd
func _ready():
	RivetHelper.start_server.connect(start_server)
	RivetHelper.setup_multiplayer()

	# ...etc...

Move the code to start the server:

gamestate.gd
func start_server():
	print("Starting server on %s" % DEFAULT_PORT)
	
	peer = ENetMultiplayerPeer.new()
	peer.create_server(DEFAULT_PORT, MAX_PEERS)
	multiplayer.set_multiplayer_peer(peer)

Update join_game to ask Rivet which lobby to connect to:

gamestate.gd
func join_game(new_player_name):
	player_name = new_player_name
	
	RivetClient.find_lobby({
		"game_modes": ["default"]
	}, _lobby_found, _lobby_find_failed)


func _lobby_found(response):
	RivetHelper.set_player_token(response.player.token)
	
	var port = response.ports.default
	print("Connecting to ", port.host)
	
	peer = ENetMultiplayerPeer.new()
	peer.create_client(port.hostname, port.port)
	multiplayer.set_multiplayer_peer(peer)

func _lobby_find_failed(error):
	game_error.emit(error)

Test locally

Open the Rivet panel in the bottom left and click Start Server. Then click the play button in the top right to start the client. You should be able to join the lobby.

Step 4: Deploy to Rivet

Write Dockerfile

Write the following Dockerfile

Dockerfile
# MARK: Builder
FROM rivetgg/godot:4.0.2 AS builder
WORKDIR /app
COPY . .
RUN mkdir -p build/linux \
    && godot -v --export-release "Linux/X11" --headless ./build/linux/game.x86_64

# MARK: Runner
FROM ubuntu:22.04
RUN apt update -y \
    && apt install -y expect-dev \
    && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/build/linux/ /app

# Unbuffer output so the logs get flushed
CMD ["sh", "-c", "unbuffer /app/game.x86_64 --verbose --headless -- --server | cat"]

Deploy game

Run the following command to deploy your game to Rivet:

rivet deploy -n prod

Create public token

We’ve been using development tokens up until this point. Now that our game is deployed, we can create a

Create a public token in the Rivet Dashboard:

Create public token

Now pass that token to your game by adding the following code to gamestate.gd:

gamestate.gd
func _ready():
	# Paste token here
	RivetClient.set_token("pub_prod.xxxx.xxxx")

Run the client again and it will connect to the production servers. Remove this line when developing locally.