frogoe
Write a closure. Ship a game. Built for agents.
Quick Start | Skills | What You Can Build | How It Works | Catalog
frogoe is an open-source game framework with one standing rule: the platform has zero taste. A game is one closure over four nouns — stage, input, loop, finish. Everything visible comes from the game and from a registry of themeable blocks. Quality is taught by skills and measured on the output, never imposed by an engine.
Install the frogoe skills, then describe the game you want:
npx skills add frogoe/engineTry a prompt like:
Using
/frogoe, make a game where you hold to charge a jump and hop between platforms as lava rises.
The skills teach agents the frogoe production loop: confirm the BRIEF (verb, mood, palette), scaffold with frogoe init, write the game closure, install HUD blocks, run frogoe check, and ship a single-file artifact. They work with Claude Code, Codex, Cursor, OpenCode, and other coding agents that support skills.
npx frogoe init my-game # or: npm i -g frogoe
cd my-game
frogoe run # live reload + phone QR; --tunnel works on any network
frogoe report # last playtest: fps dips, errors, lock-screens — with timestamps
frogoe lint # fast static contract lint (stable finding codes; --json)
frogoe check # full gate: + headless Chrome — FPS, playability, audio recovery, phone-class throttle
frogoe vision # eyes for draw code: objects, gameplay frames, identity art as ASCII maps (--pretty: color)
frogoe bundle # one self-contained HTML (zero runtime requests) — only after check
frogoe export desktop|ios|android # buildable native app project in export/ (Tauri shell)
frogoe run desktop|ios|android # the dev loop inside the native shell — same hot reload
frogoe play [dir] # agent eyes + hands: JSONL frames out, input in — step mode freezes the world
frogoe embed # the card: poster loading state + sandboxed game + dist/manifest.json
frogoe skills check # skill freshness (hash = per-bundle SHA16)Requirements: bun or Node.js 22+
git clone https://github.com/frogoe/engine && cd engine
bun install
bun run verify # full gauntlet: format + lint + types + tests + knip + registry + game lint + skill freshness + the npm user journey (packaged CLI under node)
bun run verify:art # art pipeline on both examples: check → bundle (rendered gates) → embed → card e2ePlay the reference games and every block demo:
cd examples/flappy && bunx serve .
cd ../../registry/blocks/score-card && bunx serve . # each block has demo.htmlfrogoe ships 5 skills agents load on demand. Read /frogoe first — it's the router and capability map; it confirms the BRIEF up front and routes to the domain skills below.
| Skill | Use when |
|---|---|
/frogoe |
Read first for any request to make / create / edit / ship a game. Confirms the BRIEF (verb, mood, palette), routes to domain skills. |
/frogoe-core |
The technical contract — folder form, defineGame closure, four nouns, HUD bindings, external libraries and the bundler that dissolves them. |
/frogoe-creative |
House style — three dials (VARIANCE / MOTION / DENSITY), lazy defaults to question, typography, named palettes, game feel, identity art (authored assets/poster.js + assets/icon.js). |
/frogoe-cli |
CLI dev loop — init, add, run, vision (ASCII eyes), check (static + live sandbox), bundle, embed (the card + manifest), report. Finding codes split into finding-codes.md / live-sandbox.md / bundle.md / embed.md / vision.md for self-healing. |
/frogoe-registry |
Install and wire registry blocks via frogoe add. Authoring a new block to contribute upstream. |
- Arcade games: Flappy-style tappers, runners, dodgers, climbers
- Puzzle games with objectives, moves counters, timers
- Casual games with lives, fuel, combo streaks, leaderboards
- Hold-to-charge, drag-to-steer, aim-and-release mechanics
- Word & typing games — keyboard flows through the contract (
input.on("key"),input.keys), and thehud-keyboardblock brings the same events to touch screens - Games with CDN dependencies (three.js, GSAP, web fonts) bundled into one file
Define a game as one closure. The platform gives four nouns — everything else is yours:
import { defineGame } from "frogoe";
defineGame(({ stage, input, loop, finish }) => {
let y = stage.height / 2;
let vy = 0;
input.on("down", () => {
vy = -300;
});
loop.update = (dt) => {
vy += 900 * dt;
y += vy * dt;
};
loop.render = (ctx) => {
ctx.fillStyle = "#8fe9ff";
ctx.fillRect(stage.play.center - 12, y, 24, 24);
};
});| Noun | Gives | Guarantees |
|---|---|---|
stage |
width/height, safe (notch insets), play (capped column), ctx |
DPR-capped canvas, notch-proof, identical challenge on every width |
input |
on("down"|"drag"|"up"), pointer {x,y,dx,dy,down} |
Unified touch+mouse, full cancel path, dx/dy anchor-relative |
loop |
you fill loop.update(dt) + loop.render(ctx) |
Fixed 60 Hz, dt clamped, pauses when hidden |
finish |
report the run's score | Fires once, flips __frogoe.state to over |
The platform draws nothing. Everything visible is your code plus HUD blocks from the registry. The DOM+CSS layer is where beauty lives (agents write CSS well; the browser renders it); the canvas layer is where the simulation lives (60 Hz, fixed step, input unified).
Install ready-to-use HUD blocks:
frogoe add score-card # big number with bump animation
frogoe add hearts-row # lives with pop on damage
frogoe add fuel-gauge # resource bar with danger state
frogoe add game-over-card # end-of-run results + retry button
frogoe add ready-hint # verb affordance (replaces start menus)
frogoe add ready-gate # tap-to-start overlay — the audio-unlock tap
frogoe add timer-ring # circular countdown
frogoe add hud-keyboard # on-screen keys for word games — presses are real
# KeyboardEvents, the contract hears them nativelyEach block is themeable via --block-* custom properties from your BRIEF palette, ships a working demo.html, and is validated against the registry schema. frogoe add auto-injects styles + markup into index.html (idempotent — re-add replaces).
The platform (packages/contract) has zero visual opinion. If a change makes it draw, style, or sound like anything, that change is wrong — move it to the registry (a themeable block) or to skills (knowledge). This rule is load-bearing.
- Agent-native: agents already write HTML and JS; the CLI is non-interactive by default; skills teach the patterns generic docs miss.
- Zero taste: the contract draws nothing, sounds nothing, styles nothing. Your game owns the look; the registry owns the building blocks.
- Measured quality:
frogoe checkruns your game in headless Chrome through the full lifecycle — boot → play → death → retry, twice — measuring FPS, playability, audio recovery after an injected interruption, and a 4x phone-class CPU-throttle replay. Screenshots are the evidence.frogoe lintis the fast static half for iteration. - One artifact:
frogoe bundledissolves CDN dependencies into a single self-contained HTML — zero runtime requests, no link rot, verified == played. - Identity art is authored, not captured: every game ships
assets/poster.js+assets/icon.js— canvas scenes drawn by the game's own sprites (1:1 with gameplay by construction). The bundle renders them at store sizes (1080×1920 / 1024) behind rendered gates (title readability, safe-zone collisions, full-bleed icon), andfrogoe embedcomposes the card: poster loading state → game, plusdist/manifest.json(palette, fonts, sha256 integrity). - Open source: Apache 2.0, no per-game fees.
| Package | Description |
|---|---|
frogoe (npm) |
The CLI: init, add, run (+ --tunnel), lint (fast static), check (full gate: static + live sandbox), report, bundle, skills |
@frogoe/contract |
The whole platform (zero taste, contract 0.2.0): defineGame, four nouns, __frogoe host handle — workspace-internal, materialized into every game |
@frogoe/lint |
Pure static contract checks, zero browser deps — bundled into the CLI |
skills/ |
5 AI agent skills (router, core, creative, cli, registry) — mirrored to .claude/skills + .agents/skills |
registry/blocks/ |
12 themeable HUD blocks with demos — the catalog grows |
examples/flappy/ |
Reference game: Flappy Chick (tap runner) at Flappy Bird quality |
examples/sawstorm/ |
Reference game: Sawstorm — arena survival with touch pad, sudden death, safe persistence |
bun install # Install dependencies (NOT pnpm)
bun run verify # Full gauntlet: format + lint + types + tests + knip + registry + game lint + skill freshness
bun testUses oxlint and oxfmt (not eslint, not prettier). Commits are conventional (feat:, fix:, docs:, chore:) via lefthook + commitlint — and they are the entire release discipline: the release-please bot turns them into a running release PR, and merging it publishes to npm automatically (provenance-signed, no tokens anywhere). Prerelease channels ship by pushing hyphenated tags (v0.2.3-beta.1). See CONTRIBUTING.md.
The release pipeline's guardrails — immutable release checkouts, packed-manifest verification, release-PR-only stable channels — and the held-failure severity model in the live sandbox were learned by reading HyperFrames' workflows. Their example set the bar; go star it.