Skip to content

Core.Utilities.BufferedDirection

Dennis Steffen edited this page Jan 4, 2026 · 1 revision

The BufferedDirection class is a utility designed to manage movement input, specifically handling cases where you want a direction to "persist" for a short duration even after the user stops providing input (buffering). This is commonly used in games to make movement feel more responsive or to allow for "coyote time" in directional logic.

Key Components of BufferedDirection

  1. Input Buffering: It uses a TimerOn and a _wantDirection variable. If the raw input becomes zero, it retrieves the last known non-zero direction (_wantDirection). The timer determines how long this "cached" direction remains valid.
  2. Direction State: The Direction property provides the current processed vector, while IsGoingTowards is a helper to check if that direction is non-zero.
  3. Change Detection: The methods IsDirectionChanged and IsDirectionChangedAndIsNotZero allow you to compare the current input direction against an existing velocity. It uses normalized vectors to detect if the intended direction has shifted, even if the magnitudes differ.

How Update Works:

  • New Input: If raw input is non-zero, it updates the "wanted" direction.
  • No Input: If raw is zero, it tries to use the "wanted" direction.
  • Expiration: The timer runs as long as there is a wanted direction. Once the bufferTime expires, _wantDirection is reset to zero, effectively stopping the movement.

Usage Example

In this example, a player controller uses BufferedDirection to ensure that a quick "flick" of an analog stick or a brief key press results in a sustained movement for a fraction of a second, preventing "stuttery" movement.

using System.Numerics;
using Meatcorps.Engine.Core.Utilities;

public class PlayerMovement
{
    private BufferedDirection _directionHandler;
    private float _moveSpeed = 500f;
    private Vector2 _currentVelocity = Vector2.Zero;

    public PlayerMovement()
    {
        // Buffer the direction for 0.2 seconds
        _directionHandler = new BufferedDirection(0.2f);
    }

    public void OnUpdate(Vector2 inputDeviceRaw, float deltaTime)
    {
        // 1. Update the buffer with raw input (e.g., from a keyboard or joystick)
        _directionHandler.Update(inputDeviceRaw, deltaTime);

        // 2. Check if the direction has changed relative to our current movement
        if (_directionHandler.IsDirectionChanged(_currentVelocity, _moveSpeed, out var newVelocity))
        {
            // Update velocity if the player is trying to go somewhere else
            _currentVelocity = newVelocity;
        }

        // 3. Move the character based on the buffered direction
        if (_directionHandler.IsGoingTowards)
        {
            Console.WriteLine($"Moving towards: {_directionHandler.Direction} with speed {_moveSpeed}");
            // Perform actual position translation here:
            // Position += _currentVelocity * deltaTime;
        }
        else
        {
            _currentVelocity = Vector2.Zero;
            Console.WriteLine("Standing still.");
        }
    }
}

Why use this?

  • Input Noise: It filters out cases where a physical controller might briefly report 0,0 due to hardware deadzones.
  • Animation Transitions: It provides a stable Direction vector that can be used to keep a character facing their last moved direction for a few frames, making transitions smoother.
  • Gameplay Feel: It allows players to perform actions that require a direction (like a dash or a specific attack) slightly after they have released the movement keys.

Clone this wiki locally