State data from the client side does not get replicated

Hi!

I have the following code (from the Advanced Tutorial) which I use to initialize entities:


entity = BoltNetwork.Instantiate(BoltPrefabs.Player_online, RandomSpawn(), Quaternion.identity);


if (isServer)
{
entity.TakeControl();
}
else
{
entity.AssignControl(connection);
}

Spawn();


I start up debug mode (a server + one client).

I move the character on the server connection. It moves locally and gets replicated to the other side (the client connection). All good so far.

I move the character on the client connection. It moves locally but it is not replicated at all on the server connection. If I check the Unity inspector (the Unity editor as the server connection), no entity values gets updated.

I can see that the entity has an assigned Controller and is attached.

I was previously using client-side initialization and updated the character movement using SimulateOwner() (used in the Getting Started tutorial) . Then it stopped working when I switched to server-side initialization I started moving the character in the SimulateController() method.

SimulateController mostly consist of CharacterController.Move calls at this point.

I do not use any commands at this point.

Any classic pitfalls that I should have been looking out for?

Comments

  • If you're just changing properties on the client (property set to "everyone but controller") they will not replicate to the server or other clients, it is purely local. If you want to be server auth, you need to send commands with your input and so on like in the tutorial. If you want to be client auth, just have clients own their own players and call settransform and your transform will replicate to everyone.
  • Thank you for the reply!

    OK, I see. It's not that important whether it's server/client auth at the moment. I would prefer not using commands if that's possible.

    What I'm trying to achieve is to trigger a melee state between two players if they come up close.

    I.e: Player A closes in on player B, a collider puts Player A and B in a melee state. Maybe with a Bolt state trigger?

    I tried doing this solely by client auth, but since all clients were owners, I could not induce states from other players with events or triggers.

    Do you have any ideas on how I can achieve this?
  • Does the server own all entities or does each player own their own player entity? Can you upload a project with this issue?
  • Hmm, I'm not sure if I can produce a good code example. I think it would be easier if I try a theoretical example.

    Let's say you want to create a multiplayer Pac-man game (client auth). When the ghost players gets too close to Pac-man (with a collider), you'll have to change Pac-man's state to something else. Maybe you want a game-over state, maybe you want a different Pac-man animation state, etc.

    How would you check for collisions properly?

    And if you detect a collision, how would you go about to modify the state of the Pac-man player if the game uses client-auth?

    What would you do if you wanted to create a synchronized state between the ghost and Pac-man? Like "hey guys, this state is happening now and you have to use THESE animations at the same time"

    This is easy to create offline in Unity, but what I'm looking are some Proton Bolt best practices.
  • You can detect collision client side and change the state of the player when a collision is made. I don't understand the problem.
  • Alright, fair enough. :) But what if I also want to change the state of the other player, the one I collide with?
  • Send an event to change the state
  • Alright, I'll try that. Thanks again. :)
  • https://goo.gl/GjBg5a
    I would read doc "Bolt Use Cases"
  • OK, I'll check that out! :)

    This is a bit off-topic, but Bolt won't pick up my Bolt.EntityBehaviour script, the Attached method never gets called. How does the framework collect and execute these scripts?

    I suspect that it's because I'm instantiating my own game objects and put them under the parent game object, so maybe that Query runs before that. Can I trigger it manually somehow?

    My prefab setting is "Global" and my Bolt setting is "Components in children" as mentioned in the documentation you sent me.

    The code I'm using to do this:
    
    using UnityEngine;
    public class NetworkPlayerBehaviour : Bolt.EntityBehaviour<IPlayerState>
    {
        public GameObject PlayerObject;
    
        public GameObject PlayerWithoutBloat;
    
        public Transform CameraPosition;
        
        public override void Attached()
        {
            GameObject instantiatedObject;
            if (entity.isOwner)
            {
                MainCameraController.instance.Configure(CameraPosition);
                instantiatedObject = Instantiate(PlayerObject, transform);
                gameObject.AddComponent<FirstPersonLook>();
            }
            else
            {
                instantiatedObject = Instantiate(PlayerWithoutBloat, transform);
            }
    
            state.SetTransforms(state.PlayerTransform, instantiatedObject.transform);
    
            state.SetAnimator(instantiatedObject.GetComponent<Animator>());
            state.Animator.applyRootMotion = entity.isOwner;
        }
    };
    
  • You need to instantiate the entities using Bolt, this is covered in the getting started docs. There are advanced ways to do parenting and manual attach but you really need to have a good understanding of Bolt before trying these things.
  • Thanks for all the help. :)

    I ended up using client auth (like in the Getting Started tutorial), a Unity trigger and events to modify the state for both players whenever the trigger was triggered.