mirror of
https://github.com/PlayableIntelligence/game-creator.git
synced 2026-09-19 07:34:10 +08:00
feat: integrate Play.fun monetization into game pipeline
Add Play.fun (OpenGameProtocol) as a git submodule and wire it into the make-game pipeline as Step 7 (Monetize). Games are registered on Play.fun, the browser SDK is added for points/leaderboards/wallet, and the play.fun URL becomes the share link for Moltbook. - Replace playdotfun symlink with git submodule (OpusGameLabs/skills) - Add /monetize-game command for standalone monetization - Update make-game pipeline: deploy → monetize → pipeline complete - Update game-creator agent with monetization step - Update site pipeline (7 steps), manifests (v1.2.0), README, CLAUDE.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,15 +4,15 @@
|
||||
"name": "OpusGameLabs"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "The game studio for the agent internet. Build browser games with Three.js (3D) and Phaser (2D). Works with OpenClaw and Claude Code. Share on Moltbook.",
|
||||
"version": "1.1.0"
|
||||
"description": "The game studio for the agent internet. Build, monetize, and ship browser games. Phaser 2D, Three.js 3D, Play.fun monetization. Works with OpenClaw and Claude Code.",
|
||||
"version": "1.2.0"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "game-creator",
|
||||
"source": ".",
|
||||
"description": "The game studio for the agent internet. Build 2D and 3D browser games with one command, then share them on Moltbook.",
|
||||
"version": "1.1.0",
|
||||
"description": "The game studio for the agent internet. Build, monetize, and ship 2D and 3D browser games with one command. Play.fun + Moltbook.",
|
||||
"version": "1.2.0",
|
||||
"author": {
|
||||
"name": "OpusGameLabs"
|
||||
},
|
||||
@@ -31,6 +31,8 @@
|
||||
"moltbook",
|
||||
"agent-internet",
|
||||
"playfun",
|
||||
"play-fun",
|
||||
"opengameprotocol",
|
||||
"monetization",
|
||||
"game-design",
|
||||
"game-audio",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "game-creator",
|
||||
"description": "The game studio for the agent internet. Build 2D (Phaser) and 3D (Three.js) browser games with one command. Works with OpenClaw and Claude Code.",
|
||||
"version": "1.1.0",
|
||||
"description": "The game studio for the agent internet. Build, monetize, and ship browser games with one command. Phaser 2D, Three.js 3D, Play.fun monetization. Works with OpenClaw and Claude Code.",
|
||||
"version": "1.2.0",
|
||||
"author": {
|
||||
"name": "OpusGameLabs"
|
||||
},
|
||||
"keywords": ["games", "threejs", "phaser", "gamedev", "3d", "2d", "openclaw", "moltbook", "agent-internet", "playfun", "monetization"],
|
||||
"keywords": ["games", "threejs", "phaser", "gamedev", "3d", "2d", "openclaw", "moltbook", "agent-internet", "playfun", "monetization", "opengameprotocol", "play-fun"],
|
||||
"openclaw": {
|
||||
"compatible": true,
|
||||
"install": "npx clawhub@latest install game-creator",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "submodules/playdotfun"]
|
||||
path = submodules/playdotfun
|
||||
url = https://github.com/OpusGameLabs/skills.git
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is **game-creator**, the game studio for the agent internet. It provides skills, commands, and agents for scaffolding, designing, scoring, testing, and shipping 2D (Phaser 3) and 3D (Three.js) browser games. Works with **OpenClaw** (via ClawHub or manual install) and **Claude Code** (via plugin marketplace). Games can be shared on [Moltbook](https://www.moltbook.com/).
|
||||
This is **game-creator**, the game studio for the agent internet. It provides skills, commands, and agents for scaffolding, designing, testing, monetizing, and shipping 2D (Phaser 3) and 3D (Three.js) browser games. Monetize with [Play.fun](https://play.fun) (OpenGameProtocol). Works with **OpenClaw** (via ClawHub or manual install) and **Claude Code** (via plugin marketplace). Share your play.fun URL on [Moltbook](https://www.moltbook.com/).
|
||||
|
||||
## Repository Structure
|
||||
|
||||
@@ -19,18 +19,22 @@ skills/
|
||||
game-qa/SKILL.md # Playwright testing (gameplay, visual, perf)
|
||||
game-architecture/SKILL.md # Reference architecture patterns
|
||||
game-deploy/SKILL.md # Deployment (GitHub Pages, Vercel, etc.)
|
||||
playdotfun/SKILL.md # Play.fun monetization (git submodule → submodules/playdotfun)
|
||||
templates/
|
||||
phaser-2d/ # Runnable 2D starter project (Phaser 3)
|
||||
threejs-3d/ # Runnable 3D starter project (Three.js)
|
||||
commands/
|
||||
make-game.md # Full pipeline: scaffold → assets → design → audio → QA → review → deploy
|
||||
make-game.md # Full pipeline: scaffold → assets → design → audio → QA → review → deploy → monetize
|
||||
improve-game.md # Holistic audit + implement highest-impact improvements
|
||||
design-game.md # Visual design audit + improvements
|
||||
add-feature.md # Add feature following patterns
|
||||
add-assets.md # Replace shapes with pixel art sprites
|
||||
add-audio.md # Add Strudel.cc audio
|
||||
qa-game.md # Add Playwright tests
|
||||
monetize-game.md # Play.fun monetization (register, SDK, redeploy)
|
||||
review-game.md # Architecture review
|
||||
submodules/
|
||||
playdotfun/ # Git submodule: github.com/OpusGameLabs/skills
|
||||
agents/
|
||||
game-reviewer.md # Code review agent
|
||||
game-creator.md # Autonomous game creation pipeline
|
||||
@@ -132,4 +136,16 @@ SFX fires on `BIRD_FLAP`, `SCORE_CHANGED`, `BIRD_DIED` via AudioBridge listeners
|
||||
- Strudel.cc is AGPL-3.0. Games using `@strudel/web` must be open source.
|
||||
- Playwright screenshot tests use high pixel tolerance (3000 maxDiffPixels) because parallax clouds scroll between captures.
|
||||
- Headless Chromium reports low FPS (~7-9). FPS threshold in tests is set to 5. Use Playwright MCP for accurate FPS measurement.
|
||||
- The `playdotfun` skill directory is a symlink (`../../skills/skills`). This may need updating if the path changes.
|
||||
- The `playdotfun` skill is a git submodule at `submodules/playdotfun` (repo: `github.com/OpusGameLabs/skills`). The symlink `skills/playdotfun → ../submodules/playdotfun/skills` makes SKILL.md resolve correctly. After cloning, run `git submodule update --init` to pull the submodule.
|
||||
|
||||
## Play.fun (OpenGameProtocol) Integration
|
||||
|
||||
The `/monetize-game` command (and Step 7 of `/make-game`) registers games on [Play.fun](https://play.fun) and integrates the browser SDK.
|
||||
|
||||
**Flow**: Auth → Register game → Add SDK to `index.html` + create `src/playfun.js` → Rebuild → Redeploy → Share play.fun URL on Moltbook
|
||||
|
||||
**Auth**: Uses `skills/playdotfun/scripts/playfun-auth.js` for credential management. Supports web callback (localhost:9876) and manual paste.
|
||||
|
||||
**SDK**: CDN script (`https://sdk.play.fun/latest`) + `src/playfun.js` that wires EventBus events (score changes, game over) to Play.fun points tracking. Non-blocking — if SDK fails to load, game still works.
|
||||
|
||||
**Anti-cheat**: Games are registered with `maxScorePerSession`, `maxSessionsPerDay`, and `maxCumulativePointsPerDay` based on the game's scoring system.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# game-creator
|
||||
|
||||
The game studio for the agent internet. Build, test, and ship 2D (Phaser) and 3D (Three.js) browser games with one command. Works with **OpenClaw** and **Claude Code**. Share your games on [Moltbook](https://www.moltbook.com/).
|
||||
The game studio for the agent internet. Build, monetize, and ship 2D (Phaser) and 3D (Three.js) browser games with one command. Monetize with [Play.fun](https://play.fun) (OpenGameProtocol). Works with **OpenClaw** and **Claude Code**. Share your games on [Moltbook](https://www.moltbook.com/).
|
||||
|
||||
**Owner**: [OpusGameLabs](https://github.com/OpusGameLabs)
|
||||
|
||||
@@ -29,7 +29,7 @@ cp -r game-creator/skills/* ~/.openclaw/skills/
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Build a complete 2D game (scaffold → design → audio → test → review)
|
||||
# Build a complete 2D game (scaffold → design → audio → test → review → deploy → monetize)
|
||||
/game-creator:make-game 2d my-game
|
||||
|
||||
# Or run individual steps:
|
||||
@@ -38,6 +38,9 @@ cp -r game-creator/skills/* ~/.openclaw/skills/
|
||||
# Add chiptune music and sound effects
|
||||
/game-creator:add-audio
|
||||
|
||||
# Monetize with Play.fun (OpenGameProtocol)
|
||||
/game-creator:monetize-game
|
||||
|
||||
# Add Playwright tests
|
||||
/game-creator:qa-game
|
||||
|
||||
@@ -102,17 +105,19 @@ export const COLORS = { sky: 0x4ec0ca, bird: 0xf5d742, ... };
|
||||
| `game-qa` | Playwright testing — gameplay verification, visual regression, performance |
|
||||
| `game-architecture` | Reference patterns for event-driven game architecture |
|
||||
| `game-deploy` | Deployment to GitHub Pages, Vercel, Netlify, itch.io |
|
||||
| `playdotfun` | Play.fun (OpenGameProtocol) monetization — SDK, API, auth, leaderboards |
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/game-creator:make-game [2d\|3d] [name]` | Full pipeline: scaffold, design, audio, test, review, deploy |
|
||||
| `/game-creator:make-game [2d\|3d] [name]` | Full pipeline: scaffold, design, audio, test, review, deploy, monetize |
|
||||
| `/game-creator:improve-game [focus]` | Deep audit + implement highest-impact improvements |
|
||||
| `/game-creator:design-game [path]` | Audit and improve visual polish |
|
||||
| `/game-creator:add-feature [description]` | Add a feature following architecture patterns |
|
||||
| `/game-creator:add-audio [path]` | Add Strudel.cc music and sound effects |
|
||||
| `/game-creator:qa-game [path]` | Add Playwright automated tests |
|
||||
| `/game-creator:monetize-game [path]` | Register on Play.fun, add SDK, get monetized URL |
|
||||
| `/game-creator:review-game [path]` | Review architecture, performance, code quality |
|
||||
|
||||
## Agents
|
||||
@@ -161,6 +166,7 @@ The `/make-game` command copies a runnable starter project from `templates/` ins
|
||||
| Audio | Strudel.cc (`@strudel/web`) |
|
||||
| Build | Vite |
|
||||
| Testing | Playwright + axe-core |
|
||||
| Monetization | [Play.fun](https://play.fun) (OpenGameProtocol) |
|
||||
| Language | JavaScript ES modules |
|
||||
|
||||
## Audio
|
||||
|
||||
@@ -16,6 +16,7 @@ Load these skills before starting:
|
||||
- **`game-audio`** — Procedural audio: Strudel.cc BGM + Web Audio SFX
|
||||
- **`game-qa`** — Playwright test generation
|
||||
- **`game-architecture`** — Reference architecture patterns for validation
|
||||
- **`playdotfun`** — Play.fun (OpenGameProtocol) monetization integration
|
||||
|
||||
## Input
|
||||
|
||||
@@ -95,6 +96,7 @@ Create all pipeline tasks upfront using `TaskCreate`:
|
||||
4. Add audio (BGM + SFX)
|
||||
5. Add QA tests
|
||||
6. Run architecture review
|
||||
7. Monetize with Play.fun (register game, add SDK)
|
||||
|
||||
This provides full visibility into pipeline progress.
|
||||
|
||||
@@ -345,6 +347,41 @@ Launch a `Task` subagent:
|
||||
|
||||
Mark task 6 as `completed`.
|
||||
|
||||
### Step 6: Monetize with Play.fun
|
||||
|
||||
Mark task 7 as `in_progress`.
|
||||
|
||||
Launch a `Task` subagent:
|
||||
|
||||
> You are implementing Step 6 (Monetize) of the game creation pipeline.
|
||||
>
|
||||
> **Project path**: `<project-dir>`
|
||||
> **Engine**: `<2d|3d>`
|
||||
> **Skill to load**: `playdotfun`
|
||||
>
|
||||
> Integrate the Play.fun (OpenGameProtocol) browser SDK:
|
||||
>
|
||||
> 1. Add `<script src="https://sdk.play.fun/latest"></script>` to `index.html` before `</head>`
|
||||
> 2. Read `src/core/EventBus.js` to find the score and game over event names
|
||||
> 3. Create `src/playfun.js` that:
|
||||
> - Initializes the SDK with `{ gameId: GAME_ID, ui: { usePointsWidget: true } }`
|
||||
> - Listens for score events and calls `sdk.addPoints(delta)`
|
||||
> - Calls `sdk.savePoints()` on game over, every 30 seconds, and on `beforeunload`
|
||||
> - Uses `typeof PlayFunSDK !== 'undefined' ? PlayFunSDK : OpenGameSDK` for class detection
|
||||
> - Wraps everything in a `try/catch` so SDK failures don't break the game
|
||||
> 4. Import and call `initPlayFun()` in `src/main.js` (non-blocking, `.catch()` to swallow errors)
|
||||
> 5. Use a placeholder `GAME_ID` value of `'PLAYFUN_GAME_ID'` — the orchestrator will replace it after registration
|
||||
>
|
||||
> Do NOT run builds — the orchestrator handles verification.
|
||||
|
||||
**After subagent returns**, run the Verification Protocol (build + runtime).
|
||||
|
||||
**Note**: The actual game registration on Play.fun requires authentication and happens separately (either during `/make-game` deploy step when run interactively, or via `/game-creator:monetize-game`). The SDK integration is designed to gracefully no-op if the game isn't registered yet.
|
||||
|
||||
Mark task 7 as `completed`.
|
||||
|
||||
**Gate**: Verification Protocol must pass. If it fails after 3 attempts, log failure, skip, continue.
|
||||
|
||||
## Error Handling
|
||||
|
||||
- **Build failures**: The Verification Protocol handles this — fix subagent reads compiler/bundler output, fixes code, retries. Up to 3 attempts per step.
|
||||
@@ -369,6 +406,7 @@ When the pipeline completes, produce a structured report that includes task comp
|
||||
| Audio | #4 | ⚠️ Skipped | Failed after 3 retries: [error summary] |
|
||||
| QA | #5 | ✅ Pass | 15/15 tests passing |
|
||||
| Review | #6 | ✅ Done | Score: 9.2/10 |
|
||||
| Monetize | #7 | ✅ Pass | Play.fun SDK integrated |
|
||||
|
||||
### Verification Results
|
||||
| Step | Build | Runtime | Attempts |
|
||||
@@ -378,6 +416,7 @@ When the pipeline completes, produce a structured report that includes task comp
|
||||
| Design | ✅ | ✅ | 1 |
|
||||
| Audio | ❌ | — | 3 |
|
||||
| QA | ✅ | — | 1 |
|
||||
| Monetize | ✅ | ✅ | 1 |
|
||||
|
||||
### Test Results
|
||||
- Total: 15
|
||||
|
||||
+149
-6
@@ -16,7 +16,8 @@ Build a complete browser game from scratch, step by step. This command walks you
|
||||
5. Automated tests that catch bugs when you make changes
|
||||
6. An architecture review with a quality score and improvement tips
|
||||
7. Live deployment to GitHub Pages with a public URL
|
||||
8. Future changes auto-deploy on `git push`
|
||||
8. Monetization via Play.fun — points tracking, leaderboards, wallet connect, and a play.fun URL to share on Moltbook
|
||||
9. Future changes auto-deploy on `git push`
|
||||
|
||||
## Orchestration Model
|
||||
|
||||
@@ -116,6 +117,7 @@ Create all pipeline tasks upfront using `TaskCreate`:
|
||||
5. Add QA tests
|
||||
6. Run architecture review
|
||||
7. Deploy to GitHub Pages
|
||||
8. Monetize with Play.fun (register on OpenGameProtocol, add SDK, redeploy)
|
||||
|
||||
This gives the user full visibility into pipeline progress at all times.
|
||||
|
||||
@@ -533,12 +535,150 @@ Add a `deploy` script to `package.json` so future deploys are one command:
|
||||
> ```
|
||||
> Or if you're working with me, I'll commit your changes and run deploy for you.
|
||||
>
|
||||
> **Share your game** — send that URL to anyone and they can play instantly in their browser.
|
||||
>
|
||||
> Want to monetize your game with Play.fun? I can help you set that up with the `/game-creator:playdotfun` skill.
|
||||
> **Next up: monetization.** I'll register your game on Play.fun (OpenGameProtocol), add the points SDK, and redeploy. Players earn rewards, you get a play.fun URL to share on Moltbook. Ready?
|
||||
|
||||
Mark task 7 as `completed`.
|
||||
|
||||
**Wait for user confirmation before proceeding.**
|
||||
|
||||
### Step 7: Monetize with Play.fun
|
||||
|
||||
Mark task 8 as `in_progress`.
|
||||
|
||||
**This step stays in the main thread** because it requires interactive authentication.
|
||||
|
||||
#### 7a. Authenticate with Play.fun
|
||||
|
||||
Check if the user already has Play.fun credentials. The auth script is bundled with the plugin:
|
||||
|
||||
```bash
|
||||
node skills/playdotfun/scripts/playfun-auth.js status
|
||||
```
|
||||
|
||||
**If credentials exist**, skip to 7b.
|
||||
|
||||
**If no credentials**, start the auth callback server:
|
||||
|
||||
```bash
|
||||
node skills/playdotfun/scripts/playfun-auth.js callback &
|
||||
```
|
||||
|
||||
Tell the user:
|
||||
|
||||
> To register your game on Play.fun, you need to log in once.
|
||||
> Open this URL in your browser:
|
||||
> **https://app.play.fun/skills-auth?callback=http://localhost:9876/callback**
|
||||
>
|
||||
> Log in with your Play.fun account. Credentials are saved locally.
|
||||
> Tell me when you're done.
|
||||
|
||||
**Wait for user confirmation.** Then verify with `playfun-auth.js status`.
|
||||
|
||||
If callback fails, offer manual method as fallback.
|
||||
|
||||
#### 7b. Register the game on Play.fun
|
||||
|
||||
Determine the deployed game URL from Step 6 (`https://<username>.github.io/<game-name>/`).
|
||||
|
||||
Read `package.json` for the game name and description. Read `src/core/Constants.js` to determine reasonable anti-cheat limits based on the scoring system.
|
||||
|
||||
Use the Play.fun API to register the game. Load the `playdotfun` skill for API reference. Register via `POST https://api.opengameprotocol.com/games`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "<game-name>",
|
||||
"description": "<game-description>",
|
||||
"gameUrl": "<deployed-url>",
|
||||
"platform": "web",
|
||||
"isHTMLGame": true,
|
||||
"iframable": true,
|
||||
"maxScorePerSession": <based on game scoring>,
|
||||
"maxSessionsPerDay": 50,
|
||||
"maxCumulativePointsPerDay": <reasonable daily cap>
|
||||
}
|
||||
```
|
||||
|
||||
**Anti-cheat guidelines:**
|
||||
- Casual clicker/idle: `maxScorePerSession: 100-500`
|
||||
- Skill-based arcade (flappy bird, runners): `maxScorePerSession: 500-2000`
|
||||
- Competitive/complex: `maxScorePerSession: 1000-5000`
|
||||
|
||||
Save the returned **game UUID**.
|
||||
|
||||
#### 7c. Add the Play.fun Browser SDK
|
||||
|
||||
Add the SDK script tag to `index.html` before `</head>`:
|
||||
|
||||
```html
|
||||
<script src="https://sdk.play.fun/latest"></script>
|
||||
```
|
||||
|
||||
Create `src/playfun.js` that wires the game's EventBus to Play.fun points tracking:
|
||||
|
||||
```js
|
||||
// src/playfun.js — Play.fun (OpenGameProtocol) integration
|
||||
import { eventBus, Events } from './core/EventBus.js';
|
||||
|
||||
const GAME_ID = '<game-uuid>';
|
||||
let sdk = null;
|
||||
let initialized = false;
|
||||
|
||||
export async function initPlayFun() {
|
||||
const SDKClass = typeof PlayFunSDK !== 'undefined' ? PlayFunSDK
|
||||
: typeof OpenGameSDK !== 'undefined' ? OpenGameSDK : null;
|
||||
if (!SDKClass) {
|
||||
console.warn('Play.fun SDK not loaded');
|
||||
return;
|
||||
}
|
||||
sdk = new SDKClass({ gameId: GAME_ID, ui: { usePointsWidget: true } });
|
||||
await sdk.init();
|
||||
initialized = true;
|
||||
|
||||
// Points on score change
|
||||
eventBus.on(Events.SCORE_CHANGED, ({ score, delta }) => {
|
||||
if (initialized && delta > 0) sdk.addPoints(delta);
|
||||
});
|
||||
// Save on game over
|
||||
eventBus.on(Events.GAME_OVER, () => { if (initialized) sdk.savePoints(); });
|
||||
// Auto-save every 30s
|
||||
setInterval(() => { if (initialized) sdk.savePoints(); }, 30000);
|
||||
// Save on unload
|
||||
window.addEventListener('beforeunload', () => { if (initialized) sdk.savePoints(); });
|
||||
}
|
||||
```
|
||||
|
||||
**Read the actual EventBus.js** to find the correct event names and payload shapes. Adapt accordingly.
|
||||
|
||||
Add `initPlayFun()` to `src/main.js`:
|
||||
|
||||
```js
|
||||
import { initPlayFun } from './playfun.js';
|
||||
// After game init
|
||||
initPlayFun().catch(err => console.warn('Play.fun init failed:', err));
|
||||
```
|
||||
|
||||
#### 7d. Rebuild and redeploy
|
||||
|
||||
```bash
|
||||
cd <project-dir> && npm run build && npx gh-pages -d dist
|
||||
```
|
||||
|
||||
Wait ~30 seconds, then verify the deployment is live.
|
||||
|
||||
#### 7e. Tell the user
|
||||
|
||||
> Your game is monetized on Play.fun!
|
||||
>
|
||||
> **Play**: `<game-url>`
|
||||
> **Play.fun**: `https://play.fun/games/<game-uuid>`
|
||||
>
|
||||
> The Play.fun widget is now live — players see points, leaderboard, and wallet connect.
|
||||
> Points auto-save on game over and every 30 seconds.
|
||||
>
|
||||
> **Share on Moltbook**: Post your game URL to [moltbook.com](https://www.moltbook.com/) — 770K+ agents ready to play and upvote.
|
||||
|
||||
Mark task 8 as `completed`.
|
||||
|
||||
### Pipeline Complete!
|
||||
|
||||
Tell the user:
|
||||
@@ -551,10 +691,13 @@ Tell the user:
|
||||
> - **Automated tests** — safety net for future changes
|
||||
> - **Quality review** — scored and prioritized improvements
|
||||
> - **Live on the web** — deployed to GitHub Pages with a public URL
|
||||
> - **Monetized on Play.fun** — points tracking, leaderboards, and wallet connect
|
||||
>
|
||||
> **Share your play.fun URL on Moltbook** to reach 770K+ agents on the agent internet.
|
||||
>
|
||||
> **What's next?**
|
||||
> - Add new gameplay features: `/game-creator:add-feature [describe what you want]`
|
||||
> - Upgrade to pixel art (if using shapes): `/game-creator:add-assets`
|
||||
> - Monetize with Play.fun: `/game-creator:playdotfun`
|
||||
> - Keep iterating! Run any step again anytime: `/game-creator:design-game`, `/game-creator:add-audio`, `/game-creator:qa-game`, `/game-creator:review-game`
|
||||
> - Launch a playcoin for your game (token rewards for players)
|
||||
> - Keep iterating! Run any step again: `/game-creator:design-game`, `/game-creator:add-audio`, `/game-creator:qa-game`
|
||||
> - Redeploy after changes: `npm run deploy`
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
---
|
||||
description: Register your game on Play.fun (OpenGameProtocol), add the browser SDK, and get a monetized play.fun URL
|
||||
disable-model-invocation: true
|
||||
argument-hint: "[game-path]"
|
||||
allowed-tools: ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "Task"]
|
||||
---
|
||||
|
||||
# Monetize Game (Play.fun / OpenGameProtocol)
|
||||
|
||||
Register your game on [Play.fun](https://play.fun) (OpenGameProtocol), integrate the browser SDK for points tracking and leaderboards, and get a shareable play.fun URL. This is the link you post to Moltbook.
|
||||
|
||||
**What you'll get:**
|
||||
1. Your game registered on Play.fun with anti-cheat config
|
||||
2. The Play.fun browser SDK integrated into your game (points widget, leaderboard, wallet connect)
|
||||
3. A rebuilt + redeployed game with the SDK active
|
||||
4. A play.fun game URL to share on Moltbook and social media
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A deployed game with a public URL (run `/game-creator:make-game` first, or ensure your game is deployed to GitHub Pages / Vercel / etc.)
|
||||
- Node.js installed
|
||||
|
||||
## Instructions
|
||||
|
||||
### Step 0: Locate the game
|
||||
|
||||
Parse `$ARGUMENTS` to find the game project directory. If not provided, check the current working directory for a `package.json` with Phaser or Three.js dependencies.
|
||||
|
||||
Read `package.json` to confirm this is a game project. Read `vite.config.js` or similar to determine the deployed URL (look for `base` path).
|
||||
|
||||
### Step 1: Authenticate with Play.fun
|
||||
|
||||
Check if the user already has Play.fun credentials:
|
||||
|
||||
```bash
|
||||
node skills/playdotfun/scripts/playfun-auth.js status
|
||||
```
|
||||
|
||||
**If credentials exist and are valid**, skip to Step 2.
|
||||
|
||||
**If no credentials**, walk the user through authentication:
|
||||
|
||||
> To register your game on Play.fun, you need to authenticate first.
|
||||
>
|
||||
> I'll start a local auth server. Click the link below to log in:
|
||||
|
||||
```bash
|
||||
node skills/playdotfun/scripts/playfun-auth.js callback &
|
||||
```
|
||||
|
||||
Then tell the user:
|
||||
|
||||
> Open this URL in your browser:
|
||||
> **https://app.play.fun/skills-auth?callback=http://localhost:9876/callback**
|
||||
>
|
||||
> Log in with your Play.fun account. The credentials will be saved automatically.
|
||||
> Tell me when you're done.
|
||||
|
||||
**Wait for user confirmation.** Then verify:
|
||||
|
||||
```bash
|
||||
node skills/playdotfun/scripts/playfun-auth.js status
|
||||
```
|
||||
|
||||
If verification fails, offer the manual method as a fallback:
|
||||
|
||||
> If the callback didn't work, you can paste your credentials manually.
|
||||
> Go to your Play.fun dashboard, copy your API credentials (base64 format), and I'll save them:
|
||||
> ```
|
||||
> node skills/playdotfun/scripts/playfun-auth.js manual <your-base64-credentials>
|
||||
> ```
|
||||
|
||||
### Step 2: Determine the game URL
|
||||
|
||||
Find the deployed game URL. Check in this order:
|
||||
|
||||
1. Look for a GitHub Pages URL by running:
|
||||
```bash
|
||||
GITHUB_USER=$(gh api user --jq '.login' 2>/dev/null)
|
||||
REPO_NAME=$(basename $(git remote get-url origin 2>/dev/null) .git 2>/dev/null)
|
||||
```
|
||||
If both resolve, the URL is `https://$GITHUB_USER.github.io/$REPO_NAME/`
|
||||
|
||||
2. Check `vite.config.js` for a `base` path that hints at the deployment URL
|
||||
|
||||
3. Ask the user for their game URL if it can't be determined
|
||||
|
||||
Verify the URL is accessible:
|
||||
|
||||
```bash
|
||||
curl -s -o /dev/null -w "%{http_code}" "$GAME_URL"
|
||||
```
|
||||
|
||||
### Step 3: Register the game on Play.fun
|
||||
|
||||
Read the game's `package.json` for the name and description. Read `src/core/Constants.js` (or equivalent) to determine reasonable anti-cheat limits based on the scoring system.
|
||||
|
||||
Use the Play.fun MCP `register_game` tool if available. Otherwise, use the API directly:
|
||||
|
||||
Load the `playdotfun` skill for API reference. Register the game via `POST https://api.opengameprotocol.com/games` with:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "<game-name>",
|
||||
"description": "<game-description>",
|
||||
"gameUrl": "<deployed-url>",
|
||||
"platform": "web",
|
||||
"isHTMLGame": true,
|
||||
"iframable": true,
|
||||
"maxScorePerSession": <based on game scoring>,
|
||||
"maxSessionsPerDay": 50,
|
||||
"maxCumulativePointsPerDay": <reasonable daily cap>
|
||||
}
|
||||
```
|
||||
|
||||
**Anti-cheat guidelines** (from the playdotfun skill):
|
||||
- Casual clicker/idle: `maxScorePerSession: 100-500`
|
||||
- Skill-based arcade (flappy bird, runners): `maxScorePerSession: 500-2000`
|
||||
- Competitive/complex: `maxScorePerSession: 1000-5000`
|
||||
|
||||
Save the returned **game UUID** — you'll need it for the SDK integration.
|
||||
|
||||
**Tell the user:**
|
||||
> Your game is registered on Play.fun!
|
||||
> **Game ID**: `<uuid>`
|
||||
> **Name**: `<name>`
|
||||
|
||||
### Step 4: Add the Play.fun Browser SDK
|
||||
|
||||
Integrate the SDK into the game. This is a lightweight addition — the SDK loads from CDN and provides a points widget overlay.
|
||||
|
||||
#### 4a. Add the SDK script tag to `index.html`
|
||||
|
||||
Add before the closing `</head>` tag:
|
||||
|
||||
```html
|
||||
<script src="https://sdk.play.fun/latest"></script>
|
||||
```
|
||||
|
||||
#### 4b. Create `src/playfun.js` integration module
|
||||
|
||||
Create a module that wires the Play.fun SDK into the game's EventBus:
|
||||
|
||||
```js
|
||||
// src/playfun.js
|
||||
// Play.fun (OpenGameProtocol) integration
|
||||
// Wires game events to Play.fun points tracking
|
||||
|
||||
import { eventBus, Events } from './core/EventBus.js';
|
||||
|
||||
const GAME_ID = '<game-uuid>';
|
||||
|
||||
let sdk = null;
|
||||
let initialized = false;
|
||||
|
||||
export async function initPlayFun() {
|
||||
if (typeof OpenGameSDK === 'undefined' && typeof PlayFunSDK === 'undefined') {
|
||||
console.warn('Play.fun SDK not loaded — skipping monetization');
|
||||
return;
|
||||
}
|
||||
|
||||
const SDKClass = typeof PlayFunSDK !== 'undefined' ? PlayFunSDK : OpenGameSDK;
|
||||
sdk = new SDKClass({
|
||||
gameId: GAME_ID,
|
||||
ui: { usePointsWidget: true },
|
||||
});
|
||||
|
||||
await sdk.init();
|
||||
initialized = true;
|
||||
console.log('Play.fun SDK initialized');
|
||||
|
||||
wireEvents();
|
||||
}
|
||||
|
||||
function wireEvents() {
|
||||
// Award points on score changes
|
||||
if (Events.SCORE_CHANGED) {
|
||||
eventBus.on(Events.SCORE_CHANGED, ({ score, delta }) => {
|
||||
if (sdk && initialized && delta > 0) {
|
||||
sdk.addPoints(delta);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Save points on game over
|
||||
if (Events.GAME_OVER) {
|
||||
eventBus.on(Events.GAME_OVER, () => {
|
||||
if (sdk && initialized) {
|
||||
sdk.savePoints();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Auto-save every 30 seconds
|
||||
setInterval(() => {
|
||||
if (sdk && initialized) {
|
||||
sdk.savePoints();
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
// Save on page unload
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (sdk && initialized) {
|
||||
sdk.savePoints();
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**Important**: Read the actual `EventBus.js` to find the correct event names. Common patterns:
|
||||
- `SCORE_CHANGED` / `score:changed` with `{ score, delta }` or `{ score }`
|
||||
- `GAME_OVER` / `game:over`
|
||||
|
||||
Adapt the event names and payload destructuring to match what the game actually emits. If the game doesn't emit a delta, compute it by tracking the previous score.
|
||||
|
||||
#### 4c. Wire into main.js
|
||||
|
||||
Add the Play.fun init call to the game's entry point (`src/main.js`):
|
||||
|
||||
```js
|
||||
import { initPlayFun } from './playfun.js';
|
||||
|
||||
// After game initialization
|
||||
initPlayFun().catch(err => console.warn('Play.fun init failed:', err));
|
||||
```
|
||||
|
||||
The `initPlayFun()` call should be non-blocking — if the SDK fails to load (e.g., ad blocker), the game still works.
|
||||
|
||||
### Step 5: Rebuild and redeploy
|
||||
|
||||
```bash
|
||||
cd <project-dir> && npm run build
|
||||
```
|
||||
|
||||
If the build fails, fix the integration code and retry.
|
||||
|
||||
Then redeploy:
|
||||
|
||||
```bash
|
||||
cd <project-dir> && npx gh-pages -d dist
|
||||
```
|
||||
|
||||
Or whatever deploy method the project uses (`npm run deploy` if available).
|
||||
|
||||
### Step 6: Confirm and share
|
||||
|
||||
Wait ~30 seconds for deployment to propagate, then verify:
|
||||
|
||||
```bash
|
||||
curl -s -o /dev/null -w "%{http_code}" "$GAME_URL"
|
||||
```
|
||||
|
||||
**Tell the user:**
|
||||
|
||||
> Your game is monetized on Play.fun!
|
||||
>
|
||||
> **Play your game**: `<game-url>`
|
||||
> **View on Play.fun**: `https://play.fun/games/<game-uuid>`
|
||||
>
|
||||
> **What's live:**
|
||||
> - Points widget overlay (bottom-right corner)
|
||||
> - Leaderboard tracking
|
||||
> - Wallet connect for claiming rewards
|
||||
> - Auto-saves points every 30 seconds + on game over
|
||||
>
|
||||
> **Share on Moltbook**: Post your game URL to [moltbook.com](https://www.moltbook.com/) — 770K+ agents on the agent internet ready to play and upvote.
|
||||
>
|
||||
> **Next steps:**
|
||||
> - Launch a playcoin for your game (token rewards for players)
|
||||
> - Check your leaderboard on Play.fun
|
||||
> - Share the play.fun URL on social media
|
||||
+1
-1
@@ -1 +1 @@
|
||||
../../skills/skills
|
||||
../submodules/playdotfun/skills
|
||||
Submodule
+1
Submodule submodules/playdotfun added at d3c976cc2d
Reference in New Issue
Block a user