PVG
4. Simple Input Handling — Program Video Games

4. Simple Input Handling

Every action in a game starts with a player's intention, expressed through input. In our System Stack, Input sits at the foundation level - a core system that many others depend on.

Today we're discussing the concept of input systems and how they form the bridge between player intention and game action.

Input in the Fractal Code Cycle

Recall our fundamental pattern:

Input → Processing → Output

For an input system at the game level:

  • Input: Physical device interactions (keyboard, mouse, gamepad)
  • Processing: Converting device states to meaningful game actions
  • Output: Game action states that other systems can use

The Concept of Input Abstraction

Why Abstract Input?

  1. Decoupling: Separate what the player is doing from how the game interprets it
  2. Flexibility: Change control schemes without changing game logic
  3. Consistency: Support multiple input devices through the same interface

Layers of Abstraction

  1. Physical Layer: The actual hardware events (key press, button click)
  2. Device Layer: The software representation of those events (key down, key up)
  3. Logical Layer: The game action these represent (move up, jump, interact)

Most game engines handle the first two layers. As game developers, we focus on translating the device layer to the logical layer.

Input States

Types of Input States

  1. Binary States: On/off, pressed/not pressed
  2. Continuous States: Analog values like joystick position (0.0 to 1.0, or -1.0 to 1.0)
  3. Edge Triggers: Detecting the moment of change (just pressed, just released)

State Duration

  1. Press: Triggered once when input begins
  2. Hold: Continuous while input is active
  3. Release: Triggered once when input ends

Different game actions may require different state types. For example:

  • Movement often uses hold state (continuous while key is down)
  • Jumping might use press state (triggered once on key press)
  • Charge attacks might use both press and release states

Input in the Game Loop

The Input Phase

In our Game Loop pattern:

for each frame:
    input()
    update()
    render()

The input() phase is responsible for:

  1. Polling device states from the hardware/engine (input, raylib in our case)
  2. Transforming those states into game action states (processing)
  3. Making those action states available to other systems (output, storing in GameState)

Input and Time

Input is tied to the current frame. We capture a snapshot of the input state that remains consistent throughout the frame, even if the physical input changes mid-frame.

Input in Our System Stack

Recall our System Stack organization:

  • Base Layer: Entities, Input, Time, Assets, Save/Load
  • Presentation: Camera, Shaders, Animation, UI, Particles
  • Interaction: Player, Collisions, AI, Scenes
  • Game Systems: Stats, Combat, Inventory, Abilities
  • Content: Dialogue, Quests, NPC Schedules

Input sits in the base layer because:

  1. It has no dependencies on other game systems
  2. Many higher-level systems depend on it
  3. It interfaces directly with the hardware/engine (raylib)

Input System Design Considerations

Configurability

Players may want to remap controls. A well-designed input system should make this easy by:

  • Separating key mapping from input processing
  • Storing mappings in a configurable format
  • Supporting multiple control schemes

We will cover this in a later lecture, but it's something to keep in mind when designing your input system.

Accessibility

The scope of this varies wildly depending on game type.

For a turn-based RPG, I'd say we can offer binding of any action to any button or joystick that's detected, and that should be enough.

Context Sensitivity

The same input might mean different things in different contexts:

  • E might mean "interact" in exploration but "select" in a menu
  • WASD might control movement in exploration but menu navigation in UI

A robust input system adapts to these changing contexts.

Try It Yourself

  1. Think about a game you enjoy. What are its input abstractions? How do physical inputs map to game actions?
  2. Consider a complex action in a game (like a combo move). How might that be represented in an input system?
  3. How would you design an input system that supports both keyboard/mouse and gamepad for the same game?

The Big Idea

A well-designed input system creates a layer of abstraction that decouples physical input from game behavior, providing flexibility and consistency across your game.

The specific implementation is simple and straightforward code. The thing to keep in mind is your player's available actions in the game.

Make it intuitive for them.