Parte: 7 — Multijugador y networking · Fuente: Documentación oficial de Godot 4 (Scene Replication) + ejemplos de la comunidad ⏱️ Duración estimada: 55 min · Nivel: Avanzado
Replicar el mundo sin escribir RPCs a mano usando los dos nodos de replicación de Godot 4: MultiplayerSpawner (para instanciar escenas replicadas: jugadores, balas) y MultiplayerSynchronizer (para sincronizar propiedades con un SceneReplicationConfig). Al terminar spawnearás un jugador por cada peer que se conecta y sincronizarás su posición automáticamente, entendiendo el papel de la autoridad en cada nodo.
Al finalizar, el alumno podrá:
spawn_path y escenas spawnables.SceneReplicationConfig.set_multiplayer_authority().| # | Tema | Por qué importa |
|---|---|---|
| 1 | Replicación de escena en Godot 4 | Automatiza lo que antes eran decenas de RPCs |
| 2 | MultiplayerSpawner y spawn_path | Define dónde y qué se instancia en red |
| 3 | Escenas spawnables | Lista blanca de lo que el spawner puede crear |
| 4 | spawn() en el servidor |
Solo la autoridad instancia; los clientes reciben |
| 5 | MultiplayerSynchronizer | Replica propiedades marcadas cada tick |
| 6 | SceneReplicationConfig | Qué propiedades se envían y con qué frecuencia |
| 7 | Autoridad por nodo | Quién manda sobre cada jugador |
| 8 | Input local + sincronía | Cada quien mueve el suyo, todos lo ven |
spawn(); los clientes lo replican solos.SceneReplicationConfig. Clave: envía desde la autoridad hacia los demás.position) y su modo (siempre / al spawnear). Clave: se edita en el inspector del synchronizer.true si este par manda sobre el nodo. Clave: úsalo para leer input solo en el dueño del personaje.Godot 4.x y dos instancias. Crearás dos escenas: Jugador.tscn (un CharacterBody2D o Node2D con Sprite2D y un MultiplayerSynchronizer) y Mundo.tscn (con un Node2D contenedor Jugadores y un MultiplayerSpawner). Configura el spawn_path del spawner apuntando a Jugadores y añade Jugador.tscn a Auto Spawn List. En el MultiplayerSynchronizer del jugador, crea un SceneReplicationConfig y añade la propiedad position. Guía: Scene replication de Godot 4.
1) El mundo y el spawner. Script en el nodo raíz de Mundo.tscn. El servidor spawnéa un jugador cuando alguien conecta; el spawner replica esa instancia a todos.
extends Node2D
const ESCENA_JUGADOR := preload("res://Jugador.tscn")
const PUERTO := 9996
@onready var _spawner: MultiplayerSpawner = $MultiplayerSpawner
@onready var _contenedor: Node2D = $Jugadores
func _ready() -> void:
multiplayer.peer_connected.connect(_on_peer_conectado)
multiplayer.peer_disconnected.connect(_on_peer_desconectado)
if "--server" in OS.get_cmdline_args():
var peer := ENetMultiplayerPeer.new()
peer.create_server(PUERTO, 8)
multiplayer.multiplayer_peer = peer
# El propio servidor también tiene su jugador (id 1).
_crear_jugador(1)
else:
var peer := ENetMultiplayerPeer.new()
peer.create_client("127.0.0.1", PUERTO)
multiplayer.multiplayer_peer = peer
func _on_peer_conectado(id: int) -> void:
if multiplayer.is_server():
_crear_jugador(id)
func _on_peer_desconectado(id: int) -> void:
if multiplayer.is_server() and _contenedor.has_node(str(id)):
_contenedor.get_node(str(id)).queue_free()
func _crear_jugador(id: int) -> void:
# Solo el servidor instancia; el spawner replica al resto.
var jugador := ESCENA_JUGADOR.instantiate()
jugador.name = str(id) # nombre = id para localizarlo luego
_contenedor.add_child(jugador, true)
# La autoridad del jugador es el peer al que pertenece.
jugador.set_multiplayer_authority(id)
2) El jugador que se mueve. Script en Jugador.tscn. Solo la autoridad lee input; el MultiplayerSynchronizer replica position al resto automáticamente.
extends CharacterBody2D
const VELOCIDAD := 220.0
func _physics_process(_delta: float) -> void:
# Solo el dueño de este jugador procesa su input.
if not is_multiplayer_authority():
return
var direccion := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
velocity = direccion * VELOCIDAD
move_and_slide()
No hace falta ningún RPC de posición: el MultiplayerSynchronizer del jugador, con position en su SceneReplicationConfig, envía la posición desde la autoridad a todos los demás cada tick.
Cómo probarlo con dos instancias: lanza servidor (--server) y cliente. Verás dos jugadores en ambas ventanas. Mueve con las flechas en la ventana del servidor: su jugador (id 1) se mueve en las dos. Mueve en el cliente: su jugador se mueve en las dos. Cada instancia solo controla el suyo (por is_multiplayer_authority()), pero ve moverse a todos gracias al synchronizer.
Detalle de autoridad: por defecto la autoridad de un nodo recién añadido es el servidor. Al llamar
set_multiplayer_authority(id)sobre el jugador, ese cliente pasa a mandar sobre su personaje y su synchronizer envía la posición.
rotation al SceneReplicationConfig y haz que el jugador mire hacia su dirección de movimiento.MultiplayerSpawner extra para balas y spawnéalas desde el servidor al pulsar disparo.Label con el id encima de cada jugador.replication_interval del synchronizer y observa el efecto en la fluidez.Monta una arena donde cada peer tiene su cuadrado controlable, todos spawneados por MultiplayerSpawner y sincronizados con MultiplayerSynchronizer. Añade balas: al pulsar espacio, el servidor spawnéa una bala en la posición del jugador que disparó y la replica a todos.
Criterio de aceptación: con 1 servidor + 1 cliente, ambos ven dos cuadrados; cada quien mueve solo el suyo pero ve moverse al otro con fluidez; al disparar en cualquiera de los dos, aparece una bala en ambas ventanas en la posición correcta.
| Síntoma | Causa y arreglo |
|---|---|
| El cliente no ve al jugador spawneado | La escena no está en la lista spawnable del spawner, o el spawn_path no coincide |
| La posición no se replica | Falta añadir position al SceneReplicationConfig del synchronizer |
| Todos controlan al mismo jugador | No asignaste autoridad; usa set_multiplayer_authority(id) por jugador |
| El cliente puede mover jugadores ajenos | No compruebas is_multiplayer_authority() antes de leer input |
| Nombres de nodo duplicados | Instanciaste sin name único; usa jugador.name = str(id) y add_child(nodo, true) |
reliable.Clase 141 - RPCs: llamadas remotas y sincronización