From 10e4766809ed9669e28eae5ef8230a798ac5a510 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:31:57 +1200 Subject: [PATCH] Try fix UI state debug assert (#6191) * Try fix UI state debug assert * comment --- .../GameStates/GameStateProcessor.cs | 40 ++++++++++++------- .../Systems/SharedUserInterfaceSystem.cs | 2 +- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Robust.Client/GameStates/GameStateProcessor.cs b/Robust.Client/GameStates/GameStateProcessor.cs index ed44c72d0b..bf5a97d2d2 100644 --- a/Robust.Client/GameStates/GameStateProcessor.cs +++ b/Robust.Client/GameStates/GameStateProcessor.cs @@ -220,24 +220,34 @@ Had full state: {LastFullState != null}" { var compState = change.State; - if (compState is IComponentDeltaState delta - && compData.TryGetValue(change.NetID, out var old)) // May fail if relying on implicit data + if (compState is not IComponentDeltaState delta) { - DebugTools.Assert(old is not IComponentDeltaState, "last state is not a full state"); - - if (cloneDelta) - { - compState = delta.CreateNewFullState(old!); - } - else - { - delta.ApplyToFullState(old!); - compState = old; - } - DebugTools.Assert(compState is not IComponentDeltaState, "newly constructed state is not a full state"); + compData[change.NetID] = compState; + continue; } - compData[change.NetID] = compState; + if (!compData.TryGetValue(change.NetID, out var old)) + { + // Either the server needs to ensure that the initial state it sends to a client is a full + // state, or the client needs to be able to construct an implicit full state (i.e., get-state + // code needs to be in shared code). + // + // Without this, the client won't be able to reset predicted changes made to this component. + DebugTools.Assert("Received delta state without having received or constructed an implicit full state"); + continue; + } + + DebugTools.Assert(old is not IComponentDeltaState, "last state is not a full state"); + + if (!cloneDelta) + { + delta.ApplyToFullState(old!); + continue; + } + + var newFull = delta.CreateNewFullState(old!); + compData[change.NetID] = newFull; + DebugTools.Assert(newFull is not IComponentDeltaState, "constructed state is not a full state"); } if (entityState.NetComponents == null) diff --git a/Robust.Shared/GameObjects/Systems/SharedUserInterfaceSystem.cs b/Robust.Shared/GameObjects/Systems/SharedUserInterfaceSystem.cs index 4aa458b65b..92093acf13 100644 --- a/Robust.Shared/GameObjects/Systems/SharedUserInterfaceSystem.cs +++ b/Robust.Shared/GameObjects/Systems/SharedUserInterfaceSystem.cs @@ -305,7 +305,7 @@ public abstract class SharedUserInterfaceSystem : EntitySystem private void OnUserInterfaceGetState(Entity ent, ref ComponentGetState args) { - if (ent.Comp.LastFieldUpdate >= args.FromTick) + if (args.FromTick > ent.Comp.CreationTick && ent.Comp.LastFieldUpdate >= args.FromTick) { var fields = EntityManager.GetModifiedFields(ent.Comp, args.FromTick);