Hello. I trying to create simple air hockey game with WebRTC multiplayer with Nakama. To makes it easier for me, I decided to add my game over existing source code, because doing the other way around was too difficult for me. While I want to add only single Puck for both players, existing code want to do it twice and after creating one Puck on the board, he fails to do it twice with following error: add_child: Can't add child 'Puck' to 'PlayersSpawnUnder', already has a parent 'PlayersSpawnUnder'.
With current code it works, but Puck is really laggy and can be in wrong position sometimes.

Source code - Link
GameManager.gd
extends Node2D
export var player : PackedScene
var Puck = preload("res://Puck.tscn").instance()
var ReadyPlayers = {}
func _ready():
setupGame()
pass # Replace with function body.
func setupGame():
for id in GameManager.Players:
var currentPlayer = player.instance()
var currentPuck = Puck
currentPlayer.name = str(id)
$PlayersSpawnUnder.add_child(currentPlayer)
$PlayersSpawnUnder.add_child(currentPuck)
currentPlayer.set_network_master(GameManager.Players[id].peer_id)
currentPlayer.position = get_node("SpawnPlayerPositions/" + str(GameManager.Players[id].peer_id)).position
currentPuck.position = get_node("SpawnPlayerPositions/3").position
var myID = OnlineMatch.get_my_session_id()
var player = $PlayersSpawnUnder.get_node(str(myID))
player.playerControlled = true
rpc_id(1, "finishedSetup", myID)
mastersync func finishedSetup(id):
ReadyPlayers[id] = GameManager.Players[id]
if ReadyPlayers.size() == GameManager.Players.size():
print("start game all players are ready")`
Player.gd
extends KinematicBody2D
export (bool) var playerControlled = false
var updateFrames = 6
var currentFrames = 0
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
func _physics_process(delta):
if playerControlled:
self.position = get_global_mouse_position()
look_at(get_global_mouse_position())
# if Input.is_action_just_pressed("shoot"):
# rpc("shoot", $Position2D.global_transform, name)
# pass
currentFrames += 1
if updateFrames <= currentFrames:
rpc("UpdateRemotePlayers", position, rotation)
currentFrames = 0
#remotesync func shoot(shootPos, playerWhoShot):
# var bullet = Bullet.instance()
# get_tree().get_nodes_in_group("GameWorld")[0].add_child(bullet)
# bullet.transform = shootPos
# bullet.playerWhoShot = playerWhoShot
puppet func UpdateRemotePlayers(currentpos, currentRotation):
$Tween.interpolate_property(self, "position", global_position, currentpos, .1, Tween.TRANS_LINEAR)
$Tween.start()
$Tween2.interpolate_property(self, "rotation", rotation, currentRotation, .1, Tween.TRANS_LINEAR)
$Tween2.start()
Puck.gd
extends RigidBody2D
export (bool) var playerControlled = false
var updateFrames = 6
var currentFrames = 0
func _physics_process(delta):
currentFrames += 1
if updateFrames <= currentFrames:
rpc("UpdateRemotePuck", position, rotation)
currentFrames = 0
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
puppet func UpdateRemotePuck(currentpos, currentRotation):
$Tween.interpolate_property(self, "position", global_position, currentpos, .1, Tween.TRANS_LINEAR)
$Tween.start()
$Tween2.interpolate_property(self, "rotation", rotation, currentRotation, .1, Tween.TRANS_LINEAR)
$Tween2.start()
Any help is appreciated!