Multiplayer - Server and Client in the same Scene Tree

Godot has the really cool feature that you can have a Server and a Client in the same scene tree.
This is very useful for testing the game without running multiple instances.
This is documented here

However if you are like me, and you are easily confused by the myriad of multiplayer nodes you might struggle to set it up. It took me a few hours until I realized my mistake.

You need to create a new SceneMultiplayer Node and set it to the scene tree with
set_multiplayer. Yes that is exactly what the documentation says but it took me a while that it says MultiplayerAPI which is different to MultiplayerPeer mentioned just below.

Here is a demo snippet

extends Node

# --------------

const TEST_PORT := 28080
const LOCAL_IP := "localhost"

# --------------

class RpcTester extends Node:

	var sent: bool = false
	var received: bool = false

	func send():
		receive.rpc()
		sent = true

	@rpc("any_peer", "reliable", "call_remote")
	func receive():
		received = true


# Validating that two nodes in the same game instance can connect to each other via a network connection.
func _ready() -> void:
	var rpc_host := RpcTester.new()
	add_child(rpc_host)

	var rpc_client := RpcTester.new()
	add_child(rpc_client)

	var host_enet := ENetMultiplayerPeer.new()
	var host_mp := SceneMultiplayer.new()
	get_tree().set_multiplayer(host_mp, rpc_host.get_path())
	host_enet.create_server(TEST_PORT)

	rpc_host.multiplayer.multiplayer_peer = host_enet

	await get_tree().create_timer(1.0).timeout
	assert(host_enet.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED)

	var client_enet := ENetMultiplayerPeer.new()
	var client_mp := SceneMultiplayer.new()
	get_tree().set_multiplayer(client_mp, rpc_client.get_path())
	var err = client_enet.create_client(LOCAL_IP, TEST_PORT)
	if err:
		print(err)
		return
	rpc_client.multiplayer.multiplayer_peer = client_enet

	while client_enet.get_connection_status() != MultiplayerPeer.CONNECTION_CONNECTED:
		print("waiting for connection")
		await get_tree().create_timer(1.0).timeout

	rpc_host.send()

5 Likes

Thank you :folded_hands:. It was extremely confusing to me to have to create a new MultiplayerAPI, which is an abstract class; almost sure it’s a documentation mistake or could at least get further clarification.

2 Likes

Than you :+1:
It’s very hard to see exemple of this anywhere else

!

1 Like