Player names increase by one when trying to set them

Godot Version

v4.6.2.stable.official [71f334935]

Question

Hello! I’m working on a multiplayer game. The way that I handle spawning and synchronizing the players is this: I instantiate each player and set some values. I set the player’s identifier (1) so it knows what stats to load, who to accept inputs from, etc., then add the player as a child of the node “main” (2). The value pNum is being set correctly (3), so I know the value of id is correct. The name of the nodes (4 and 5) do not match, though. To be clear, one player node should be named 1 and the other should be named whatever the other player’s UID is.

Thanks for any help you can give!

EDIT: if you need any more information, please tell me!

What happens if you do:

newPlayer.name = id

If it doesn’t assign ‘id’ as the name, it probably means the name is already used by another node, so that might be a helpful clue.

id is an integer here, that’s likely why it wasn’t working! Thank you!

Oh right, that makes sense!

Good luck on the rest of your project!

@candyarts

Nevermind, it seems like the name is being used on another node. That’s strange, though, because in the scene tree, it looks like I never rename more than one node to the value.

You probably have something in your code that increases id by 1 before it’s assigned as the node name.

I think if the name was already used by another node, Godot would default to its standard naming convention, it wouldn’t just increase the name by 1 (I could be wrong about this).

You are probably spawning too many players per peer, the node names are incremented automatically if “force readable name” is assigned true which is likely is. If you are using MultiplayerSpawner nodes maybe you are accidentally adding players per connection peers in addition to on server. Where is your code for spawning players? Can you paste it in a code block instead of a screenshot?

I’m not using MultiplayerSpawner objects, should I be?

func _ready() -> void:
	var determiner = Node.new()
	determiner.name = str(multiplayer.get_unique_id())
	add_child(determiner)
	
	if multiplayer.get_unique_id() == 1:
		var dungeonStyle = randi_range(0, dungeons.size() - 1)
		for k in Global.players:
			if Global.levelSeq[Global.levelNum] == 0:
				generateDungeon.rpc_id(int(Global.players[k].id), dungeonStyle)
			elif Global.levelSeq[Global.levelNum] == 1:
				generateShop.rpc_id(int(Global.players[k].id))
			else:
				generateBossfight.rpc_id(int(Global.players[k].id))
	
	var j = 0
	var toSpawn = []
	for player_index in Global.players:
		var newPlayer: PlayerEntity = preload("res://scenes/player.tscn").instantiate()
		newPlayer.get_node("playerCam").enabled = false
		newPlayer.get_node("playerCam").visible = false
		newPlayer.set_color(Global.players[player_index].color)
		
		var id = Global.players[player_index]["id"]
		newPlayer.set_playerNum(id)
		toSpawn.append(newPlayer)
		add_child(newPlayer)
		newPlayer.name = str(id)
		print_rich("[color=salmon](UID {0}) {1}'s name is now {2}".format(
			[
				str(multiplayer.get_unique_id()),
				str(id),
				newPlayer.name
			]
		))
		for spawn in $spawnLocs.get_children():
			if spawn.name == str(j):
				if newPlayer is PlayerEntity:
					newPlayer.global_position = spawn.global_position + Vector2(newPlayer.get_index(), 0)
		j += 1

“When set to an existing sibling’s name, the node is automatically renamed.” from the Node’s name property documentation. It doesn’t specify what it’s set to, though.

Is set_playerNum() a function you wrote? If so, can you show the code?

Typically the node is renamed to @NodeType@@ with a bunch of numbers, but setting the name, or using “force readable name” on the add_child call, it will append or increment a number suffix, so Node becomes Node2 and Node3 becomes Node4, in your case only having numbers 1 becomes 2

I’d bet your Globa.players has duplicate players, if you aren’t using MultiplayerSpawners or RPCs to add players.

Yeah, here:

func set_playerNum(new_num: int) -> int:
	playerNum = new_num
	isInitialized = true
	return playerNum

playerNum is an integer. It’s used for telling the player what inputs to respond to, what stats to use when setting up HP, etc.

I don’t see anything in there that increases id before it’s assigned as the name.

@gertkeno is probably right: the node is being renamed because the name is already used, and Godot is doing the renaming incrementally.

Here’s my Global.

I’m not using an @rpc decoration, so it shouldn’t be spawning multiple players.

Sorry for pinging the person named ‘rpc’.

Is this like re-spawning the players or recreating them for a new scene? Maybe you are deleting old players before this, but the queue_free has yet to remove them?

Nope, I’m using change_scene_to_file(), with the code above being the _ready() function for the scene’s root.

Any peer_connected connections? You are purely spawning players on each client, no RPCs, and not they spawn themselves then Global.players?

oh it is this,

Your determiner node is named after the client’s id, so their player cannot also be named that. Maybe you can move spawned players as a child of a new node such as a “Players” folder.

Thank you so much! That worked! I still wanted to be able to tell what “machine” I’m on, so I just added “Debug” to the start of the determiner’s name!