#variable not synchronizing to peers

1 messages · Page 1 of 1 (latest)

devout knot
#

im making a multiplayer game with active ragdoll integrations.
to do that, i made a system to which the "host" client handles all the physics while the rest of the clients just recieve the bone poses and replicate them on a normal skeleton.
the inputs from the other clients work just fine, the host machine recieves them and handles them well. my problem comes from the pose synchronization. for this, ill need to explain the system further in detail.
each player will start with the "PlayerController" node, which contains a MultiplayerSynchronizer, a "ControlledBody" which is the one with the active ragdoll, a "SynchronizedBody" which will replicate the previous one's skeleton pose, and a "PlayerCamera" which... serves as a camera for the player (see the image for the complete structure). the MultiplayerSynchronizer has two variables synchronized: "input_sync_data", the input data, and "skeleton_sync_data", the skeleton pose data. both are PackedByteArrays
the player controller, when instantiated, will begin with its multiplayer authority being set and a "host" boolean, which indicates if it is in the host machine or not. then it will select one of the bodies to handle, the ControlledBody if host, the SynchronizedBody if not, and delete the other one in any of the cases.
in the process function, it will act differently depending on if it's host and if it's multiplayer authority:

  • if it is multiplayer authority, it will take the input data and pack it inside the input_sync_data variable. if it's not, it will unpack it. the input data will be packed from and unpacked into dedicated input variables. as i said, this part works just fine
  • if it is host, meaning it has the ControlledBody, it will call a function that packs the PhysicalBones data of it and store it in skeleton_sync_data. if it isnt, meaning it has the SynchronizedBody, it will take skeleton_sync_data and give it to a function inside the body, which will unpack the data and apply it to BoneAttachments
#

now here's my problem: the synchronization works but just for the host (see how the input works from both instances and also how the host player moves exactly the same way in both instances, but the second player cant synchronize in it's own)

quaint sedge
#

Also, what does Pack/Unpack bones look like? What are the types, etc?

devout knot
#

ok i was gonna follow the description but i got distracted

devout knot
#

the thing is that the bone sync variable doesnt transfer between the non host players

#

when i print the var from a non host player node without multiplayer authority it returns an empty array

quaint sedge
#

You're doing a lot of explaining, why not post what is filling the debugger and the pack/unpack methods?

devout knot
#

so what i think is happening is that the node not being multiplayer authority is making it so that the multiplayer synchronizer doesnt transfer the property

quaint sedge
#

If the host sets the bones, and is not the authority of the synchronizer, then no one will sync it

#

Share the debugger anyways, there is a non-zero chance that's what it says

devout knot
#
func unpack_bones(data : PackedByteArray):
    bones.sort_custom(func(a,b) -> bool:
        var aid = a.get_bone_idx()
        var bid = b.get_bone_idx()
        return aid < bid)
    
    var buffer = StreamPeerBuffer.new()
    buffer.data_array = data
    
    var o := Vector3(buffer.get_float(), buffer.get_float(), buffer.get_float())
    
    bones[0].global_position = o
    
    for bone in bones:
        var quat = Quaternion(
            buffer.get_16() / 32767.0,
            buffer.get_16() / 32767.0,
            buffer.get_16() / 32767.0,
            buffer.get_16() / 32767.0
        ).normalized()
        bone.global_rotation = quat.get_euler()

func pack_bones():
    var buffer = StreamPeerBuffer.new()
    var root_position = root_bone.global_position
    buffer.put_float(root_position.x)
    buffer.put_float(root_position.y)
    buffer.put_float(root_position.z)
    
    for bone in range(physics_bones.size()):
        var q : Quaternion = physics_bones[bone].quaternion
        buffer.put_16(int(q.x * 32767))
        buffer.put_16(int(q.y * 32767))
        buffer.put_16(int(q.z * 32767))
        buffer.put_16(int(q.w * 32767))
devout knot
quaint sedge
#

Ah, haha.

devout knot
#

i chose quaternion because it is the most memory efficient way

quaint sedge
#

So yeah, I'd start by adding a second sync that is responsible for setting the bones, and set its authority to the host.

#

See if that helps

devout knot
#

for all the other players, right?

#

the variable

#

like the variable is destined to store all the other player's data

#

that's what im talking about

quaint sedge
#

Assuming I understand: One player is host, and all players send input data to that host. That host translates inputs, deals with the bones, and then packs and syncs them back?

devout knot
#

no

#

the playercontrollers get host if they are in the host machine

#

the true host is determined if host and multiplayer authority

#

a solution is to put the other dkeleton data in the true host by a dictionary, sort that dictionary, put the data in order in the skeleton sync and then make the host on the other machines distribute the data

#

something like that

quaint sedge
#

Your whole host and true host lingo has me very confused.

If you disable processing the actual bones data, and just inspect with the remote inspector, are you getting any values? Any debug errors outside of those NAN quaternions that might illuminate anything?

devout knot
#

basically the "host" bool indicates that it is in the host machine

#

the "true host" is the playercontroller node in the host machine that has authority

devout knot
#

that's why

quaint sedge
#

Are you supporting local multiplayer as well as networked?

devout knot
#

i am playtesting local but im aiming for online

devout knot
quaint sedge
#

So when would there be a "host" player that is not also "true host"?

devout knot
#

i could change the name to that but it doesnt change much

quaint sedge
#

What does "host machine" mean? Because when talking about multiplayer, it sounds like "The Server" IE: The host of the game.

Do you mean it like a local client? So if I'm playing, and I join a game (not host it), my player is marked "host" in my client?

devout knot
#

if not, it is really easy to change it

quaint sedge
#

I'm completely lost on structure. But it's not important

All that matters is that whatever needs to be able to set the bones (pack them), it must have authority over the synchronizer that will sync the value.

devout knot
#

ok, i did it, it works now

#

the problem is

#

it looks too jittery

#

i tried to solve it with slerp but it goes crazy

devout knot