gameplate - v2.2.0
    Preparing search index...

    gameplate - v2.2.0

    gameplate

    gameplate

    State. Loop. Input. Scenes. Selectors. Ship a game today.

    npm CI gzip types license

    npm install gameplate
    
    import { createGame, defineActions } from 'gameplate';

    const actions = defineActions<{ x: number }>()({
    moveBy: (s, dx: number) => ({ x: s.x + dx }),
    });

    const game = createGame({
    state: { x: 0 },
    actions,
    update: (state, dt, actions) => {
    if (game.keyboard.isDown('ArrowRight')) actions.moveBy(200 * dt);
    },
    render: (state) => draw(state), // 👈 your renderer, any tech
    });

    game.start();

    That's the whole API surface. Read it, write it, ship it.


    • 🪶 3 KB gzipped. Smaller than a single sprite sheet. Zero runtime deps. Forever.
    • 🦺 TypeScript-first. strict: true + every noUnchecked* flag. Inference does the work — no as any, ever.
    • 🎯 Renderer-agnostic. Canvas · WebGL · WebGPU · PIXI · Three.js · DOM · terminal. Pick one. Switch tomorrow.
    • ⏱️ Deterministic loop. Variable timestep by default; opt into fixed-step + interpolation when physics need to be reproducible.
    • 🎮 Input, normalized. Keyboard + pointer + gamepad (with radial-deadzoned sticks and edge detection). Headless no-ops cleanly — same API on Node.
    • 🎬 Typed scene FSM. menu → start → playing with compile-time checks. Send a wrong event? TypeScript stops you.
    • 🧠 Memoized selectors. Reselect-style derived state, ~30 LOC, exact same shape.
    • 🎞️ Record & replay. Capture every dispatched action; replay it deterministically. Bug repro, regression tests, server-authoritative validation — all in JSON.
    • 🖥️ Browser & Node. Headless simulation, server-authoritative play, CI snapshot tests — same code, two runtimes.
    • 📦 Dual ESM + CJS. publint clean. Provenance signed. Tree-shakeable.

    type State = { player: { x: number; y: number }; score: number };

    const actions = defineActions<State>()({
    move: (s, dx: number, dy: number) => ({
    ...s,
    player: { x: s.player.x + dx, y: s.player.y + dy },
    }),
    score: (s, pts: number) => ({ ...s, score: s.score + pts }),
    });

    const game = createGame({ state: { player: { x: 0, y: 0 }, score: 0 }, actions });

    game.actions.move(10, 0); // ✅ typed
    game.actions.move('lol', 0); // ❌ TS error — caught at compile time

    That's state + actions. Add update for input handling, render for drawing, and you have a game.


    createGame One-call setup — state + loop + input wired together.
    createStore The underlying typed store (subscribe, getState, setState).
    defineActions Curried generic that gives perfect IntelliSense without retyping S.
    createLoop Bare loop — variable or fixed-step with interpolation alpha.
    createKeyboard / createPointer / createGamepad Normalized input — keys, pointer, and Standard Gamepad with edge detection. No-op stubs on the server.
    createMachine Compile-time-checked finite state machine for scenes/menus.
    createSelector Reselect-style memoization, ~30 LOC.
    createRecorder / replay Deterministic record + replay of every action. JSON-serialisable.

    → Full API reference


    gameplate doesn't ship a renderer — it ships the glue. Drop into:

    three.js PIXI v8 regl WebGPU Canvas 2D

    Switch renderers without changing one line of game logic. Patterns for each →


    keyboard ─┐
    🖱 pointer ─┼──▶ actions ──▶ store ──▶ selectors ──▶ render ──▶ 🎨 your renderer
    🛰 network ─┘ │ ▲
    ▼ │
    scene FSM ──────────────────┘

    loop (dt, alpha) ──▶ update ──▶ actions

    A handful of composable functions. Pick the ones you need. Ignore the rest.


    • ✅ 141/141 tests, ≥ 90 % line coverage
    • ✅ CI matrix: Node 20 / 22 / 24 × Ubuntu / macOS / Windows
    • publint + @arethetypeswrong/cli clean on every PR
    • ✅ Size limit: < 4 KB gzipped ESM, enforced in CI
    • ✅ CodeQL security analysis on every PR
    • ✅ npm provenance on every release (OIDC trusted publishing)

    PRs welcome. See CONTRIBUTING.md. Architecture decisions are recorded in DECISIONS.md.

    git clone https://github.com/yankouskia/gameplate
    cd gameplate
    pnpm install
    pnpm test:watch

    MIT © Alex Yankouski · Sponsor →

    If gameplate saved you a weekend, ⭐ star it — it's the easiest way to say thanks.