Skip to content

Buffered Input

Buffered Input allows you to detect button presses that happened slightly before your FSM was ready to react. For example, a jump button pressed just before landing.

This is extremely common in action games, platformers, and fighting games, where small timing assists make controls feel responsive.

A BufferedInput stores:

  • The time a button was last pressed
  • A buffer window (in seconds)
  • Whether the press has been consumed or is still available

This enables features like:

  • Early jump buffering
  • Attack buffering
  • Dodge windows
  • Fighting-game chords (two buttons pressed together)
  • Input sequences
  • AI-driven or test input

A buffered press can be checked, consumed, combined with others, or triggered manually.


How BufferedInput Works

When a button is pressed (via real input or a simulated press):

  1. Record() stores the press time.
  2. The press becomes available for a limited duration (the buffer window).
  3. Actions such as CheckBufferedInput or CheckBufferedChord can:
  4. Detect whether a buffered press is available
  5. Optionally consume it (making it unavailable)
  6. Once the window expires, the press is no longer available.

Typical buffer values range from 0.05s to 0.15s depending on the game feel.


Buffered Input Actions

Below is the list of provided actions for working with BufferedInput values.


RecordBufferedInput

Manually records a press on a BufferedInput variable.
Useful for AI input, tutorials, scripted behavior, or integration tests.

Options:

  • Override buffer window

CheckBufferedInput

Checks whether a buffered press is available (unconsumed and within the buffer window).

Options:

  • Override window for this check
  • Consume press on success (default)

This is the core action for jump buffering, dodge buffering, etc.


CheckBufferedChord

Checks whether two buffered inputs were pressed within a short time of each other.

Example uses:

  • Punch + Kick → Throw
  • Dash button + direction
  • Multi-button ability triggers

Options:

  • Require both presses to still be available
  • Consume both on success
  • Max chord window (default: 0.05s)

Rejects “ghost chords” by ensuring both inputs were pressed at least once.


CheckBufferedSequence (coming soon)

Checks whether a sequence of inputs happened in order within timing constraints.
Useful for fighting-game motions, combos, and gesture inputs.


Using Buffered Input in FSMs

A typical pattern:

  1. Record input

    • InputGetButtonDown → records into a BufferedInput
  2. Check buffered press

    • In another state (e.g., Landed), run CheckBufferedInput
  3. Consume & react

    • True → Jump
    • False → idle or fallback behavior

Example:

State: In Air
InputGetButtonDown(Jump, JumpBufferedInput)

State: Landed
CheckBufferedInput(JumpBufferedInput) → Jump

Even if the player hit Jump just before landing, the press is still caught.


Best Practices

  • Keep buffer windows small (0.05–0.15s) for responsive but fair input.
  • Chords often work best with RequireFreshInputs = true.
  • Use PressBufferedInput in tests and AI input systems for deterministic behavior.
  • Most actions default to consuming the press on success - this prevents repeated triggers.