Improbable Icon

Issue: Transform synchronization


i am trying the set up the blank starter project with the feature module for transform synchronization. But i can’t get it to work.

Based on the documentation i tried the following steps:

  • Adding TransformSynchronizationHelper.AddClientSystems(Worker.World); in my UnityClientConnector class within the HandleWorkerConnectionEstablished method.
  • Adding TransformSynchronizationHelper.AddServerSystems(Worker.World); in my UnityGameLogicConnector class within the HandleWorkerConnectionEstablished method.
  • Adding TransformSynchronizationHelper.AddTransformSynchronizationComponents(template, serverAttribute); to my CreatePlayerEntityTemplate method for player creation.
  • Create following transform strategies






  • Adding the transform synchronization script to the following player prefabs (capsule)

Authoritative Player

None Authoritative Player


At the moment i can see other player capsules and can walk with the individual players (development scene + additional client through standalone client), but the transform synchronization not working.

Any suggetions to get this to work?

Thanks in advance!

Hello Michael, how are you?

First of all, thank you for sending so many details about your setup, it really helps us to help you!

Let me ask you one more piece of information, though: Can you run your game and send a screenshot of the Transform Synchronization component both for the authoritative player and GameLogic player, also make sure to expand the info below SpatialOS by clicking on the arrow next to it? This is mine for my authoritative player while the game runs


I want to ensure that the Transform Synchronization component is enabled.

Hey Jay!

I’m feeling good so far. I hope you as well!

If i run my development scene, the following details are displayed:

Authorative player:

GameLogic player

I hope I haven’t missed anything totally obvious somewhere. Have really tried a lot in the meantime.

The bug was in my PlayerCreatorPipeline class. As a result, the transform was not executed correctly. Now it is working as intended. I’m sorry for the time invested!

But i have still some overall questions regarding the transform synchronization module:

  • The fps starter project does not use the module. Is there a special reason for this?
  • What is the best way to add movement validation on server side?
  • Or should you rather not use the module if you need any kind of server side validation?


Hey @michael.joehnke,

Apologies for the delay in a response, I was offline yesterday.

Glad to hear you got it sorted out! Can you expand what was missing on your PlayerCreatorPipeline?

Regarding your questions

  • The FPS project came before the Player Synchronization module was created

  • There are different ways of doing the server side movement validation, if you want to know more a good starting point is Gabriel Gambetta’s article on the topic of server conciliation -

  • Since you can read the content of the Transform Synchronization components you can definitely use it along server side validation, it is entirely up to you.

Let me know if I can help further!

Hi there! I got some issue too, I was trying to add this on Blank Starter project and I can’t even write this on the UnityClientConnector, there is no reference of that class anywhere?

Even with a “using Improbable.Gdk.TransformSynchronization;”, I am doing it wrong?

Hello @OmeGaCinoS ,

Check if your project Import Settings have the TransformSynchronization assembly reference added to it

Oh yeah of course! -_-! Totally forget about that thanks!

I try to make it all like michael.joehnke to work it out, but I got two different player at the same place…

This is making things like that, I’m working on the FPS project to check difference but, I remove all script from the original player, but all the script continue to work, like initialization etc.

But before I put TransformSynchronization, I was able to move on local without problem, but there was no link to update the position into the server.

Hello @OmeGaCinoS,

Glad to hear that!

Just to confirm I understood: After you got transform synchronization working, the two players started showing up in the same place? And that did not happened before?

Hi, yeah totally, I follow Michael.joehnke step, to see if I can totally reproduce his success! xD So I’m based on his screen and object.

I can see quickly at the beginning my player is at his own place, but, 1 sec later, that’s teleporting me on the other player. And I can’t move.

Can you show me how you’re setting up your transform synchronization component within the entity template?

I am attempting the exact same as @michael.joehnke, but I cannot get the transform sync to work. I believe it is because my QBI is messed up.

This is my entity template

public static class EntityTemplates {
    public static EntityTemplate CreatePlayerEntityTemplate(EntityId entityId, string workerId, byte[] serializedArguments) {
        var clientAttribute = EntityTemplate.GetWorkerAccessAttribute(workerId);
        var serverAttribute = UnityGameLogicConnector.WorkerType;

        var template = new EntityTemplate();
        template.AddComponent(new Metadata.Snapshot("Player"), serverAttribute);
        template.AddComponent(new Position.Snapshot(), clientAttribute);

        TransformSynchronizationHelper.AddTransformSynchronizationComponents(template, serverAttribute);
        PlayerLifecycleHelper.AddPlayerLifecycleComponents(template, workerId, serverAttribute);

        var serverSelfQuery = InterestQuery.Query(Constraint.EntityId(entityId));
        var serverRangeQuery = InterestQuery.Query(Constraint.RelativeCylinder(1000));

        var clientSelfQuery = InterestQuery.Query(Constraint.EntityId(entityId));
        var clientRangeQuery = InterestQuery.Query(Constraint.RelativeCylinder(500));

        var interest = InterestTemplate.Create()
            .AddQueries<Metadata.Component>(serverSelfQuery, serverRangeQuery)
            .AddQueries<Position.Component>(clientSelfQuery, clientRangeQuery)
            .AddQueries<TransformInternal.Component>(serverSelfQuery, serverRangeQuery);
        template.AddComponent(interest.ToSnapshot(), serverAttribute);

        template.SetReadAccess(serverAttribute, clientAttribute);
        template.SetComponentWriteAccess(EntityAcl.ComponentId, serverAttribute);
        return template;

Am I setting this template up correctly? I am currently trying to get my authoritative client to update the server workers entity, but it wont budge. The client sees the player moving correctly, but the server workers version never moves.

For more detail here is the client worker:

and the server worker:

I am sure I am doing something very silly, but in the absence of a full example for transform sync this is pretty difficult. Can anyone spot my mistake please?

It would also be nice if there was a full project example of the transform sync to see.

Hey @Poynter_Benjamin,

This is something I’m working on, stay tuned :slight_smile:

i can’t get it to work too. Can you share your PlayerCreatorPipeline class.?