Subscene baseline mismatch

I have an issue related to pre-spawned ghosts. I get the following error when starting the game:

Reason is the following code, which is executed by the server on level startup, so before any client connects. The code sets the data of a ghost component used on all pre-spawned ghosts of that archetype:

      // Set modifications on pre-spawned ghosts to trigger a change and cause mirroring to work properly
      // (Only required on server, because it syncs to the clients)
      foreach (var (_, entityTracking, coverEntity) in SystemAPI.Query<PureCover, EntityTracking>()
                 .WithOptions(EntityQueryOptions.IncludeDisabledEntities)
                 .WithEntityAccess())
      {
        var updatedTracking = entityTracking;
        updatedTracking.ModificationServerTickIndex = serverTickIndex;
        commandBuffer.SetComponent(coverEntity, updatedTracking);
      }

I think it is not of interesset but just in case here the code of the component:
EntityTracking

  /// <summary>
  /// A component used for change tracking of entities.
  /// </summary>
  [GhostComponent]
  [StructLayout(LayoutKind.Explicit, Size = EntityTracking.Size, Pack = 4)]
  public struct EntityTracking : IComponentData
  {
    /// <summary>
    /// Size of the struct.
    /// </summary>
    public const int Size = sizeof(uint) * 3;

    /// <summary>
    /// Gets or sets the server tick index on which the entity has been created.
    /// When zero entity entity exists since start. This is used for pre-spawned ghosts for example.
    /// </summary>
    [FieldOffset(0)]
    [GhostField]
    public uint CreationServerTickIndex;

    /// <summary>
    /// Gets or sets the server tick index on which the entity has been disposed.
    /// When zero entity is not disposed yet.
    /// </summary>
    [FieldOffset(4)]
    [GhostField]
    public uint DisposalServerTickIndex;

    /// <summary>
    /// Gets or sets the server tick index on which the entity has been modified last.
    /// Creations and disposals are also always updating this field.
    /// When zero entity entity exists since start and was never changed. This is used for pre-spawned ghosts for example.
    /// </summary>
    [FieldOffset(8)]
    [GhostField]
    public uint ModificationServerTickIndex;
  }

I suspect it has something to do with modifying pre-spawned ghosts before any clients connects, but how should this be done?

I am using Netcode for Entties 1.0.12.

If it write data to the pre-spawned ghosts before the server or the client calculate the baselines and relative hashes that can cause the mismatching problem.

That system must run on both server and client in order to have the same baseline data serialised when the PrespawnInitializationSystem will run.

And being the EntityTracking replicated (CreationServerTickIndex in particular) that will cause a problem during serialization, because client and server will start from a different value to calculate the delta compression

1 Like

Thanks for quick answering, @CMarastoni .

I see. I cannot rely on the server tick index then, because these differ between server and client cause of different times of execution. Unfortunately also the system in charge here is executed after connecting on client-side, so it would still be too late. But I came up with the following solution now, executing the code on server and client:

      // Set modifications on pre-spawned ghosts to trigger a change and cause mirroring to work properly
      foreach (var (_, entityTracking, coverEntity) in SystemAPI.Query<PureCover, EntityTracking>()
                 .WithOptions(EntityQueryOptions.IncludeDisabledEntities)
                 .WithEntityAccess())
      {             
        // No value is changed here, but entity queries using a change filter on EntityTracking still detect the change which is sufficient for triggering
        commandBuffer.SetComponent(coverEntity, entityTracking);
      }

One more question: After a client connected to the server, when another client connects there is no more issues when pre-spawned ghost components changed in the meantime by the server, isn’t it?

Yes, the baseline are initialised once, after the first client go in game. After that point making modification is absolutely ok.

1 Like