I/O is the conversation your game has with the world. Information flows in — from the keyboard, from the config, from the network — your code reacts, and something gets sent back out to the screen. Every interactive moment runs through this loop.
Click any channel to see how it moves data.
Game
I / O
Keyboard
GameEnv
API
Canvas

Pick a channel above to see what it does.

  1. Canvas Rendering (Output). Draws every visible pixel, every frame. ctx.fillRect(x, y, w, h) paints rectangles; ctx.drawImage(sprite, x, y) paints sprites. Used for sprites, backgrounds, UI, and animations.
  2. Keyboard Events (Input). Listens for physical key presses. window.addEventListener("keydown", (e) => { ... }) fires whenever a key goes down. Used for movement, jumping, attacking, and menu navigation.
  3. GameEnv Config (Input). A bundle of startup settings that defines the rules — gravity, debug mode, canvas size, difficulty. Loaded once at boot and read by every system after that.
  4. API Calls (I/O). Sends data out to a server and waits for data back. fetch("/api/score") returns a Promise with the response. Used for leaderboards, cloud saves, dynamic AI behavior, and multiplayer sync.
Click a system to switch tabs.

Keyboard Events — Input

Translates physical key presses into in-game actions.

window.addEventListener("keydown", (e) => {
  if (e.key === " ") player.jump();
});

keydown fires on press, keyup on release. Used for movement, jumping, attacking, menu navigation.

GameEnv Config — Input

System-level input that's set once at startup — not from the player, from your own code.

const gameEnv = { gravity: 0.4, debug: false };

Defines canvas size, gravity, physics, difficulty, and asset paths. Everything else builds on top of these values.

API Calls — Input + Output

Two-way communication with a server.

fetch("/api/score")
  .then(res => res.json())
  .then(data => show(data));

Sends data out and gets data back. Used for leaderboards, cloud saves, dynamic AI, multiplayer.

Canvas Rendering — Output

Draws everything the player sees, every frame.

ctx.fillRect(x, y, w, h);
ctx.drawImage(sprite, x, y);

Renders sprites, backgrounds, UI, effects. The final step in the loop: state updates first, then the canvas draws it.

Channel
Direction
Game use
Keyboard
Input
Movement, jumping, menus
GameEnv
Input (startup)
Gravity, canvas size, difficulty
API
Input + Output
Scores, saves, multiplayer
Canvas
Output
All visuals every frame
  • Input updates state. Output draws state. The game loop is the bridge between them — it runs every frame.
  • Keyboard events are asynchronous — they fire when the OS notices them, not on a fixed schedule.
  • GameEnv is read-only after startup. It sets the rules everything else plays by.
  • APIs return Promises — don't use the response before it actually arrives. await it or chain .then().