frogoe 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/frogoe.mjs +11 -0
- package/dist/cli.js +3124 -0
- package/dist/contract/contract.js +236 -0
- package/dist/registry/blocks/coin-counter/coin-counter.html +101 -0
- package/dist/registry/blocks/coin-counter/registry-item.json +27 -0
- package/dist/registry/blocks/combo-counter/combo-counter.html +106 -0
- package/dist/registry/blocks/combo-counter/registry-item.json +27 -0
- package/dist/registry/blocks/fuel-gauge/fuel-gauge.html +130 -0
- package/dist/registry/blocks/fuel-gauge/registry-item.json +29 -0
- package/dist/registry/blocks/game-over-card/game-over-card.html +185 -0
- package/dist/registry/blocks/game-over-card/registry-item.json +30 -0
- package/dist/registry/blocks/hearts-row/hearts-row.html +92 -0
- package/dist/registry/blocks/hearts-row/registry-item.json +27 -0
- package/dist/registry/blocks/mini-board/mini-board.html +125 -0
- package/dist/registry/blocks/mini-board/registry-item.json +28 -0
- package/dist/registry/blocks/objective-chip/objective-chip.html +101 -0
- package/dist/registry/blocks/objective-chip/registry-item.json +29 -0
- package/dist/registry/blocks/ready-gate/ready-gate.html +124 -0
- package/dist/registry/blocks/ready-gate/registry-item.json +28 -0
- package/dist/registry/blocks/ready-hint/ready-hint.html +104 -0
- package/dist/registry/blocks/ready-hint/registry-item.json +29 -0
- package/dist/registry/blocks/score-card/registry-item.json +27 -0
- package/dist/registry/blocks/score-card/score-card.html +92 -0
- package/dist/registry/blocks/timer-ring/registry-item.json +28 -0
- package/dist/registry/blocks/timer-ring/timer-ring.html +123 -0
- package/dist/registry/registry.json +51 -0
- package/dist/registry/schema/registry-item.schema.json +36 -0
- package/dist/registry/schema/registry.schema.json +22 -0
- package/dist/runtimeVersion.js +10 -0
- package/dist/templates/_shared/AGENTS.md +105 -0
- package/dist/templates/_shared/CLAUDE.md +105 -0
- package/package.json +42 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frogoe game
|
|
2
|
+
|
|
3
|
+
## Skills — USE THESE FIRST
|
|
4
|
+
|
|
5
|
+
**Always read the relevant skill before writing or modifying game code.** Skills encode the frogoe contract and creative direction that generic docs don't cover. Skipping them produces broken games.
|
|
6
|
+
|
|
7
|
+
**Doing anything with frogoe?** Read the `frogoe` skill — it confirms the BRIEF (verb, mood, palette) up front and routes every request. The domain skills it routes to:
|
|
8
|
+
|
|
9
|
+
- `frogoe-core` — the technical contract: folder form, `defineGame` closure, four nouns, HUD bindings, external libraries. Read before writing any game code.
|
|
10
|
+
- `frogoe-creative` — house style: three dials (VARIANCE/MOTION/DENSITY), lazy defaults, typography, palettes, game feel. Read when choosing how a game looks.
|
|
11
|
+
- `frogoe-cli` — CLI dev loop: init, add, run, check, bundle. Finding codes table for self-healing.
|
|
12
|
+
- `frogoe-registry` — HUD block catalog: find, evaluate, install, author new blocks.
|
|
13
|
+
|
|
14
|
+
Skills live at `.agents/skills/` (install via `npx skills add frogoe/engine`). Missing or stale? Re-run the install command and restart the agent session.
|
|
15
|
+
|
|
16
|
+
## The contract
|
|
17
|
+
|
|
18
|
+
A game is **one closure**. The platform gives four nouns — everything else is yours:
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { defineGame } from "frogoe";
|
|
22
|
+
|
|
23
|
+
defineGame(({ stage, input, loop, finish }) => {
|
|
24
|
+
let y = stage.height / 2;
|
|
25
|
+
let vy = 0;
|
|
26
|
+
|
|
27
|
+
input.on("down", () => {
|
|
28
|
+
vy = -300;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
loop.update = (dt) => {
|
|
32
|
+
vy += 900 * dt;
|
|
33
|
+
y += vy * dt;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
loop.render = (ctx) => {
|
|
37
|
+
ctx.fillStyle = "#8fe9ff";
|
|
38
|
+
ctx.fillRect(stage.play.center - 12, y, 24, 24);
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| Noun | What it gives | Guarantees |
|
|
44
|
+
| -------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
45
|
+
| `stage` | `width/height`, `safe` (notch insets), `play` (capped column), `ctx` | DPR-capped canvas, notch-proof, identical challenge on every screen width |
|
|
46
|
+
| `input` | `on("down"\|"drag"\|"up")`, `pointer {x,y,dx,dy,down}` | Unified touch+mouse, full cancel path, dx/dy anchor-relative |
|
|
47
|
+
| `loop` | you fill `loop.update(dt)` + `loop.render(ctx)` | Fixed 60 Hz, dt clamped, pauses when hidden |
|
|
48
|
+
| `finish` | report the run's score | fires once, flips `__frogoe.state` to `over` |
|
|
49
|
+
|
|
50
|
+
The platform draws NOTHING. Everything visible is your code + HUD blocks from the registry.
|
|
51
|
+
|
|
52
|
+
## Commands
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
frogoe run # serve with live reload + phone QR (safe-area only exists on real devices)
|
|
56
|
+
frogoe run --tunnel # + public URL — phone works on any network (cloudflared, auto-downloaded once)
|
|
57
|
+
frogoe check # static contract lint (stable finding codes; --json for CI)
|
|
58
|
+
frogoe check --live # + headless Chrome: FPS, playability, HUD outline, screenshots
|
|
59
|
+
frogoe bundle # one self-contained HTML (externals dissolved, zero runtime requests)
|
|
60
|
+
frogoe add <block> # copy a HUD block into blocks/ (score, hearts, fuel, game-over, etc.)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> **Agents must run `frogoe check` after ANY code change** and fix all errors before
|
|
64
|
+
> presenting the result. Warnings should be reviewed before bundling. Use `--json` for
|
|
65
|
+
> machine-readable findings that can be fixed programmatically.
|
|
66
|
+
|
|
67
|
+
## Project structure
|
|
68
|
+
|
|
69
|
+
- `index.html` — entry shell: `<canvas id="c">` + import map + `.hud` layer (HUD blocks land here)
|
|
70
|
+
- `game.js` — the whole simulation: `defineGame(({stage, input, loop, finish}) => {...})`
|
|
71
|
+
- `BRIEF.md` — the game's identity: verb, mood, palette (validated by `frogoe check`)
|
|
72
|
+
- `frogoe.json` — contract version pin
|
|
73
|
+
- `.frogoe/` — tool-owned, gitignored (the contract runtime — never edit)
|
|
74
|
+
- `blocks/` — HUD blocks copied from the registry (themed via `.hud` CSS custom properties)
|
|
75
|
+
- `dist/` — `frogoe bundle` output (single self-contained HTML)
|
|
76
|
+
|
|
77
|
+
## Check — ALWAYS RUN AFTER CHANGES
|
|
78
|
+
|
|
79
|
+
After creating or editing any file, **always** run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
frogoe check # static: BRIEF validation, folder structure, input patterns
|
|
83
|
+
frogoe check --live # browser: runtime errors, canvas painted, FPS, playability
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Fix all errors before presenting the result. Common findings:
|
|
87
|
+
|
|
88
|
+
| Code | Meaning | Fix |
|
|
89
|
+
| ------------------------ | ------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
90
|
+
| `brief/todo` | BRIEF.md still has TODO markers | Fill in verb, mood, palette |
|
|
91
|
+
| `input/incremental-drag` | `x += p.dx` (wall-rocket bug) | Use `x = grabX + p.dx` or track lastX |
|
|
92
|
+
| `folder/touch-select` | Phone long-press summons text selection (iOS + Android) | Add `-webkit-user-select: none; user-select: none; -webkit-touch-callout: none` on html/body |
|
|
93
|
+
| `audio/suspended-only` | Resume gated on `=== "suspended"` (iOS silent bug) | Resume when `state !== "running"` — see frogoe-core `references/audio.md` |
|
|
94
|
+
| `live/hud-outline` | HUD text missing text-shadow/stroke | Add `text-shadow: 0 2px 0 <dark>` |
|
|
95
|
+
| `live/fps` | Below 30fps | Cache gradients, reduce shadowBlur, cut particles |
|
|
96
|
+
| `live/not-playable` | Scripted taps changed nothing | Wire `input.on("down")` to actual game logic |
|
|
97
|
+
|
|
98
|
+
## Key rules
|
|
99
|
+
|
|
100
|
+
1. **pointer.dx is anchor-relative** (measured since touch-down, not per-event). Steer with `x = grabX + p.dx` or track your own `lastX`. NEVER `x += p.dx` inside a drag handler — every pointermove re-applies the cumulative offset and the actor rockets into a wall.
|
|
101
|
+
2. **All HUD text lives in the DOM layer** (`.hud` div) with a `text-shadow` or `-webkit-text-stroke`. The outline IS the readability mechanism — game backgrounds change every frame, so pixel-contrast against them is meaningless.
|
|
102
|
+
3. **Gameplay uses `stage.play`** (capped centered column: `left/right/center/width`), never raw `window.innerWidth` — identical challenge on every screen width.
|
|
103
|
+
4. **Fixed furniture respects `stage.safe`** — notches cover screen edges. Score at fixed y=34 sits under the Dynamic Island on modern phones.
|
|
104
|
+
5. **One page, zero runtime requests** after bundling. Author-time CDN dependencies are fine — `frogoe bundle` dissolves them (allowlist + pin + hash + inline).
|
|
105
|
+
6. **`finish(score)`** ends the run. The results card is a HUD block (`game-over-card`), never something the platform draws.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frogoe game
|
|
2
|
+
|
|
3
|
+
## Skills — USE THESE FIRST
|
|
4
|
+
|
|
5
|
+
**Always read the relevant skill before writing or modifying game code.** Skills encode the frogoe contract and creative direction that generic docs don't cover. Skipping them produces broken games.
|
|
6
|
+
|
|
7
|
+
**Doing anything with frogoe?** Start at the `frogoe` skill — it confirms the BRIEF (verb, mood, palette) up front and routes every request. The domain skills it routes to:
|
|
8
|
+
|
|
9
|
+
- `frogoe-core` — the technical contract: folder form, `defineGame` closure, four nouns, HUD bindings, external libraries. Read before writing any game code.
|
|
10
|
+
- `frogoe-creative` — house style: three dials (VARIANCE/MOTION/DENSITY), lazy defaults, typography, palettes, game feel. Read when choosing how a game looks.
|
|
11
|
+
- `frogoe-cli` — CLI dev loop: init, add, run, check, bundle. Finding codes table for self-healing.
|
|
12
|
+
- `frogoe-registry` — HUD block catalog: find, evaluate, install, author new blocks.
|
|
13
|
+
|
|
14
|
+
Skills live at `.agents/skills/` (install via `npx skills add frogoe/engine`). Missing or stale? Re-run the install command and restart the agent session.
|
|
15
|
+
|
|
16
|
+
## The contract
|
|
17
|
+
|
|
18
|
+
A game is **one closure**. The platform gives four nouns — everything else is yours:
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { defineGame } from "frogoe";
|
|
22
|
+
|
|
23
|
+
defineGame(({ stage, input, loop, finish }) => {
|
|
24
|
+
let y = stage.height / 2;
|
|
25
|
+
let vy = 0;
|
|
26
|
+
|
|
27
|
+
input.on("down", () => {
|
|
28
|
+
vy = -300;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
loop.update = (dt) => {
|
|
32
|
+
vy += 900 * dt;
|
|
33
|
+
y += vy * dt;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
loop.render = (ctx) => {
|
|
37
|
+
ctx.fillStyle = "#8fe9ff";
|
|
38
|
+
ctx.fillRect(stage.play.center - 12, y, 24, 24);
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| Noun | What it gives | Guarantees |
|
|
44
|
+
| -------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
45
|
+
| `stage` | `width/height`, `safe` (notch insets), `play` (capped column), `ctx` | DPR-capped canvas, notch-proof, identical challenge on every screen width |
|
|
46
|
+
| `input` | `on("down"\|"drag"\|"up")`, `pointer {x,y,dx,dy,down}` | Unified touch+mouse, full cancel path, dx/dy anchor-relative |
|
|
47
|
+
| `loop` | you fill `loop.update(dt)` + `loop.render(ctx)` | Fixed 60 Hz, dt clamped, pauses when hidden |
|
|
48
|
+
| `finish` | report the run's score | fires once, flips `__frogoe.state` to `over` |
|
|
49
|
+
|
|
50
|
+
The platform draws NOTHING. Everything visible is your code + HUD blocks from the registry.
|
|
51
|
+
|
|
52
|
+
## Commands
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
frogoe run # serve with live reload + phone QR (safe-area only exists on real devices)
|
|
56
|
+
frogoe run --tunnel # + public URL — phone works on any network (cloudflared, auto-downloaded once)
|
|
57
|
+
frogoe check # static contract lint (stable finding codes; --json for CI)
|
|
58
|
+
frogoe check --live # + headless Chrome: FPS, playability, HUD outline, screenshots
|
|
59
|
+
frogoe bundle # one self-contained HTML (externals dissolved, zero runtime requests)
|
|
60
|
+
frogoe add <block> # copy a HUD block into blocks/ (score, hearts, fuel, game-over, etc.)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> **Agents must run `frogoe check` after ANY code change** and fix all errors before
|
|
64
|
+
> presenting the result. Warnings should be reviewed before bundling. Use `--json` for
|
|
65
|
+
> machine-readable findings that can be fixed programmatically.
|
|
66
|
+
|
|
67
|
+
## Project structure
|
|
68
|
+
|
|
69
|
+
- `index.html` — entry shell: `<canvas id="c">` + import map + `.hud` layer (HUD blocks land here)
|
|
70
|
+
- `game.js` — the whole simulation: `defineGame(({stage, input, loop, finish}) => {...})`
|
|
71
|
+
- `BRIEF.md` — the game's identity: verb, mood, palette (validated by `frogoe check`)
|
|
72
|
+
- `frogoe.json` — contract version pin
|
|
73
|
+
- `.frogoe/` — tool-owned, gitignored (the contract runtime — never edit)
|
|
74
|
+
- `blocks/` — HUD blocks copied from the registry (themed via `.hud` CSS custom properties)
|
|
75
|
+
- `dist/` — `frogoe bundle` output (single self-contained HTML)
|
|
76
|
+
|
|
77
|
+
## Check — ALWAYS RUN AFTER CHANGES
|
|
78
|
+
|
|
79
|
+
After creating or editing any file, **always** run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
frogoe check # static: BRIEF validation, folder structure, input patterns
|
|
83
|
+
frogoe check --live # browser: runtime errors, canvas painted, FPS, playability
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Fix all errors before presenting the result. Common findings:
|
|
87
|
+
|
|
88
|
+
| Code | Meaning | Fix |
|
|
89
|
+
| ------------------------ | ------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
90
|
+
| `brief/todo` | BRIEF.md still has TODO markers | Fill in verb, mood, palette |
|
|
91
|
+
| `input/incremental-drag` | `x += p.dx` (wall-rocket bug) | Use `x = grabX + p.dx` or track lastX |
|
|
92
|
+
| `folder/touch-select` | Phone long-press summons text selection (iOS + Android) | Add `-webkit-user-select: none; user-select: none; -webkit-touch-callout: none` on html/body |
|
|
93
|
+
| `audio/suspended-only` | Resume gated on `=== "suspended"` (iOS silent bug) | Resume when `state !== "running"` — see frogoe-core `references/audio.md` |
|
|
94
|
+
| `live/hud-outline` | HUD text missing text-shadow/stroke | Add `text-shadow: 0 2px 0 <dark>` |
|
|
95
|
+
| `live/fps` | Below 30fps | Cache gradients, reduce shadowBlur, cut particles |
|
|
96
|
+
| `live/not-playable` | Scripted taps changed nothing | Wire `input.on("down")` to actual game logic |
|
|
97
|
+
|
|
98
|
+
## Key rules
|
|
99
|
+
|
|
100
|
+
1. **pointer.dx is anchor-relative** (measured since touch-down, not per-event). Steer with `x = grabX + p.dx` or track your own `lastX`. NEVER `x += p.dx` inside a drag handler — every pointermove re-applies the cumulative offset and the actor rockets into a wall.
|
|
101
|
+
2. **All HUD text lives in the DOM layer** (`.hud` div) with a `text-shadow` or `-webkit-text-stroke`. The outline IS the readability mechanism — game backgrounds change every frame, so pixel-contrast against them is meaningless.
|
|
102
|
+
3. **Gameplay uses `stage.play`** (capped centered column: `left/right/center/width`), never raw `window.innerWidth` — identical challenge on every screen width.
|
|
103
|
+
4. **Fixed furniture respects `stage.safe`** — notches cover screen edges. Score at fixed y=34 sits under the Dynamic Island on modern phones.
|
|
104
|
+
5. **One page, zero runtime requests** after bundling. Author-time CDN dependencies are fine — `frogoe bundle` dissolves them (allowlist + pin + hash + inline).
|
|
105
|
+
6. **`finish(score)`** ends the run. The results card is a HUD block (`game-over-card`), never something the platform draws.
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "frogoe",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "froge CLI — the agent's hands: init, add, run, check, bundle",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"bin": {
|
|
7
|
+
"frogoe": "bin/frogoe.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/cli.js",
|
|
17
|
+
"types": "./dist/cli.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"test": "bun test",
|
|
22
|
+
"check-types": "tsc --noEmit",
|
|
23
|
+
"build": "tsup && bun scripts/build-copy.mjs",
|
|
24
|
+
"dev": "bun src/cli.ts"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@hono/node-server": "^2.1.1",
|
|
28
|
+
"@puppeteer/browsers": "^3.2.1",
|
|
29
|
+
"citty": "^0.2.2",
|
|
30
|
+
"esbuild": "^0.28.2",
|
|
31
|
+
"hono": "^4.13.5",
|
|
32
|
+
"puppeteer-core": "^25.9.0",
|
|
33
|
+
"qrcode-terminal": "^0.12.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@frogoe/lint": "workspace:*",
|
|
37
|
+
"tsup": "^8.5.1"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22"
|
|
41
|
+
}
|
|
42
|
+
}
|