I’ve got a multiplayer scene using godots built in multiplayer stuff. In said scene i have a box which is just a rigidbody3d. When the host shoots the box it reacts accordingly and moves. It moves on both the host and clients screens as ive got the position and rotation synced in the multiplayersynchronizer node of the scene.
However when the client shoots the box it doesnt move and if the client continues to shoot it will ‘kill’ the box and remove it (has a small script attached with a health variable and if its lower than 0 it queue_frees it) yet it will only remove it from the clients game not the hosts. I assume the shooting movement thing is to do with authority so I guess that leaves me with two questions
How can i move the box via shooting/ whatever regardless of who is shooting be that host or client
How can i sync the scene tree so that if a host or client ‘kills’ and item which is freed how can i update the other clients.
I will assume you want an central authority server.
So the spawner should also spawn that box from the host side. As wells as spawn bullets/rays that the player shoots.
Typically with central auth servers the client should only send player input to the server. While the server handles spawning/despawning nodes, movement and physics.
The client side code should check if it’s the authority before trying to free an object. Otherwise you are going to get into this situation again where the client isn’t seeing the “real” world anymore.
Peer-to-peer is possible but you then need to manage spawner authority. As only the authority spawner will synchronize watched nodes to all the clients.
I recommend reading these articles there is a cool dual server client physics approach at the end.
I guess I will also add that there will be somethings that you don’t really care to sync, like particles. Clients could manage particles on their side.
I was planning for this to be purely p2p with no need for any hosted servers. With one player being the ‘host’ and the others ‘clients’
The box has a simple script which has a method to register the hit and apply an impulse and free it if the health gets to zero. I assume it doesn’t move when the client hits it because it doesn’t have authority as the position and rotation are synced using the synchronizer.
@rpc("any_peer", "call_local")
func hit_successful(damage, direction:= Vector3.ZERO, position:= Vector3.ZERO):
var hit_position = position - get_global_transform().origin
health -= damage
if health <= 0:
queue_free()
if direction != Vector3.ZERO:
apply_impulse(direction * damage, hit_position)
Call from the player when shooting box
if collider.is_in_group("Target") and collider.has_method("hit_successful"):
collider.hit_successful.rpc(currentWeapon.WeaponDamage, hit_direction, hit_position)