more creativity, less setup.
An open-source toolkit for 2D browser games. It handles the boring bits so you can get to the fun part sooner.
An open-source toolkit for 2D browser games. It handles the boring bits so you can get to the fun part sooner.
Empowering best-in-class 2D web games
Every game starts as a spark: a world to poke at, a jump that feels just right, a joke only you would make. Then the plumbing shows up. Game loop, crisp pixels, controls, sound, levels, assets, and figuring out why it broke. The spark can fizzle before it ever gets to play.
debuff does the plumbing. You get to tinker, wobble things, break them on purpose and keep the bits that make you grin.
No spelunking through game.world.systems.physics.step(). A game is a scene with update and render, and the fun stuff is one call away.
const game = new Game({ canvas, width: 320, height: 180 });
const input = new Input(game, {
bindings: { pop: ["Space", "PadA", "Pointer"] },
});
game.add(play).go("play");
game.start();// Too floaty? Drag the slider in the dev panel until it feels right.
const tuning = game.params.define("player", {
speed: { type: "number", default: 140, min: 0, max: 600, units: "px/s" },
});
player.vx = approach(player.vx, dir * tuning.values.speed, accel * dt);if (input.pressed("pop")) {
// squish, sparkle, rumble, boop
squash(tweens, player, 0.35);
particles.emit({ x: player.x, y: player.y, count: 16, gravity: 200 });
game.camera.shake(0.3);
audio.synth({ freq: 660, freqEnd: 220, decay: 0.15 });
}import { expect, play, test } from "keiko";
test("never leaves the screen", async () => {
const game = await play<State>();
game.press("ArrowLeft");
game.during("3s", (s) => s.player.x >= 8, "buff stays on screen");
});{
"steps": [
{ "press": "ArrowRight" },
{ "wait": 30 },
{ "release": "ArrowRight" },
{ "expect": { "state.player.x": { "gt": 200 } } },
{ "capture": "moved" }
]
}The examples include a tilemap platformer, mossfell, a top-down adventure, squish, a match-3, and Overbuffed, a swarm survival game. They're all playable right in the browser, each with its source and the docs behind it.
Agents are welcome and never required. With the debuff MCP server, an agent like Claude Code can play the game you have open, read its state and explained errors, tune params and verify its changes with scenarios. Every action it takes shows in your dev panel, where you can undo it.
New projects ship an AGENTS.md with the commands and rules, so agents start with the right context. Creative calls stay with you: the tools are built for agents to propose and people to decide.
Built on the shoulders of Vite, Vitest, happy-dom, TypeScript, Tiled, LDtk and more open-source work. Thank you.