godotengine / godotengine/godot-docs

The MultiplayerSpawner documentation is too non-specific for actual use and lacks practical, workable examples

Open
#11,205 5 comments 0 reactions 0 assignees View on GitHub
area:class reference
Dominant language
reStructuredText
Stars
5.7k
Forks
3.8k
Avg merge
1d 20h
Merged PRs (30d)
25

Description

### 4.5 build 5

The MultiplayerSpawner documentation makes no sense to me. It has no actionable examples and it talks in terms so vague it is impossible (for me) to figure out what to do. I had several AI agents analyze the source code to try and figure out how this is supposed to work and ~50 hours in I'm still right where I started in terms of progress, which is a lot for something that looks like it should take 2 minutes and ~20 lines of codes to set up.

[**MultiplayerSpawner documentation**](https://docs.godotengine.org/en/stable/classes/class_multiplayerspawner.html)

**Expected usage:**

Add a MultiplayerSpawner to your scene, point it at an anchor Node (attachment_node down below) and when your server adds children of whitelisted scenes to this anchor, the spawner replicates the node to clients.

Except it doesn't. It fails every time, often silently. I've tried a ton of variants from people across the internet, but examples are exceedingly hard to find and I have yet to even see a working one anywhere that doesn't fake it by running the spawning code on both client and server with cameras in different positions but the controls manipulating the same character across both debug instances by simply not turning off inputs when the window is not focused.

### Example 1:

Since the base case doesn't work, I tried the spawn function, which requires a custom Callable to work.

How are you supposed to set the Callable? We don't know. The documentation says the following:

Callable spawn_function
set_spawn_function(value) setter
get_spawn_function() getter

_"Method called on all peers when a custom spawn() is requested by the authority. Will receive the data parameter, and should return a Node that is not in the scene tree."_

So it returns a Callable, but we're also supposed to set a "value" to it, which isn't typed but hints at requiring a "function" to call back to. Are we supposed to do something with the returned Callable? What do we pass to spawn_function? I tried some variants:

How about the actual function signature? Doesn't work
`multiplayer_spawner.spawn_function = spawn_callback`
Maybe a Callable? Nothing
`multiplayer_spawner.spawn_function = Callable(self, "spawn_callback")`
The string name of the function to be called? This does throw an error that it needs a Callable as input, but as stated before, it doesn't work with a Callable as set up above so what about creating a Callable from the function call? Again, nothing
`multiplayer_spawner.spawn_function = Callable(spawn_callback)`

It's very unclear as to how the MultiplayerSpawner is supposed to be used as it fails, often silently, if configured incorrectly and some do's and don't + code examples would go a long way. I understood the remote nodes are identified by a combination of their path, authority and name so something like the following should work (it doesn't):

```
##Pass the peer's id (multiplayer.get_unique_id()) and the spawnable scene
func spawn_multiplayer_scene(peer_id: int, scene: PackedScene) -> Node:
var instance = scene.instantiate()
instance.set_multiplayer_authority(peer_id, true)
attachment_node.add_child(instance, true)
multiplayer_spawner.spawn({
"path": scene.resource_path,
"name": instance.name,
"authority": peer_id
})
return instance

##Called on the authority that controls the spawned scene
func spawn_callback(data: Dictionary[String, Variant]) -> Node:
var scene = data["path"] as PackedScene
var instance = scene.instantiate()
instance.name = data["name"]
instance.set_multiplayer_authority(data["authority"], true)
return instance
```

but the spawn callback never gets called anywhere because it's unclear how the spawner should learn about its existence. I'm sure the actual implementation is not that complicated, but the documentation is lacking to the point where guessing the intent via analyzing the source code still doesn't really tell various LLMs anything useful.

### Example 2:

_Node spawn(data: Variant = null)_

_Requests a custom spawn, with data passed to spawn_function on all peers. Returns the locally spawned node instance already inside the scene tree, and added as a child of the node pointed by spawn_path._

_Note: Spawnable scenes are spawned automatically. spawn() is only needed for custom spawns._

I think what's meant here after my many hours of trying things:

Spawn is meant for custom spawn logic.

It calls the Callable set under the spawn_function attribute of target MultiplayerSpawner. The target function of the Callable is called on the clients based on their authority, so if the server spawns the instance, it is only called on clients to which the nodes are replicated towards. The locally spawned Node is returned by the spawn function on the server for immediate use and is automatically added to the anchor Node set in the MultiplayerSpawner's spawn_path.

**In closing:**

Based on many of the old forum posts and questions about this component that I've read, I'm not alone in my confusion so I hope this can get some attention from the team. Much love, thanks for building a wonderful engine.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.