Godot Version
4.2.1
Question
I’ve recently been trying to set up multiplayer networking for my Godot game using a tutorial I found on YouTube. Despite this I keep getting this error when another player character joins the server, causing the player’s position changes to not occur globally.
_process_rpc: RPC 'update_remote_position' is not allowed on node /root/Player/1 from: 694666895. Mode is 2, authority is 1.
Here is my networking code:
extends BoxContainer
var peer = ENetMultiplayerPeer.new()
const ADDRESS = "localhost"
const PORT = 9999
var player_ids = []
func _create_server():
peer.create_server(PORT)
multiplayer.multiplayer_peer = peer
create_player(1)
peer.peer_connected.connect(
func(new_peer_id):
await get_tree().create_timer(1).timeout
rpc("add_newly_connected_player", new_peer_id)
rpc_id(new_peer_id, "add_previously_connected_players", player_ids)
create_player(new_peer_id)
)
func _join_server():
peer.create_client(ADDRESS, PORT)
multiplayer.multiplayer_peer = peer
func _disconnect():
multiplayer.multiplayer_peer = null
func create_player(new_peer_id):
player_ids.append(new_peer_id)
var player_instance = preload("res://prefabs/player.tscn").instantiate()
$/root.add_child(player_instance)
player_instance.set_multiplayer_authority(new_peer_id)
player_instance.position = Vector2.ZERO
@rpc
func add_newly_connected_player(new_peer_id):
create_player(new_peer_id)
@rpc
func add_previously_connected_players(peer_ids):
for peer_id in peer_ids:
create_player(peer_id)
# Called when the node enters the scene tree for the first time.
func _ready():
$JoinButton.pressed.connect(self._join_server)
$HostButton.pressed.connect(self._create_server)
$LeaveButton.pressed.connect(self._disconnect)
pass # Replace with function body.
And here is my movement code:
extends CharacterBody2D
@export var SPEED = 300.0
@export var JUMP_VELOCITY = -400.0
# Get the gravity from the project settings to be used with the player character
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
#Get sprite, and marker nodes for animations, projectiles, etc
@onready var sprite = get_node("AnimatedSprite2D")
#Preload fireball scene as prefab
var fireball_scene = preload("res://prefabs/fireball.tscn")
func _ready():
name = str(get_multiplayer_authority())
#Update the position of the markers where projectiles are spawned
func update_markers():
var BackMarker = get_node("BackMarker")
var FrontMarker = get_node("FrontMarker")
FrontMarker.position = Vector2(self.position.x - 70, self.position.y - 40)
BackMarker.position = Vector2(self.position.x + 70, self.position.y - 40)
#Function that handles projectile input
func projectile():
#Update the position of the markers for projectiles
update_markers()
#Define fireball variables and get marker nodes for positioning
var fireball_instance
var fireball_animations
var BackMarker = get_node("BackMarker")
var FrontMarker = get_node("FrontMarker")
#Check for inputs in the "projectile" input map
if Input.is_action_just_pressed("projectile"):
#Instantiate fireball and get animatios
fireball_instance = fireball_scene.instantiate()
fireball_animations = fireball_instance.get_node("Sprite2D/AnimationPlayer")
#Add the instance to the scene as a child of the root node
get_node("/root").add_child(fireball_instance)
#Place the fireball in the corresponding marker and play the "shoot" animation
if sprite.scale.x > 0:
fireball_instance.position = FrontMarker.position
fireball_animations.play("shoot")
elif sprite.scale.x < 0:
fireball_instance.position = BackMarker.position
fireball_animations.play("shoot_right")
#Wait for the animation to finish and then erase the fireball
await get_tree().create_timer(fireball_animations.current_animation_length).timeout
fireball_instance.queue_free()
func _physics_process(delta):
if is_multiplayer_authority():
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
# Handle Jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
#Manage projectile input
projectile()
# Get the input direction and handle the movement/deceleration.
var direction = Input.get_axis("left", "right")
if direction:
velocity.x = direction * SPEED
sprite.play("walk")
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
sprite.stop()
sprite.play("idle")
#Flip sprite depending on facing direction
if velocity.x > 0:
sprite.scale.x = -0.555
if velocity.x < 0:
sprite.scale.x = 0.555
#Execute velocity instructions
move_and_slide()
rpc("update_remote_position", global_position)
@rpc("unreliable")
func update_remote_position(authority_position):
self.global_position = authority_position
Thanks in advance!(let me know if you need any more info, this is my first godot forums post)