"Failed to encode a path to a custom script." when rpc functon i called

Godot Version

4.4.1

Question

I’m trying to add multiplayer to my game, I started with the basic example given in the docs. I just added type definitions. But when the _on_player_connected(id:int): callback gets triggered by the signal, and tries to call _register_player.rpc_id(id, player_info) it gives this error:

E 0:00:06:940   game_manager.gd:89 @ _on_player_connected(): Failed to encode a path to a custom script.
  <C++ Error>   Condition "path.is_empty() || !path.begins_with("res://")" is true. Returning: ERR_UNAVAILABLE
  <C++ Source>  core/io/marshalls.cpp:1785 @ encode_variant()
  <Stack Trace> game_manager.gd:89 @ _on_player_connected()

you can view the whole source code on github

here are parts of the source code that are important here:

var players :Dictionary[int,PlayerInfo]= {}

class PlayerInfo:
	func _init(name:String):
		self.name=name
	var name:String

var player_info :=PlayerInfo.new("default")

func _ready():
	multiplayer.allow_object_decoding = true
	multiplayer.peer_connected.connect(_on_player_connected)
	multiplayer.peer_disconnected.connect(_on_player_disconnected)
	multiplayer.connected_to_server.connect(_on_connected_ok)
	multiplayer.connection_failed.connect(_on_connected_fail)
	multiplayer.server_disconnected.connect(_on_server_disconnected)

func join_game(address := ""):
	if address.is_empty():
		address = DEFAULT_SERVER_IP
	var peer := ENetMultiplayerPeer.new()
	var error := peer.create_client(address, PORT)
	if error:
		return error
	multiplayer.multiplayer_peer = peer
func create_game():
	var peer := ENetMultiplayerPeer.new()
	var error := peer.create_server(PORT, MAX_CONNECTIONS)
	if error:
		return error
	multiplayer.multiplayer_peer = peer

	players[1] = player_info
	player_connected.emit(1, player_info)
func _on_player_connected(id:int):
	print("connected " + str(id))
	_register_player.rpc_id(id, player_info)


@rpc("any_peer", "reliable")
func _register_player(new_player_info:PlayerInfo):
	var new_player_id := multiplayer.get_remote_sender_id()
	players[new_player_id] = new_player_info
	player_connected.emit(new_player_id, new_player_info)

I have a similar problem. I think I found out how to fix it though:

I think you have to do 2 things

  • First move PlayerInfo into it its own script file
  • Second add a @export tag to the fields you want to get passed over the network

player_info.gd

class_name PlayerInfo
func _init(name:String):
	self.name=name
@export var name:String
1 Like

Classes (like PlayerInfo) are not allowed in RPCs by default, and is a security risk if it is configured to be allowed.

The basic example uses a dictionary, which is fine.

The error could have changed but this is my guess without looking at the source code of the engine.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.