Multiplayer spawn with attributes doubts

Godot Version

4.5

Question

Well, I’m trying to have an small multiplayer topdown shooter, and most of the functions work, but I’m not able to imagine how to load some local data on joining the players, and how to show correctly to the rest of players.

I have some autoloads that will be updated remotely, saved and loaded, this is not a problem. When constructing the player, some (many) of these data are used to apply personal attributes as health, weapon eqquiped, level, and so on…

On multiplayer scenario I spawn the players with a MultiplayerSpawner using a custom spawn function, and each player has it own MultiplayerSynchronizer. I’ve seen several tutorials where some data are set in the server, but this is not the case.

I suppose that when client joins, server should ask with a rpc the local data neccesary to construct the player, and once spawned, share this player and data with rest of players, but I cannot imagine how to do it, neither the form of the calls.

I use rpc calls to spawn bullets and other elements, but the player ones I cannot figure out how to implement them.

Any help or advice would be very appreciate, pseudocode or whatever, as I’m blocked.

My autoloads:

player_DATA.gd

extends Node

var player_DATA: Dictionary = {
	"NAME": "player",
	"PELO": Color(0.227, 0.388, 0.549),
	"NIVEL": 1,
	"VIDA_x_LVL": 47,
	"XP": 1,
	"ARMA_EQUIPADA": 0,
	"TALENTOS_DISPONIBLES": 0,
	"STAMINA": 10,
	"DINERO": 0,
	"ADYUM": 0
}

var player_TALENTOS: Dictionary = {
	##ARMA
	"Prob_crit" : 0 ,
	"Mult_critic" : 0,
	"Veloc_disparo" : 0,
	"Tamaño_Cargador" : 0,
	##CUERPO
	"Dash" : false,
	"Mejora_vida" : 0,
	"Mejora_XP" : 0,
	"Mejora_escudo" : 0,
	##MAGIA
	"Regen_magia" : 0,
	"Veloc_magia" : 0,
	"Magia_varios_enem" : false,
	"Damage_magia" : 0
}

Spawner spawn function (into ServerManager.gd):

func spawn_player(peer_id: int) -> Node:
	randomize()
	var jugador: CharacterBody3D = player.instantiate()
	jugador.name = str(peer_id)
	jugador.PVP = es_PVP
	jugador.position = Vector3(randi() %10, 0.5, randi() %10 )
 ## IS HERE WHERE I SHOULD LOAD ALL LOCAL DATA? AND HOW?
	datos_jugador = { In this way??????
		"ID": peer_id,
		"player_DATA": PlayerData.player_DATA,
		"player_TALENTOS": PlayerData.player_TALENTOS
	}
	return jugador

Actual player.gd;

##VIDA
@onready var vida: int
@onready var VIDA_MAX: int
var morir_once: bool = false

#Parametros de movimiento
var speed
var is_blocked: bool = false
var is_rolling: bool = false
var is_reloading: bool = false
var rolling_rapido: bool = false
const SPEED_IDLE = 10 * 0.6
const SPEED_DISPARANDO = 9.5 * 0.6
const SPEED_MAGIA = 8.5 * 0.6
const MAX_SPEED = 12 * 0.6
const SPEED_ROLL_RAPIDO = 9
const SPEED_ROLL_LENTO = 2
const ACEL = 12

var direction = Vector3()
var rot = Vector3()
var mov_joy = Vector2()
var rot_joy = Vector2()
var roll_direction = Vector3()

## Modos de juego ####
const MODOS = ["MAGIA", "RIFLE"]
var modo
enum  ESTADOS {NORMAL, ROLLING, RELOADING, BLOQUEADO}
var estado_actual = ESTADOS.NORMAL

var PVP : bool = false
var datos_jugador_sincronizados: Dictionary = {}

##	SEÑALES ####
signal modo_cambiado

##	NODOS_VARIOS    ####
@onready var insercc: Marker3D = $Gael_Ix/Armature/Skeleton3D/derecha_rifle/inserccion_rifle
@onready var anim_pl : AnimationPlayer =  $Gael_Ix/AnimationPlayer
@onready var anim_tree: AnimationTree = $Player_animTree

@onready var morir_timer: Timer = $morir_timer
@onready var bola_mano: Node3D = $Gael_Ix/Armature/Skeleton3D/Mano_derecha/Magic_bolt_mano

func _enter_tree() -> void:
	set_multiplayer_authority(name.to_int())

func _ready():
	$Label3D.text = str(name)
	
	if name.to_int() == multiplayer.get_unique_id():
		$ObjetivoCam/SpringArm3D/Camera3D.current = true


	var vida_base = 300 + PlayerData.player_DATA["NIVEL"] * PlayerData.player_DATA["VIDA_x_LVL"]
	var vida_talentos = PlayerData.player_TALENTOS["Mejora_vida"] * TalentosStatic.talentos["Mejora_vida"]
	VIDA_MAX = vida_base + int(vida_talentos)
	vida = VIDA_MAX
	modo = MODOS[0]
	cambio_modo(modo)

####################	CONECTAR SEÑALES		################################################
	anim_pl.esta_rollando.connect(roll)
	anim_pl.roll_rapido.connect(cambio_veloc_roll)
	anim_pl.recarga_terminada.connect(fin_recarga)
	insercc.get_child(0).a_recargar.connect(rifle_reload)

## Rest of player code ###

Remote Root tree appearance:

Player Tree:

Results for now: