P2P proper way of freeing node

Godot Version

4.2.1 stable

What I’m doing

Hello I’m making a small party game about tanks. Each player has it’s own tank, and each player can shoot bullets in order to destroy other player’s tank. While I managed to handle most of the multiplayer stuff by myself…

I’m still new to networking things and etc. In my player script I call a function to instantiate a new bullet when player press certain action. And that function makes a rpc call to different script that only runs on the server / host.

And in that script runs all the logic to create and manage the bullets.

Everything with that works nice and smoothly,
(but if it is a bad idea to do that this way please correct me, or teach me how to use this API better).

Like I said the only problem is when I try to queue_free the bullet when it hits something or certain time passes.

Right now the logic is just a normal function called without rpc inside bullet script. I guess I need to call it by rpc, but if I do that the other error messages show up, and propably I need an authority set in order for this to work, but I’m not sure how to do that…

When bullet try to free itself I got this error message in console on client debug session, per bullet trying to vanish itself.

Question

How should I queue_free nodes instantiated at runtime? Should I set them authority when they are created? If yes the how? Because for a player it’s pretty straightforward because I’m just geeting peer_id of a client and setting it as an authority in player script.

they should only be freed by the authority.

if is_multiplayer_authority():
  queue_free()

regarding setting the auth you could do in the same way as your player name with the multiplayer id. and since your bullets will be in the same space as players and many bullets, you could add a prefix the bullet name with the id like 4892304_bullet then when the bullet is spawned you trim the name of the newly spawned node and get the authority id to set on the bullet.

I tried this check if is_multiplayer_authority() The Error go away, but when a player shoots a bullet it frees when certain condictions are met, but only on the host

From what you said I understand that I still need to set the authority for every new bullet in order for that if check to work. You also said that bullets are in the same space as players which isn’t really correct for my case.

In a “WorldNode” I instantiate the map at the host and “MapSpawner” node syncronizes it acros clients. And players are childs of that loaded map. But bullets are children of “BulletSpawner” node. Their names are set by using multiplayer.get_unique_id(). And I tried to set those names as authority (and converting their names from strng to int first) but then when “shoot_bullet” input action is pressed on host or client the other two Error show up.

So what I’m doing wrong?

Okay, well if you look closely you will notice once you add more then one bullet with the same name Godot will append a number. It actually looks like it’s just incremented the multiplayer id.

So the client tank multiplayer id is 433888721
And the first bullet is the same but the second bullet is the id + 1. (433888722). And every other bullet is incremented above that. When this happens it will be difficult to sus out the real id.

This is where you add the name = str(multiplayer_id) +"_bullet" (the string suffix could be whatever you want) So when you spawn multiple bullets that auto increment doesn’t mess with the id. Then you just use a String class function to only get the id and discard the rest of the name. (I can’t remember the exact string function name, but there will be many ways to do it)

note:

I haven’t tried a peer to peer, ( I do server client) so I don’t know if MultiplayerSpawner will behave as expected when there are objects with different authorities. But you will want to identify ownership of bullets for score keeping anyway.

I suspect you will need to have a MultiplayerSpawner that is owned specifically by each peer. Which means you will have a unique bullet spawner that is authed to each peer that joins.

ok I set the authority for each bullet inside Bullet.gd in _enter_tree() function. But I still have the same error.

obraz

My guess is that the MultiplayerSpawner isnt authed to the client so when the bullet is added it will not spawn it to other players. My previous note I talked about this.

You will probably need to rework what a player is so it will have all its own spawners that it is authed to use.

Also your spawnbullet shouldn’t need to be called for everypeer. Only the on peer adds the bullet and the MultiplayerSpawner will sync it to every one else. If you want to go the manual RPC route you shouldn’t need to use the MultiplayerSpawner.

Also your RPC sets initial state. A MultiplayerSynchronizer would do this for you. If you use the multiplayer nodes as they are intended you rarely even have to use an RPC.

ok. I moved all the logic responsible for creating bullets to the player script. And removed unnecessary rpc annotations. And it didn’t helped. I mean it did but not fully.

Now on host bullets are properly creating and freeing without errors, and are synced acros all instances.
But when client tries to shoot a bullet it only show up in his game instance, and two errors show up.

but hey the error isn’t showing up when bullets gets destroyed :wink:

about that:


The player have only one synchronizer, and spawners (one for spawning players, second for spawing bullets) are outside of player.tscn

sorry that you need to help me so much. Cuz maybe I’m doing something stupid that I don’t know and you need to spend more and more time for a dumbass like me ;d. But at least I hope I’ll learn more about multiplayer and stuff.

1 Like

Yeah you are correct, it’s probably not a good idea to give the responsibility to the player scene.

Yea so I think the last issue is that a spawner will only work for who it is authed to. And it defaults to the host.

maybe you would need another scene like a container that will have a tank spawner and a bullet spawner. And the host will have a container spawner. So when a peer connects/disconnects it will spawn/despawn a container.

Whenever a container spawns it will recursively auth all the nodes to the peer it represents. (You will still have to auth new nodes individually)

So when a player wants to spawn it will put a tank under its container tank spawn. And when the tank shoots it will put a bullet under its container bullet spawn.

In the end there will be N containers for N connected peers, with spawners for everything the peer can create and destroy. And all the nodes in a container will be authed to that peer.

Ok I moved the player to the node I called “PlayerHandler” and into this handler I also added a MultiplayerSpawner node to synchronize bullets. I restructured my code a bit, and… Everything works the same, even errors…

I think I can give a zip file with project in it. I can give it to you and remove it from forum afterward so there won’t be many copies of it.
I mean I just trust you.

This project it still far from finished and propably this way you could track faster what is the problem… But I don’t know if you are fine with that.

ok I moved bullet spawning logic back into separate node that runs only on host. So the bullets are instantiated by authority / host. And now somehow everything works… I don’t know what I exactly did but it works how it should… Well thanks for all help then.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.