Spawning

In single-player, instantiating a scene creates a local node. In multiplayer, the same operation must create that node on every connected client and assign it a network identity so the replication system can track it. This is what networked spawning does - it turns a local scene instantiation into a coordinated event across all peers.

Despawning is the reverse: it removes the object from every client and frees its network identity. Late-joining clients automatically receive the current set of spawned objects when they enter the room.

Setup

FusionSpawner acts as a networked factory that creates and destroys objects across all clients. Add a FusionSpawner node to your scene and register spawnable scenes:

GDScript

const PlayerScene = preload("res://player.tscn")
const ProjectileScene = preload("res://projectile.tscn")

@onready var spawner = $FusionSpawner

func _ready():
    spawner.add_spawnable_scene(PlayerScene)
    spawner.add_spawnable_scene(ProjectileScene)
    spawner.spawned.connect(func(n): print("Spawned: ", n.name))
    spawner.despawned.connect(func(n): print("Despawned: ", n.name))

Set spawn_path to the parent node for spawned objects (default: spawner's parent).

All clients must register the same spawnable scenes in the same order.

Spawn and Despawn

Call spawn() to create a networked instance and despawn() to remove it from all clients.

GDScript

# Spawn first registered scene
var player = spawner.spawn()
player.position = Vector2(100, 200)

# Spawn a specific registered scene
var projectile = spawner.spawn(ProjectileScene)

# Despawn
spawner.despawn(player)

Set properties on the returned node after spawning. Replicated properties (configured in FusionReplicationConfig) will be included in the next network update.

Scene Structure

A typical game scene has a FusionSpawner alongside any game logic, while each spawnable scene has its own FusionReplicator as a child of the root node.

Game Scene Structure
Game Scene Structure
Player Scene Structure
Player Scene Structure

Properties

These properties configure where spawned objects are placed in the tree and which scenes are available.

  • spawn_path (NodePath, "..") - parent for spawned objects
  • spawnable_scenes (Array[PackedScene]) - registered spawnable scenes

Signals

FusionSpawner emits signals when objects are created or destroyed, on all clients.

  • spawned(node: Node) - object spawned (local or remote)
  • despawned(node: Node) - object despawned

Sub-Objects

Sub-objects are dynamic children attached to a spawned root that get their own sync buffer. They share the root's authority - the same client owns both parent and sub-object.

To spawn sub-objects, add a FusionSpawner as a child of a spawned scene and call bind_root_replicator() to link it to the parent's replicator. This makes the spawner a "sub-spawner" - its spawn() calls create sub-objects instead of root objects.

GDScript

# In the spawned scene's script:
const TurretScene = preload("res://turret.tscn")

@onready var sub_spawner: FusionSpawner = $SubSpawner

func _ready():
    sub_spawner.add_spawnable_scene(TurretScene)
    sub_spawner.bind_root_replicator($FusionReplicator)

func spawn_turret():
    var turret = sub_spawner.spawn(TurretScene)
    turret.position = Vector2(0, -20)

Sub-objects must have their own FusionReplicator.

Sub-objects cannot have independent authority.
Ownership always follows the root object.

Back to top