Files
forgotten_caves/notes/01-input_manager.md
irrlichtandClaude Opus 5 64a6e1d42d Rewrite notes for the single-player architecture
Drop protocol.md; rewrite the tick-loop note around the game-loop-driven sim
and the intent model; rewrite the roadmap (network items removed, sim/game
crate layout, save/load and NPC blocking added); fix crate paths in the
remaining notes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 23:00:19 +02:00

2.2 KiB
Executable File

Input Manager

Current state

Input is fully decoupled from the windowing backend. game/src/input.rs owns all input types. main.rs translates pbio::Event::Key events into GameAction values each frame and stores them in an InputState. game::update() receives a &InputState and queries it with three distinct semantics. (The platform/windowing layer lives in the external pbio crate; game code only ever sees pbio::Key, never a raw backend type.)

Architecture

GameAction — game/src/input.rs

Logical actions the game cares about. Game code never sees backend key types.

pub enum GameAction { Up, Down, Left, Right, Confirm, Cancel }

InputMap — game/src/input.rs

Translates a pbio::Key to an Option<GameAction>. All key bindings live here.

Key Action
Up / W Up
Down / S Down
Left / A Left
Right / D Right
Enter Confirm
Escape Cancel

InputState — game/src/input.rs

Three internal buffers, populated from pbio::Event::Key events in main.rs:

Buffer Lifetime Populated by
pressed current frame key-down event
held until released key-down; cleared on up
released current frame key-up event

clear() is called after game::update() each frame. It clears pressed and released; held persists until the corresponding key-up event arrives.

Query API

input.button_pressed(action)  // true only on the frame the key went down
input.button_held(action)     // true every frame the key is physically held
input.button_released(action) // true only on the frame the key was released

Data flow per frame

pbio::Event::Key
  → InputMap::translate(key)
  → InputState::push / InputState::release
  → game.update(&mut framebuffer, dt, &input_state) -> Option<GameSignal>
  → input_state.clear()

Open questions

  • Should modifier keys (Shift, Ctrl) produce distinct actions, or be handled in the mapping?
  • How do we prepare for key rebinding?