#Struggling with replicating fireball

14 messages · Page 1 of 1 (latest)

steep raven
#

Hi,

Context: I'm making an online 2player game. Each player should be able to cast fireballs, but the host should be responsible and do the calculations.

I can cast a fireball that is visible for both players from my host, but the client cannot fire at all. I tried calling spawn_fireball on the host from the client by using rpc_id(1) but it seems that the function is only called by the client, and not the host. I can't seem to wrap my head around whats wrong.

Any help is greatly appreciated!

player.gd

func _ready() -> void:
    if is_multiplayer_authority():
        print("isauth")
        $Camera2D.make_current()
        root.get_node('fireballSpawner').spawn_function = create_fireball

...

func cast_fireball():
    if dying or is_attacking:
        return
    is_attacking = true
    velocity = Vector2.ZERO
    _update_facing_direction()
    
    var attack_direction = (get_global_mouse_position() - global_position).normalized()
    sprite.play(_get_special_attack_animation(attack_direction))
    
    if my_id == 1:
        print(my_id, ": hi0")
        var payload = {
            "origin": global_position,
            "dir": attack_direction
        }
        var spawner = get_tree().get_current_scene().get_node("fireballSpawner")
        spawner.spawn(payload)
    
    else:
        rpc_id(1, "notify_spawn_fireball", global_position, attack_direction)
        
    await get_tree().create_timer(0.3).timeout
    is_attacking = false    
    
const FIREBALL_SCENE = preload("res://scenes/fireball.tscn")

func spawn_fireball(origin: Vector2, direction: Vector2) -> void:
    print(my_id, ": hi2")
    if my_id != 1:
        return
        
    var payload = {
        "origin": origin,
        "dir": direction
    }
    
    var spawner = get_tree().get_current_scene().get_node("fireballSpawner")
    spawner.spawn(payload)
    
@rpc("call_remote", "reliable")
func notify_spawn_fireball(position: Vector2, direction: Vector2) -> void:
    #This should call spawn_fireball locally on host (player1) right? Because this was called from client
    spawn_fireball(position, direction)
    
func create_fireball(data: Dictionary) -> Node2D:
    var fb = fireball_scene.instantiate()
    fb.global_position = data.origin + data.dir * 8
    fb.direction = data.dir
    return fb

log:

1: hi0
1366713380: hi2
1366713380: hi2
1366713380: hi2
1366713380: hi2
buoyant plume
#

For peer -> host I think rpc needs "any_peer"

steep raven
#

So instead of the host spawning the fireball and the multiplayer spawner replicates it, the client tries to do it instead which it isnt allowed to

buoyant plume
#

Did you test it being hit past the my_id check? Breakpoint or print message.

steep raven
buoyant plume
#

Oohh, I see how the test was setup now. Sorry. I'm not sure about this.

steep raven
novel trench
#

my advice is to forget the built in nodes and do it in code. its sad but they are experimental nodes. call
rpc("spawn_fireball" )

@rpc("any_peer","call_local")
func spawn_fireball():
# create your fireball here

steep raven
novel trench
#

I can check later for exact specifics if you need, but there’s a function you can call that specifically checks if we are the host. What I usually do is disable the hit box on any projectiles attacks, enemies, etc. if we are not the host.

#

What that means is that anytime a collision happens you can already assume that it’s happening on the host and RPC to spawn in a scene on all host and client the damage number using the same technique we used to spawn the fireball in the first place

#

@steep raven

steep raven