Skip to content

Input System

The input system provides a deterministic pipeline for player input. Inputs are queued and applied at the start of each fixed update, ensuring consistent behavior during recording and playback.

Defining Input Components

Mark component fields with [Input] in a template:

public partial class SnakeGlobals : ITemplate, IExtends<TrecsTemplates.Globals>
{
    [Input(MissingInputFrameBehaviour.RetainCurrent)]
    public MoveInput MoveInput;
}

MissingInputFrameBehaviour

Controls what happens when no input is provided for a frame:

Behaviour Effect
RetainCurrent Keep the last input value
ResetToDefault Reset to the component's default value

Queuing Input

Input is queued from outside the ECS update loop (e.g., from a MonoBehaviour):

world.AddInput(entityIndex, new MoveInput { Direction = dir });

Reading Input in Systems

Input systems run first, before the fixed update phase. Mark them with [InputSystem]:

[InputSystem]
public partial class ProcessInputSystem : ISystem
{
    [SingleEntity(Tag = typeof(GlobalTag))]
    void Execute(in MoveInput input)
    {
        // input.Direction contains the queued input for this frame
    }
}

Input and Determinism

The input system is designed for deterministic replay:

  • Inputs are applied at fixed update boundaries, not at variable frame rate
  • During recording, inputs are captured alongside world state
  • During playback, input systems are not run, and instead recorded inputs replace live input
  • MissingInputFrameBehaviour ensures consistent behavior when frames are skipped or repeated