Hi,
We’re facing an issue that sounds very similar to the one presented and discussed here: Inputs occasionally missed or processed twice on the server.
Basically, we’ve managed to reproduce a bug with a very minimal setup that causes inputs (IInputComponentData
value changes) to not be picked up/seen/received by the server. Here’s the minimal project zipped up: NetcodeBootstrap.zip - Google Drive.
The issue is reproducible even when running the server & client on the same machine, all inside the editor - i.e. with latency of ~10-15ms (which also seems a bit high for running it all locally, but that’s a topic for another day).
We have a few components (simplified slightly here):
public struct TestInputComponent : IInputComponentData
{
public float Value;
}
[GhostComponent(PrefabType = GhostPrefabType.All)]
public struct TestGhostComponent : IComponentData
{
[GhostField]
public float Value;
}
A very simple input system:
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)]
[UpdateInGroup(typeof(GhostInputSystemGroup))]
public partial class TestInputSystem : SystemBase
{
protected override void OnUpdate()
{
foreach (var (input, ghost) in SystemAPI.Query<RefRW<TestInputComponent>, RefRO<TestGhostComponent>>())
{
if (Input.GetKeyUp(KeyCode.Space))
{
input.ValueRW.Value = 10f;
Log.Info($"Client input set to {input.ValueRO.Value} now, current ghost value: {ghost.ValueRO.Value} (new intended value: {ghost.ValueRO.Value + input.ValueRW.Value})");
}
else
{
input.ValueRW.Value = 0f;
}
}
}
}
And a very simple input handler system:
[WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation | WorldSystemFilterFlags.ClientSimulation)]
[UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
public partial struct TestHandleInputSystem : ISystem
{
public void OnUpdate(ref SystemState state)
{
state.Dependency = new ApplyJob()
.Schedule(state.Dependency);
}
[WithAll(typeof(Simulate))]
private partial struct ApplyJob : IJobEntity
{
private void Execute(in TestInputComponent input, ref TestGhostComponent ghost)
{
ghost.Value += input.Value;
}
}
}
Beyond that there is some boilerplate code to spawn in an authored ‘prefab’, do some more debug logging and display the component values to UI, but those are just for being able to run the test and debug. The code has been tested as is presented above, even if the zipped project has slightly more code.
Here’s the authored prefab with its GhostAuthoringComponent
:
(see next comment, I can only add one embed apparently)
It works as intended most of the time, but somewhere between 5% and 30% of the time the input is simply not handled on the server. With simple debug logging we can compare the ‘normal intended’ flow (green) with the error flow (red):
(see next comment, I can only add one embed apparently)
Notice how the ClientWorld updates are followed by a single ServerWorld update in the ‘OK!’ scenario, but not in the error scenario.
Since we’re testing with server & client on the same machine, we are assuming that packet drops are not supposed to occur - is that fair to assume?
Tested in Unity 6000.0.27f1
.
Entities version 1.3.5
.
Netcode for entities version 1.3.6
.
So what gives? Please help! Any insight is appreciated, as we are failing to understand why or how this happens.