public sealed class InputBuffer<T> where T : struct, IPredictedInput<T>Holds one client's inputs until the tick they belong to comes round. Server-side.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
A jitter buffer, and the reason a predicting client runs ahead of the server. An input has to be in the server's hands before the tick it is for, or the server simulates that tick without it — so the client stamps its inputs with a tick a little in the future and the server holds them until it gets there. TargetDepth is how much slack that is, and the whole of prediction's latency budget is in it: too little and the buffer starves on every jitter spike, too much and the player's own actions take longer to reach the world than they need to.
Starvation repeats the last input rather than zeroing. The tick has to be simulated with something, and zero is the worst available choice: a player holding forward would stop dead for one tick on the server while their own client predicted them still moving, which turns a dropped packet into a guaranteed correction. Repeating is usually exactly what the client predicted, so most starvation costs nothing at all — and StarvedCount is how anybody finds out it is happening.
The counters are a control signal, not diagnostics. Depth against TargetDepth is what the server sends back so the client can adjust its lead — a buffer that keeps starving means "run further ahead", and one that keeps growing means "you are further ahead than you need to be, and paying for it in input latency".
Fields and properties (13)
public int TargetDepthHow many ticks of input the server would like to be holding.
public int CapacityThe most ticks of input to hold before refusing the ones furthest ahead.
public Tick NewestThe newest tick an input is held for.
public bool HasAnyWhether anything is held.
public int DepthHow many ticks of input are waiting to be used.
public long StarvedCountTicks simulated with no input, which repeated the last one.
public long LateCountInputs that arrived for a tick already simulated, and could not be used.
public long DuplicateCountInputs already held when they arrived. Redundancy working, not a problem.
public long RefusedCountInputs refused because the client was running further ahead than the buffer holds.
public long MalformedCountPayloads that did not decode.
public Tick AcknowledgedThe newest tick this buffer has an input for, for telling the client.
public bool HasAcknowledgedWhether anything has been received at all.
public InputHealth HealthEverything worth reporting back, in one value.
Methods (4)
public bool TryReceive(ReadOnlySpan<byte> payload, Tick simulated)Takes a payload of inputs.
public void Offer(Tick tick, in T input, Tick simulated)Files one input directly, for a server that is also the client.
public bool TryTake(Tick tick, out T input)Takes the input for a tick, so the tick can be simulated.
public void Clear()Forgets everything, for a player who has gone.
Used by (2)
- InputBufferTargetVixen.Net.Fuzz
- PredictedInputTestsVixen.Net.Tests