@jamunlabs/gameu-cli
v0.5.4
Published
CLI for scaffolding and building gameu games (npm bin: `gameu`).
Readme
@jamunlabs/gameu-cli
CLI for scaffolding and developing games for the gameu platform.
Pure Node.js. No Rust toolchain required for game development.
Install
npm install -g @jamunlabs/gameu-cliThis pulls the host binary for your platform automatically via npm's
optionalDependencies mechanism (the same pattern esbuild /
@swc/core / sharp use). Supported platforms:
| Platform | Architecture | npm package |
|------------|---------------------|------------------------------------------|
| Linux | x64, arm64 | @jamunlabs/gameu-host-linux-x64, @jamunlabs/gameu-host-linux-arm64 |
| macOS | x64 (Intel), arm64 (Apple Silicon) | @jamunlabs/gameu-host-darwin-x64, @jamunlabs/gameu-host-darwin-arm64 |
| Windows | x64 | @jamunlabs/gameu-host-win32-x64 |
Host-binary status (current): the five platform-specific host binary packages are claimed at
0.0.0placeholders on npm, but the actual0.1.0binaries publish via the.github/workflows/release-host-binary.ymlmatrix workflow on the nexthost-v0.1.0git tag. Until that runs,gameu devfalls back toGAMEU_DEV_FROM_REPO=/path/to/gameufor repo contributors and prints a roadmap pointer otherwise. Track at https://github.com/jamunlabs/gameu/issues for the platform you need.
Usage
gameu create <name> [--runtime <kind>] [--profile <p>] [--target <t>]
Scaffold a new game project in ./<name>/.
gameu create my-game # iframe-js (default)
gameu create my-cube --runtime native-godot # bare-bones Godot 4 game
gameu create my-platformer --runtime native-godot --profile 2d-pixel
gameu create my-arena --runtime native-godot --profile 3d
# Override the per-profile renderer default explicitly:
gameu create my-arena --runtime native-godot --profile 3d --target desktopSupported runtimes (mirrors the SDK RuntimeKind enum minus the bare
native-binary slot which has no scaffold):
| Runtime | Status | What ships in the scaffold |
|----------------------|--------------------|----------------------------|
| iframe-js | host loads today | TS reducer/renderer/game + npm scripts + CLAUDE.md |
| iframe-bevy-wasm | host pending | Cargo + wasm-pack scaffolding + bridge index.html |
| iframe-unity-webgl | host pending | Unity WebGL wrapper index.html + bridge stub |
| iframe-godot-wasm | host pending | Godot Web export wrapper + GDScript bridge sample |
| native-godot | host loads today (Q181-d) | project.godot + main.tscn + main.gd + .gdextension + manifest + README + CLAUDE.md |
For --runtime native-godot, --profile <kind> picks the starter
scene + non-renderer project defaults (Q181-e):
| Profile | Scene root | Non-renderer defaults |
|---------------|-------------|-----------------------|
| bare (default) | Node | dimension-agnostic |
| 2d | Node2D + Camera2D | 1920×1080 viewport, canvas_items stretch |
| 2d-pixel | Node2D + Camera2D | 320×180 base + 1920×1080 window override, viewport stretch, nearest-neighbor texture filter, 2D pixel snap on |
| 3d | Node3D + Camera3D + DirectionalLight3D + WorldEnvironment | test-cube shape minus the cube |
--target <kind> picks the renderer (Q181-f) — orthogonal to profile,
so any combination is valid. Per-profile default in the table below;
override with --target for any other choice.
| Target | Godot renderer | When to use |
|-----------|----------------------|-------------|
| mobile | Forward Mobile (Vulkan) | Default for bare and 3d. Tile-based-GPU friendly; right answer for Android-class hardware (most gameu kiosks). |
| desktop | Forward+ (Vulkan) | Full PBR + SDFGI + volumetric fog + many lights. Higher minimum spec + battery cost. |
| compat | GL Compatibility (OpenGL ES 3.0) | Default for 2d and 2d-pixel. Widest device coverage; lightest. No PBR. |
Heads up: the SDK shared library (
libgameu_godot_sdk.so) is currently Linux x86_64 only.--target mobileselects the Mobile renderer, not an Android cross-build — Android-binary packaging is a separate deferred item.
The scaffold produces a hello-world starting point; for iframe-js
that's the gameu SDK's Reducer + Renderer + GameRunner pattern.
Every scaffolded project includes a CLAUDE.md with detailed
instructions for AI coding agents (Claude Code, etc.) — patterns,
anti-patterns, file layout, common pitfalls. Open it before letting
an agent loose on your game logic.
For native-godot you also need a one-time SDK shared-library build
from a gameu source clone (cargo build --release -p gameu-godot-sdk
cpinto<name>/lib/); the printedNext stepswalk through it. Linux x86_64 only for v1.
Files produced for the default --runtime iframe-js scaffold:
| File | Purpose |
|-----------------------|-----------------------------------------------------------|
| manifest.json | Game id, runtime, version, player counts. SDK-validated. |
| src/reducer.ts | Pure state reducer (no I/O, no DOM). |
| src/renderer.ts | DOM/canvas projection (build-once + mutate). |
| src/game.ts | Wires seams + runs the game loop. |
| src/gameu.d.ts | Ambient types for window.gameu.*. |
| index.html | Loads SDK shared libs + src/game.js as ES module. |
| CLAUDE.md | AI-agent guidance — read this first. |
| scripts/copy-sdk-assets.js | Prebuild: copies SDK JS into ./public/lib/. |
Files produced for --runtime native-godot (any profile):
| File | Purpose |
|----------------------------|-----------------------------------------------------------|
| manifest.json | Game id, runtime, version, player counts. |
| project.godot | Godot 4 project file (renderer per --target). |
| main.tscn | Main scene (root + GameuBridge + profile-specific extras).|
| main.gd | Bridge-signal wiring + signal_ready() call. |
| gameu_godot_sdk.gdextension | GDExtension descriptor → lib/libgameu_godot_sdk.so. |
| lib/.gitkeep | Placeholder so the lib/ dir is tracked before .so staging.|
| README.md, CLAUDE.md | Per-project docs (the second is for AI agents). |
Names must be kebab-case, 3-40 chars, lowercase letters + digits + hyphens, no leading/trailing/double hyphen (same rules as a kiosk subdomain slug).
gameu prepare
Validate a --runtime native-godot project and prime its extension
cache so it's ready to launch. Editor-less workflow entry point.
cd my-game
gameu prepare # cache prime + validate
gameu-desktop --native-godot-project $(pwd)Checks:
project.godotexists in cwd.lib/libgameu_godot_sdk.sois staged (whengameu_godot_sdk.gdextensionis present — non-gameu Godot projects skip this check).godot4/godotresolves on$PATH.godot --editor --headless --quitwrites.godot/extension_list.cfg.
gameu prepare --no-cache-prime runs only checks 1–2 (no Godot
invocation). Tolerates the documented Godot 4.6.2 SIGSEGV during
editor-layout teardown on Linux: the cache writes before the crash, so
gameu prepare checks the cache file directly and ignores the child's
exit code.
gameu dev [--port <port>]
Boot the local dev host with the game in the current working directory. The game appears in the host's catalog alongside the 4 built-in starters; pair a phone, pick the game, develop iteratively.
cd my-game
npm run build # produces index.html + public/lib/
gameu dev --port 8080 # boots the host; open http://localhost:8080/gameu dev resolves the platform-specific host binary via the
optionalDependencies npm packaging — no Rust toolchain, no source
clone. If the binary for your platform isn't installed (Phase 3 still
in flight or unsupported platform), the command prints a clear
roadmap pointer and exits.
No file-watching yet. Source changes require a manual npm run
build followed by a browser refresh. Live rebuild is a Phase 3.5
follow-up.
For gameu repo contributors
If you maintain the gameu platform itself and want to test SDK changes against your scaffolded game without re-publishing the binary, opt in to the cargo-build path:
GAMEU_DEV_FROM_REPO=/path/to/your/gameu-clone gameu devThis shells to cargo xtask run-game --game-dir $(pwd) from the
clone. External game devs never need this — gameu dev resolves
the npm-shipped binary automatically.
Workflows: native Godot
Three end-to-end scenarios. All three operate on the same on-disk project — switch between them mid-project at no cost. For full GDScript code examples, see the SDK README's "Recipes" section — this section covers shell ergonomics only.
A) Editor-driven (Godot 4 GUI + Claude for code)
Best when you want to lay out scenes visually, tune materials, animations, particles, etc.
gameu create my-game --runtime native-godot --profile 3d
cd my-game
# One-time SDK build (from a gameu source clone):
cd /path/to/gameu && cargo build --release -p gameu-godot-sdk
cp /path/to/gameu/target/release/libgameu_godot_sdk.so /path/to/my-game/lib/
# Open the editor (also primes the cache):
godot --path /path/to/my-game
# Edit main.gd in the script panel or your IDE.
# When ready to test against the gameu host:
gameu-desktop --native-godot-project /path/to/my-gameB) Editor-less (Claude + MCP, headless)
Best when you want to drive scene authoring purely via prompts/code
and never open the GUI. Uses the godot / blender / tiled MCPs.
gameu create my-platformer --runtime native-godot --profile 2d-pixel
cd my-platformer
# One-time SDK build (same as above):
# ... cp the .so into lib/ ...
# Validate + prime extension cache headlessly:
gameu prepare
# Develop via Claude:
# - mcp__godot__create_scene / add_node / save_scene for scene tree
# - Edit/Write on .gd files for scripts
# - mcp__tiled__* for tilemaps
# - mcp__blender__* for 3D meshes (export glTF, drop in project)
# - mcp__godot__run_project + get_debug_output to iterate
gameu-desktop --native-godot-project $(pwd)gameu prepare writes .godot/extension_list.cfg so GameuBridge
resolves on launch. Re-run it any time you add a new GDExtension.
C) Hybrid
Open the editor when scene visualization helps; close it and let
Claude continue programmatically when it doesn't. There's no
migration step — the same project.godot works in both modes.
godot --path . # tune particles visually, save, close
# ... continue with Claude editing GDScript via Edit/Write ...
gameu-desktop --native-godot-project $(pwd)Choosing --profile and --target
--profile picks the starter scene shape; --target picks the
renderer. They compose freely. Per-profile defaults match the
Android-class hardware reality of most gameu kiosks today.
| Want to build… | --profile | --target |
|-------------------------------------------|--------------|-------------------|
| Pixel-art platformer, top-down, RPG | 2d-pixel | compat (default) |
| Smooth 2D (vector / non-pixel) | 2d | compat (default) |
| 3D arena / racing / casual 3D on Android | 3d | mobile (default) |
| 3D for desktop-only with full PBR + SDFGI | 3d | desktop |
| Custom scene root from scratch | bare | mobile (default) |
| Targeting widest device coverage (low-end Android, OpenGL ES 3.0 only) | (any) | compat |
Heads up:
--target mobileselects the Mobile renderer, not an Android cross-build. The SDK shared library (libgameu_godot_sdk.so) is currently Linux x86_64 only; Android-binary packaging is on the deferred list.
Troubleshooting (native-godot)
Cannot get class 'GameuBridge' on first launch
Godot needs one editor pass to scan the .gdextension and write
.godot/extension_list.cfg. Run gameu prepare (or godot --editor
--headless --path . --quit) once. The cache survives across launches.
gameu prepare reports cache file not written
godot --editor --headless failed before reaching the cache write.
Re-run it manually to see the error:
godot --editor --headless --path . --quitThe Linux 4.6.2 SIGSEGV during editor-layout teardown is expected
and harmless — gameu prepare tolerates it. Any other error means
the project itself is malformed (check project.godot).
SDK shared library not found at lib/libgameu_godot_sdk.so
Build from a gameu source clone:
cd /path/to/gameu
cargo build --release -p gameu-godot-sdk
cp target/release/libgameu_godot_sdk.so /path/to/your-game/lib/Re-run gameu prepare after staging the .so.
Game launches but connected=false shows in logs
You're running standalone (godot --path .), not via gameu-desktop
--native-godot-project. Dev mode is intentional and lets you iterate
in the editor. To see connected=true plus real peer events, launch
through the host.
godot4 / godot not found on $PATH
Install Godot 4.6+. The host registers the binary it finds first —
godot4 takes precedence over godot (matches Linux distro
conventions where the 3.x-era godot symlink may still exist).
SDK dependency in your scaffolded game
The scaffold's package.json declares @jamunlabs/gameu-sdk: ^0.1.0 as a
dependency. The SDK is on npm, so npm install resolves it directly.
Roadmap
| Phase | What | Status |
|-------|----------------------------------------------------------------|------------|
| 1 | SDK foundation (@jamunlabs/gameu-sdk) | landed |
| 2 | Scaffold CLI (gameu create) | landed |
| 3 | Local dev loop — runtime + CLI wiring | landed |
| 3.x | Cross-platform host-binary publish (@jamunlabs/gameu-host-*) | placeholders claimed; binary publish on next host-v* tag |
| 4 | gameu build + gameu publish (npm + gameu catalog) | landed |
| 5 | In-tree starter migration (UNO/TTT/S&L/Ludo via npm-imports) | landed (4 games extracted to external repos and published as @jamunlabs/gameu-{tictactoe,snakesandladders,ludo,uno}) |
| 6 | Host install hardening (POST /api/install review) | landed |
License
MIT
