English | 日本語
Mike's Moonlight Run is a playful three-stage side-scrolling action game built for The WebMCP Challenge. A voxel-style cat crosses changing skylines, avoids gaps, flowerpots, vents, and patrolling mice, and heads for the postbox at the end of each stage.
The world, cat, enemies, obstacles, and collectibles are rendered as real-time 3D geometry with Three.js. It usually looks like a 2D platformer because the camera watches from the side, but the camera periodically makes a full 360-degree yaw orbit and reveals the depth of the scene.
The campaign moves from indigo moonlit rooftops to teal-and-violet neon rainworks and finally an amber sunrise skyrail. Gaps become wider, mice become faster and more numerous, and camera rotations begin sooner as the difficulty rises.
https://mike-moonlight-run.rojii.chatgpt.site
- Move:
Left Arrow/Right ArroworA/D - Jump:
Space,Up Arrow, orW - Restart:
Ror the restart button - Pause: the pause button
- Touch: hold the left or right button with one finger and press
JUMPwith another - Language: English is the default; use the
EN / 日本語switcher to change the interface language
Fish are optional. A floating heart restores one life when the cat is below the three-life maximum. Reaching the postbox clears the current stage; clear all three stages to stop the campaign timer, trigger the confetti celebration, and open a result card with the final time and total fish count. The result can be posted to X or copied to the clipboard. Each stage starts with three lives.
A person understands a platform game visually and acts through continuous input. An agent needs a different interface: complete, structured state and a small set of reliable actions. WebMCP lets the same live page provide both without creating a separate game service or an agent-only copy of the world.
The player and the agent share one authoritative GameState. Keyboard and touch input, Three.js rendering, physics, collisions, camera yaw, and WebMCP tool calls all read or update that same state. A person can take over from the agent at any time, and the agent can inspect what happened between short action sequences.
- A person can play directly, then ask an agent to continue from the current position.
- An agent can inspect every gap, obstacle, moving enemy, collectible, and the goal without guessing from pixels.
- The agent can execute timed movement and jump sequences in the live game and return the resulting state.
- Manual input automatically cancels an active agent sequence, making handoff immediate.
Before WebMCP, an agent would typically need screenshot interpretation, fragile coordinate-based clicking, or a separate private API. Those approaches are especially unreliable when the 3D camera rotates and enemies keep moving. Here the rotating view can challenge the human visually while the agent continues to reason from stable world coordinates.
The client registers two imperative tools with document.modelContext.registerTool(...) in app/page.tsx. Both tools operate on the same state and physics implementation in lib/moonlight-game.ts.
Reads the complete current game state. It has an empty input object and is marked read-only.
The response includes:
- game status, current stage, campaign progress, stage progress, elapsed time, and lives
- cat position, velocity, facing direction, and grounded state
- camera position, yaw angle, and yaw phase
- ground segments and gaps
- obstacles, moving enemies, uncollected fish, life-recovery hearts, and the goal
- the nearest upcoming objects
Agents should call this tool before playing and again between short action sequences because enemies move over time.
Executes an ordered sequence of 1 to 30 controls in the live game and returns the complete resulting state after the sequence finishes.
Each action has this schema:
{
"action": "run_right | run_left | jump_right | jump_left | wait",
"durationMs": 500
}actionis required.durationMsis optional and is clamped to 80–2400 ms.- The default is 760 ms for jump actions and 500 ms for other actions.
jump_rightandjump_leftcombine jumping with horizontal movement.- An active sequence can be cancelled with an
AbortSignalor by taking manual control. - After
stage_clear, the nextplay_actionscall automatically enters the next stage.
For moving hazards, use 1–5 short actions and read the state again rather than sending one long blind sequence.
- Node.js 22.13.0 or later
- npm
- A browser with WebMCP support for agent control:
- ChatGPT desktop app's in-app browser, or
- Google Chrome 149 or later with
chrome://flags/#enable-webmcp-testingenabled, followed by a browser restart
The game still supports normal keyboard and touch play in browsers without WebMCP; only the agent tools will be unavailable.
git clone https://github.com/rsakao/mike-moonlight-run.git
cd mike-moonlight-run
npm ci
npm run devOpen the local URL printed by the development server.
npm run lint
npm run buildThe production build is emitted to dist/. To run that build locally with Wrangler:
npm run start-
Open the local or hosted URL in ChatGPT's in-app browser, or in WebMCP-enabled Chrome 149+.
-
Confirm that the page reports
WEBMCP READYand lists both tool names in the Agent Console. -
Call
moonlight_run.get_stateand confirm that it returns the current cat, world, hazard, and camera state. -
Call
moonlight_run.play_actionswith a short sequence such as:{ "actions": [ { "action": "run_right", "durationMs": 500 }, { "action": "jump_right", "durationMs": 760 } ] } -
Call
moonlight_run.get_stateagain and confirm that the returned position and progress changed.
- React 19 and TypeScript
- vinext and Vite
- Three.js for the real-time 3D world
- Tailwind CSS and a Base UI button primitive
- WebMCP imperative tool registration
- ChatGPT Sites / Cloudflare Workers-compatible deployment
All game artwork and 3D geometry are created specifically for this project in code or included as project-owned assets. No external gameplay API, account, database, or secret is required.
Licensed under the MIT License.
