@genex-ai/cli-demo 0.47.0-dev.70 → 0.47.0-dev.74
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/README.md +25 -2
- package/dist/index.js +1158 -16
- package/package.json +4 -2
- package/templates/skills/genex-ai-hud/SKILL.md +381 -0
- package/templates/skills/genex-ai-hud/references/masked-fill.md +145 -0
- package/templates/skills/genex-ai-hud/references/stage1-prompt-template.md +44 -0
- package/templates/skills/genex-ai-hud/references/stage2-prompt-template.md +73 -0
- package/templates/skills/genex-ai-image/SKILL.md +14 -4
- package/templates/skills/genex-ai-menu/SKILL.md +291 -0
- package/templates/skills/genex-ai-video/SKILL.md +11 -4
- package/templates/skills/genex-getting-started/SKILL.md +5 -2
- package/templates/skills/genex-threejs-game-ui/SKILL.md +149 -18
- package/templates/skills/genex-threejs-game-ui/references/style-capsules.md +89 -0
- package/templates/skills/genex-threejs-skill-router/SKILL.md +27 -1
- package/templates/skills/genex-threejs-skill-router/references/routing-map.md +37 -17
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +10 -5
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Stage 2 prompt template — deconstruct into an asset sheet
|
|
2
|
+
|
|
3
|
+
Fill `[ASSET_LIST]`, then pass the whole text as the prompt to
|
|
4
|
+
`npx genex image "<filled prompt>" --edit <mockup-url> --quality high`.
|
|
5
|
+
|
|
6
|
+
`[ASSET_LIST]` is an itemized list of the assets to produce. Each item:
|
|
7
|
+
|
|
8
|
+
- **states its source location** in the mockup ("the HP bar at the bottom
|
|
9
|
+
left") so the model finds what to copy;
|
|
10
|
+
- **states the fused-unit boundary** when the element is several visually
|
|
11
|
+
attached pieces ("the bars panel INCLUDING the gold cross ornament on its
|
|
12
|
+
left") — separating spatially fused ornament from its container makes
|
|
13
|
+
code-side reassembly fragile, so fused units stay one asset;
|
|
14
|
+
- **states what to KEEP** from your text-ownership record (`baked_static`
|
|
15
|
+
identity labels);
|
|
16
|
+
- **states what to REMOVE** (`runtime_static` labels and `runtime_dynamic`
|
|
17
|
+
values, fills, items);
|
|
18
|
+
- **requests the annotated duplicate** for every bar/meter frame (the
|
|
19
|
+
template's progress block below covers the mechanics — your item just says
|
|
20
|
+
"output the clean frame + annotated duplicate pair").
|
|
21
|
+
|
|
22
|
+
## The template
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Look at this game HUD screenshot. Produce a GAME DEVELOPMENT ASSET SHEET — the individual reusable building-block graphics a developer would composite with code at runtime. The output is NOT a rearrangement of the visible HUD. It is a list of distinct extractable assets, where each asset preserves the EXACT proportions and visual style of how it appears in the source.
|
|
26
|
+
|
|
27
|
+
Lay these assets on a pure flat white #ffffff background, separated by at least 100px of clear whitespace between each:
|
|
28
|
+
|
|
29
|
+
[ASSET_LIST]
|
|
30
|
+
|
|
31
|
+
If an asset is a generated progress/bar/meter frame, output TWO CELLS immediately beside each other:
|
|
32
|
+
1. LEFT CELL — the clean production asset the game will use. Preserve exact style, baked_static labels, frame metal, bevels, dividers, scratches, proportions, and texture. Remove runtime dynamic fill and values. Do not paint technical colors on this clean cell.
|
|
33
|
+
2. RIGHT CELL — an annotated duplicate of the same production asset. It must be the same asset, same scale, same canvas bounds, same position, and same outer shape as the left cell. The only difference: paint runtime-fill zones with pure green key color #00ff00. Green marks only the places where runtime bar/progress fill should appear. Paint the green as a FLAT, UNIFORM, fully-saturated #00ff00 fill — no shading, no gradient, no inner shadow, no vignette, NO DARKENING TOWARD THE EDGES, no lighting, no highlights, no texture; constant color edge-to-edge with a HARD, CRISP boundary against the frame. The green is a chroma-key, not a lit surface — any edge shading makes the extracted alpha mask ragged. For discrete segment meters, paint each segment slot as a separate green shape; do not merge slots into one continuous strip and do not paint half-segments.
|
|
34
|
+
|
|
35
|
+
Do NOT create a separate black-background mask cell. Do NOT create a standalone simplified silhouette. The right cell is a registration-safe annotation map; local tooling derives the alpha mask from its green pixels and uses the left cell as the frame.
|
|
36
|
+
|
|
37
|
+
PRESERVE the exact visual style, materials, colors, ornamental detail, and PROPORTIONS of every asset as it appears in the input image. Do not redraw, do not stylize, do not normalize aspect ratios to standard shapes, do not "improve" anything. The ONLY changes are the content removals listed above (bar fills, slot items, map content, runtime-owned text, dynamic-value text, etc).
|
|
38
|
+
|
|
39
|
+
CRITICAL text ownership distinction:
|
|
40
|
+
|
|
41
|
+
KEEP these baked into the asset — they are part of the panel's IDENTITY and never change at runtime:
|
|
42
|
+
- Static labels carved or painted into the frame: panel titles, axis tick labels, scale numerals, unit indicators ("LB", "FT", "%"), decorative engravings
|
|
43
|
+
- Large sticker/hazard-panel identity labels printed into the design (examples: "SCORE", "RUN", "SPECIAL", "SPEED")
|
|
44
|
+
- Static notch / segment dividers along a bar's length (runtime code composites a scaling fill beneath them)
|
|
45
|
+
- Decorative graphics fused with the panel: an engraved emblem on a coin, a carved compass rose on a bezel, a fixed icon glyph on a slot frame
|
|
46
|
+
- Tick marks on a fixed scale (depth gauge marks, dial gradations)
|
|
47
|
+
|
|
48
|
+
REMOVE runtime-owned content:
|
|
49
|
+
- Current numeric values (the "1247" coins, the "47" ammo count)
|
|
50
|
+
- Current bar fill levels (the colored fill INSIDE a bar — runtime code reveals it through a mask)
|
|
51
|
+
- Current item icons inside slots (the sword, potion — runtime renders the equipped item)
|
|
52
|
+
- Current map content / radar blips (the game paints these at runtime)
|
|
53
|
+
- Any editable or localizable label the design does not fuse into the frame, even if it does not change frame-to-frame
|
|
54
|
+
|
|
55
|
+
The test for each text element: "is this fixed identity artwork, or should runtime code own it?" Fixed identity → KEEP. Runtime-owned → REMOVE.
|
|
56
|
+
|
|
57
|
+
DO NOT include in the output sheet:
|
|
58
|
+
- Pure tick-mark strips, line-only compass rails, or any element that consists only of evenly-spaced lines / dashes WITH NO surrounding frame or ornament
|
|
59
|
+
- Crosshairs and reticles built from simple geometric primitives (corner brackets, dots, plus signs, triangles)
|
|
60
|
+
- Plain rectangles, plain circles, plain triangles without texture or ornament
|
|
61
|
+
- Simple dot indicators, status pips, blip markers
|
|
62
|
+
- Fills inside bars, items inside slots, map terrain inside minimap rings (these are added at runtime by CSS / game code)
|
|
63
|
+
|
|
64
|
+
Those excluded elements will be recreated by runtime code (CSS shapes and DOM text) — much crisper than a downsampled PNG.
|
|
65
|
+
|
|
66
|
+
Pure white #ffffff background everywhere except where the actual UI assets sit.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Adapt the concrete KEEP/REMOVE examples to YOUR mockup's text-ownership
|
|
70
|
+
record — the categories are fixed, the examples are illustrations. The
|
|
71
|
+
annotated duplicates are extraction guides, not runtime art: after the
|
|
72
|
+
`--clean` pass, feed each clean/annotated cell pair to `npx genex ui masks`
|
|
73
|
+
to derive the mask PNG + `fillBox`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: genex-ai-image
|
|
3
|
-
description: Generate a real image (PNG/JPEG) from a text prompt with `npx genex image`, then load it into Three.js on any mesh, plane, or sprite. Use for posters, paintings, billboards, signs, logos, sprites, card/item art, loading screens, textures for in-game screens, and decals/stickers ("wanted poster", "arcade cabinet marquee", "
|
|
3
|
+
description: Generate a real image (PNG/JPEG) from a text prompt with `npx genex image`, then load it into Three.js on any mesh, plane, or sprite. Use for posters, paintings, billboards, signs, logos, sprites, card/item art, loading screens, textures for in-game screens, and decals/stickers ("wanted poster", "arcade cabinet marquee", "hand-painted tavern sign") rather than a procedural/shader look. Pass `--transparent` for anything with an alpha channel.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Genex AI · Image
|
|
@@ -22,7 +22,7 @@ art on an in-game screen, or a decal/sticker.
|
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
npx genex image "<prompt>"
|
|
25
|
-
npx genex image "
|
|
25
|
+
npx genex image "chalk graffiti tag, hand-drawn style" --transparent # PNG with alpha (decals/stickers/logos)
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Blocks until ready, then prints its public URL:
|
|
@@ -166,10 +166,20 @@ See `$genex-threejs-multiplayer` for the `shared` channel rules and the room API
|
|
|
166
166
|
- `--transparent` — PNG with an alpha channel (mandatory for decals/stickers/logos —
|
|
167
167
|
anything laid on top of a surface).
|
|
168
168
|
- `--aspect <ratio>` — image shape (e.g. `square`, `16:9`, `9:16`); default is square.
|
|
169
|
-
- `--
|
|
170
|
-
|
|
169
|
+
- `--quality <low|medium|high>` — quality preset; higher costs more and takes longer.
|
|
170
|
+
- `--size <WxH>` — exact pixel size (multiples of 16, each side ≤ 3840, aspect ≤ 3:1).
|
|
171
|
+
- `--edit <url>` — edit THAT generated image with the prompt (image-to-image).
|
|
172
|
+
- `--clean <url>` — ML background removal of THAT image only (prompt recorded, unused).
|
|
173
|
+
- `--remove-bg` — chain ML background removal after the generation/edit.
|
|
174
|
+
- `--bg-mode <sprite|glyph|sheet>` — background-removal model (`glyph` for
|
|
175
|
+
digits/closed shapes; `--clean` defaults to `sheet`).
|
|
176
|
+
- `--no-wait` — enqueue and return immediately, without the URL. Fire-and-forget
|
|
177
|
+
only: re-running the command creates (and bills) a NEW image.
|
|
171
178
|
- `--api-url <url>` — override the API base (local dev).
|
|
172
179
|
|
|
180
|
+
Menu backdrops belong to `$genex-ai-menu`; a cohesive art-directed HUD sprite
|
|
181
|
+
set belongs to `$genex-ai-hud` — both build on this command.
|
|
182
|
+
|
|
173
183
|
## Troubleshooting
|
|
174
184
|
|
|
175
185
|
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: genex-ai-menu
|
|
3
|
+
description: Generate a cinematic game menu — one looping atmospheric video background plus animated DOM buttons — with `npx genex image` + `npx genex video --frame`. Use for main menus, title/start screens, pause, victory/defeat, lobby, and credits screens when the game deserves a filmic backdrop ("storm light over a lighthouse coast", "sun-drenched poppy meadow") rather than a plain CSS panel.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Genex AI · Menu
|
|
7
|
+
|
|
8
|
+
Turn two commands into a cinematic menu: one looping atmospheric mp4 as the
|
|
9
|
+
full-screen background, 3–5 HTML buttons on top. The video sets the mood; the
|
|
10
|
+
buttons are ordinary DOM, so the menu stays crisp, localizable, and wired to
|
|
11
|
+
real game events.
|
|
12
|
+
|
|
13
|
+
## When to use this vs. a plain CSS menu
|
|
14
|
+
|
|
15
|
+
- **Use this skill** when the menu should feel like the game's opening shot —
|
|
16
|
+
a title screen with weather and light, a defeat screen over smoldering ruins,
|
|
17
|
+
a lobby with the arena breathing in the background.
|
|
18
|
+
- **Use plain CSS** (`$genex-threejs-game-ui` alone) for utilitarian screens —
|
|
19
|
+
a quick pause overlay, a settings list, a loading bar. A dark translucent
|
|
20
|
+
panel is cheaper and often more readable. You can also get the best of both:
|
|
21
|
+
reuse this skill's menu video under a darker overlay for pause/victory
|
|
22
|
+
variants (see Tips).
|
|
23
|
+
|
|
24
|
+
## Style brief first
|
|
25
|
+
|
|
26
|
+
Use the game's ONE shared style brief from `$genex-threejs-game-ui`'s "Plan the
|
|
27
|
+
UI first" gate (materials, 4–5 named hues, font pair, mood) — the menu, HUD,
|
|
28
|
+
and loader all consume the same brief; don't write a second one here. The
|
|
29
|
+
style is THIS game's: don't default to any stock register the examples below
|
|
30
|
+
might suggest. Two hard rules for the frame prompt:
|
|
31
|
+
|
|
32
|
+
- **Full-bleed cinematic 16:9.** The frame is a filmic establishing shot,
|
|
33
|
+
edge to edge. End the prompt with: `Edge-to-edge cinematic composition.
|
|
34
|
+
Full-bleed 16:9 frame. No UI elements, no text, no buttons in the frame.`
|
|
35
|
+
- **NO UI in the frame — ever.** No buttons, no title text, no logos, no
|
|
36
|
+
menus baked into the image. All of that is DOM on top. If the image model
|
|
37
|
+
draws UI into the frame, the prompt was wrong — rewrite and regenerate.
|
|
38
|
+
|
|
39
|
+
## Single-frame vs two-frame
|
|
40
|
+
|
|
41
|
+
- **Single-frame (default — use this).** Generate ONE image and pass it as
|
|
42
|
+
`--frame`: the video model receives it as both the first and last frame, so
|
|
43
|
+
frame N equals frame 0 and the loop is mathematically seamless. Constraint:
|
|
44
|
+
the motion prompt must describe **return-to-start** motion — a cycle that
|
|
45
|
+
ends where it began. Good: "ravens circle the spire and return to their
|
|
46
|
+
perches", "fog drifts left then back right", "candle flames flicker".
|
|
47
|
+
Bad: "camera dollies forward into the gate" (one-way motion fights the
|
|
48
|
+
identical endpoints and produces a visible hitch).
|
|
49
|
+
- **Two-frame** (`--first-frame` + `--last-frame`) only when the menu
|
|
50
|
+
genuinely needs a state change (rain starts and persists, a figure walks in
|
|
51
|
+
and stays). The loop will have a visible seam where the last frame snaps
|
|
52
|
+
back to the first — accept that trade deliberately or don't use it.
|
|
53
|
+
|
|
54
|
+
## Run
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# 1. The frame — a still of the scene the loop returns to (this example is a
|
|
58
|
+
# painterly meadow; YOUR prompt comes from YOUR game's style brief):
|
|
59
|
+
npx genex image "windswept alpine meadow at golden hour, wildflowers leaning in the gusts, painterly light, cinematic wide shot. Edge-to-edge cinematic composition. Full-bleed 16:9 frame. No UI elements, no text, no buttons in the frame." --aspect 16:9 --quality high
|
|
60
|
+
# -> https://assets.genex.technology/generations/<id>/image-main
|
|
61
|
+
|
|
62
|
+
# 2. Animate it into a seamless loop (same image as first AND last frame).
|
|
63
|
+
# Enqueue in the background and keep building — video takes minutes:
|
|
64
|
+
npx genex video "grass and wildflowers sway and settle back, clouds drift and return, light shimmers" --frame https://assets.genex.technology/generations/<id>/image-main --duration 8 --no-wait
|
|
65
|
+
# -> Queued (<gen-id>)
|
|
66
|
+
|
|
67
|
+
# 3. Later — pick the finished loop up (safe to re-run; never creates a new one):
|
|
68
|
+
npx genex wait <gen-id>
|
|
69
|
+
# -> https://assets.genex.technology/generations/<gen-id>/video-mp4
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Work async — the menu must never block the game.** Generate the frame right
|
|
73
|
+
after the UI plan gate, enqueue the video with `--no-wait`, ship the CSS menu
|
|
74
|
+
(buttons + title over the frame IMAGE as a static backdrop), and swap the
|
|
75
|
+
`<video>` in when `genex wait` prints the URL. The frame image doubles as the
|
|
76
|
+
**loading screen background** — it exists minutes before the video does (see
|
|
77
|
+
`$genex-threejs-game-ui`'s loader spec). Both assets live in Genex storage
|
|
78
|
+
(R2) — permanent, public, CORS-open; you load them straight from the printed
|
|
79
|
+
URLs, nothing is downloaded or committed.
|
|
80
|
+
|
|
81
|
+
## Wire it as a phase screen
|
|
82
|
+
|
|
83
|
+
The menu is one `data-phase` screen in the `$genex-threejs-game-ui`
|
|
84
|
+
architecture (the `#ui` overlay + `setPhase()` state machine). Complete,
|
|
85
|
+
copy-pasteable example:
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<div id="ui">
|
|
89
|
+
<div id="screen-menu" class="screen" data-phase="menu">
|
|
90
|
+
<video class="menu-bg"
|
|
91
|
+
src="https://assets.genex.technology/generations/<id>/video-mp4"
|
|
92
|
+
autoplay muted loop playsinline></video>
|
|
93
|
+
<div class="menu-title stagger" style="--i: 0">EMBERFALL</div>
|
|
94
|
+
<button class="menu-btn stagger" id="menu-play" style="--i: 1; left: 38%; top: 52%; width: 24%; height: 8%;">PLAY</button>
|
|
95
|
+
<button class="menu-btn stagger" id="menu-options" style="--i: 2; left: 38%; top: 63%; width: 24%; height: 8%;">OPTIONS</button>
|
|
96
|
+
<button class="menu-btn stagger" id="menu-credits" style="--i: 3; left: 38%; top: 74%; width: 24%; height: 8%;">CREDITS</button>
|
|
97
|
+
<div class="menu-corner stagger" style="--i: 4">v1.0</div>
|
|
98
|
+
</div>
|
|
99
|
+
<!-- other .screen phases (playing HUD, pause, over) live beside it -->
|
|
100
|
+
</div>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```css
|
|
104
|
+
#screen-menu { position: absolute; inset: 0; overflow: hidden; background: #000; }
|
|
105
|
+
.menu-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
|
|
106
|
+
.menu-title {
|
|
107
|
+
position: absolute; left: 0; right: 0; top: 14%; text-align: center;
|
|
108
|
+
font-family: "Cinzel", serif; font-size: 9vh; color: #f4e3b8;
|
|
109
|
+
letter-spacing: 0.08em;
|
|
110
|
+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.85), 0 8px 32px rgba(0, 0, 0, 0.6);
|
|
111
|
+
pointer-events: none; /* the title is decor, NOT a button */
|
|
112
|
+
}
|
|
113
|
+
.menu-btn {
|
|
114
|
+
position: absolute; border: none; background: transparent; cursor: pointer;
|
|
115
|
+
font-family: "Cinzel", serif; font-size: 4vh; color: rgba(255, 255, 255, 0.92);
|
|
116
|
+
letter-spacing: 0.12em; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.9);
|
|
117
|
+
transition: transform 160ms ease, color 160ms ease, text-shadow 160ms ease;
|
|
118
|
+
}
|
|
119
|
+
/* ONE selected state serves mouse hover, keyboard focus, and gamepad alike. */
|
|
120
|
+
.menu-btn.is-selected, .menu-btn:hover, .menu-btn:focus-visible {
|
|
121
|
+
color: #fff; transform: translateX(0.4em) scale(1.04); outline: none;
|
|
122
|
+
text-shadow: 0 2px 6px rgba(0, 0, 0, 0.9), 0 0 22px rgba(255, 220, 150, 0.8);
|
|
123
|
+
}
|
|
124
|
+
.menu-btn.is-selected::before {
|
|
125
|
+
content: "❯"; position: absolute; left: -1.1em; opacity: 0.9;
|
|
126
|
+
}
|
|
127
|
+
.menu-btn:active { transform: translateX(0.4em) scale(0.97); }
|
|
128
|
+
.menu-corner {
|
|
129
|
+
position: absolute; right: 2%; bottom: 2%; font-size: 1.8vh;
|
|
130
|
+
color: rgba(255, 255, 255, 0.6); pointer-events: none;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* Entrance choreography — title first, buttons stagger in, corner last.
|
|
134
|
+
`.is-on` is toggled by setPhase() (see $genex-threejs-game-ui's Motion
|
|
135
|
+
section); each element stamps its own --i in the HTML above. */
|
|
136
|
+
.screen .stagger { opacity: 0; transform: translateY(12px);
|
|
137
|
+
transition: opacity 320ms ease, transform 320ms ease;
|
|
138
|
+
transition-delay: calc(var(--i, 0) * 70ms); }
|
|
139
|
+
.screen.is-on .stagger { opacity: 1; transform: none; }
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
// Buttons emit the SAME intents the gameplay input path uses — never a page reload.
|
|
144
|
+
document.getElementById("menu-play")!.addEventListener("click", () => setPhase("playing"));
|
|
145
|
+
document.getElementById("menu-options")!.addEventListener("click", () => setPhase("options"));
|
|
146
|
+
document.getElementById("menu-credits")!.addEventListener("click", () => setPhase("credits"));
|
|
147
|
+
|
|
148
|
+
// Menus are keyboard-first: ↑/↓ moves the selection, Enter activates.
|
|
149
|
+
// Mouse hover drives the SAME selection, so the chevron never disagrees.
|
|
150
|
+
const btns = [...document.querySelectorAll<HTMLButtonElement>("#screen-menu .menu-btn")];
|
|
151
|
+
let sel = 0;
|
|
152
|
+
function select(i: number): void {
|
|
153
|
+
sel = (i + btns.length) % btns.length;
|
|
154
|
+
btns.forEach((b, j) => b.classList.toggle("is-selected", j === sel));
|
|
155
|
+
}
|
|
156
|
+
btns.forEach((b, i) => b.addEventListener("mouseenter", () => select(i)));
|
|
157
|
+
select(0);
|
|
158
|
+
document.addEventListener("keydown", (e) => {
|
|
159
|
+
if (document.getElementById("screen-menu")!.hidden) return;
|
|
160
|
+
if (e.key === "ArrowDown") select(sel + 1);
|
|
161
|
+
else if (e.key === "ArrowUp") select(sel - 1);
|
|
162
|
+
else if (e.key === "Enter") btns[sel].click();
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Layout rules baked into the example:
|
|
167
|
+
|
|
168
|
+
- **`<video autoplay muted loop playsinline>`** — `muted` is what makes
|
|
169
|
+
autoplay legal before any user gesture (the menu IS the first screen);
|
|
170
|
+
`object-fit: cover` + `inset: 0` fills any viewport without letterboxing.
|
|
171
|
+
- **Normalized `%` boxes, kebab-case stable ids.** Buttons are absolutely
|
|
172
|
+
positioned with percentage boxes so the layout scales with the viewport.
|
|
173
|
+
- **The big title is NOT a button** — a top-center decorative element with
|
|
174
|
+
`pointer-events: none`. 3–4 action buttons stack below it; a small
|
|
175
|
+
version/handle string sits in a corner. Layered `text-shadow` beats
|
|
176
|
+
`-webkit-text-stroke` for weight (a heavy stroke reads as a browser game).
|
|
177
|
+
- **Everything enters choreographed** — nothing may simply appear. Title,
|
|
178
|
+
then buttons, then corner text, ~70 ms apart.
|
|
179
|
+
- **One visible selection at all times** (chevron + glow above), driven by
|
|
180
|
+
keyboard AND mouse through the same `select()`.
|
|
181
|
+
- Clicks route to `setPhase()` / game events — the menu renders game state,
|
|
182
|
+
it never owns a second copy of it.
|
|
183
|
+
|
|
184
|
+
## Menu sound
|
|
185
|
+
|
|
186
|
+
The video is necessarily muted, so an unwired menu is SILENT — that reads as
|
|
187
|
+
broken. Three `npx genex sfx` calls (see `$genex-ai-sfx`): a short hover tick
|
|
188
|
+
(wire to `select()`, quiet), a confirm on activate, and a low ambient loop
|
|
189
|
+
matching the scene (wind, surf, candle room tone) started on the first user
|
|
190
|
+
gesture (autoplay policy blocks earlier — a `click`/`keydown` once-listener).
|
|
191
|
+
|
|
192
|
+
## Pick the fonts
|
|
193
|
+
|
|
194
|
+
Match the display font to the genre and add its Google Fonts `<link>` to
|
|
195
|
+
`index.html` (otherwise the browser silently falls back to sans-serif and the
|
|
196
|
+
menu looks broken):
|
|
197
|
+
|
|
198
|
+
| Genre / mood | Display font | Body / small text |
|
|
199
|
+
| --- | --- | --- |
|
|
200
|
+
| Fantasy / RPG | Cinzel | EB Garamond |
|
|
201
|
+
| Sci-fi / racing | Orbitron or Russo One | Exo 2 |
|
|
202
|
+
| Military / action | Black Ops One | Oswald |
|
|
203
|
+
| Retro / 8-bit | Press Start 2P | VT323 |
|
|
204
|
+
| Sport / bold arcade | Anton | Barlow Condensed |
|
|
205
|
+
| Horror / typewriter | Special Elite | Courier Prime |
|
|
206
|
+
| Cozy / casual | Baloo 2 | Nunito |
|
|
207
|
+
| Painterly / adventure | IM Fell English | Crimson Text |
|
|
208
|
+
| Western / rustic | Rye | Bitter |
|
|
209
|
+
| Elegant / noir | Cormorant Garamond | Jost |
|
|
210
|
+
|
|
211
|
+
The table is a starting point, not a taxonomy — pick by the game's OWN
|
|
212
|
+
register, and browse Google Fonts' display category when none of these fits.
|
|
213
|
+
One display font + one body font per menu. Give text its own contrast against
|
|
214
|
+
the moving video — layered text-shadows or a subtle dark plate (avoid heavy
|
|
215
|
+
text strokes — they read as a browser game, not a title screen).
|
|
216
|
+
|
|
217
|
+
**Title treatment.** A bare display font is the floor, not the ceiling. Two
|
|
218
|
+
upgrades, in order of effort:
|
|
219
|
+
|
|
220
|
+
- **Layered CSS (free):** gradient ink via `background-clip: text` +
|
|
221
|
+
stacked shadows (a tight dark one for contrast, a wide soft one for glow).
|
|
222
|
+
- **A generated logotype (Tier 3 — offer it, don't pre-build):**
|
|
223
|
+
`npx genex image "the word 'EMBERFALL' as an ornate engraved game logo, <style brief>" --transparent`,
|
|
224
|
+
cleaned with `--bg-mode glyph` if letter counters get eaten, trimmed with
|
|
225
|
+
`npx genex ui trim`. Short names (one or two words) come out best.
|
|
226
|
+
|
|
227
|
+
## Tips
|
|
228
|
+
|
|
229
|
+
- **Subtle motion beats dramatic.** The clip loops forever — cinematic drift,
|
|
230
|
+
flicker, and weather read as alive; big camera moves and fast subjects make
|
|
231
|
+
the loop obvious and exhausting.
|
|
232
|
+
- **One menu = ONE video, generated one-off — not iteratively.** Video
|
|
233
|
+
generation is strictly rate-limited and takes minutes per attempt. Get the
|
|
234
|
+
still frame right first (images are cheap to redo), then animate it once.
|
|
235
|
+
- **720p is right.** It's a background under UI; higher resolutions cost more,
|
|
236
|
+
take longer, and change nothing visible.
|
|
237
|
+
- **Pause/victory/defeat variants reuse the same video — as GRADES.** Same
|
|
238
|
+
`<video>` element or URL, different emotion via CSS `filter` on the
|
|
239
|
+
background: pause = a plain dark overlay (`rgba(0,0,0,0.55)`); defeat =
|
|
240
|
+
`filter: saturate(0.25) brightness(0.55)` with a ~600 ms beat before the
|
|
241
|
+
buttons stagger in; victory = `filter: saturate(1.15) brightness(1.05)` with
|
|
242
|
+
the score counting up (tween ~800 ms, never snap). Zero extra generations,
|
|
243
|
+
three distinct moods.
|
|
244
|
+
- **Lobby screens:** matchmaking status and countdowns come from
|
|
245
|
+
`$genex-threejs-multiplayer` — render the roster and `players.length /
|
|
246
|
+
minPlayers` count over the same video, and drive the overlay's dismissal
|
|
247
|
+
from `mm.matchmaking.status` exactly as that skill mandates.
|
|
248
|
+
|
|
249
|
+
## Publish checklist
|
|
250
|
+
|
|
251
|
+
- The mp4 loads from the **URL** the command printed — permanent and CORS-open,
|
|
252
|
+
identical in local dev, the published game, and remixes. Nothing to commit.
|
|
253
|
+
- Don't copy the video into `public/assets/` — generated assets live in R2.
|
|
254
|
+
- Keep the `muted` attribute — without it, autoplay is blocked and the menu
|
|
255
|
+
opens on a black rectangle.
|
|
256
|
+
- The Google Fonts `<link>` lives in `index.html`, so it ships with the build.
|
|
257
|
+
|
|
258
|
+
## Options
|
|
259
|
+
|
|
260
|
+
- `--frame <url>` (video) — one R2 image URL used as both the first and last
|
|
261
|
+
frame: the seamless-loop mode. The URL must be one printed by `npx genex image`.
|
|
262
|
+
- `--first-frame <url>` / `--last-frame <url>` (video) — two-frame mode for a
|
|
263
|
+
genuine state change; expect a loop seam.
|
|
264
|
+
- `--duration <sec>` (video) — 4, 6, or 8 for frame-conditioned clips;
|
|
265
|
+
default 8.
|
|
266
|
+
- `--aspect 16:9 --quality high` (image) — the right settings for a menu frame.
|
|
267
|
+
- `--no-wait` — enqueue and return immediately with the generation id; pick
|
|
268
|
+
the result up later with `npx genex wait <id>` (safe to re-run — it attaches
|
|
269
|
+
to the SAME generation). The default for menu videos: build while it
|
|
270
|
+
renders. Re-running the GENERATE command, by contrast, creates (and bills)
|
|
271
|
+
a new one.
|
|
272
|
+
|
|
273
|
+
## Troubleshooting
|
|
274
|
+
|
|
275
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it
|
|
276
|
+
writes your `GENEX_TOKEN`).
|
|
277
|
+
- **"Prompt rejected"** — the provider's content-safety filter blocked the
|
|
278
|
+
prompt. Non-retryable; rewrite the wording.
|
|
279
|
+
- **Video takes minutes** — that's normal for video generation; enqueue with
|
|
280
|
+
`--no-wait` and keep building, then `npx genex wait <id>` for the URL.
|
|
281
|
+
Never re-run the generate command to "check on" a generation — every run
|
|
282
|
+
creates (and bills) a new video; only `genex wait` attaches to an existing
|
|
283
|
+
one.
|
|
284
|
+
- **The loop visibly "jumps"** — the motion prompt wasn't return-to-start
|
|
285
|
+
(or you used two-frame mode). Re-generate the video with cyclical motion
|
|
286
|
+
wording; the frame image can be reused as-is.
|
|
287
|
+
- **UI/text baked into the frame** — the frame prompt allowed it. Append the
|
|
288
|
+
"No UI elements, no text, no buttons in the frame." sentence and regenerate
|
|
289
|
+
the image.
|
|
290
|
+
- **Black screen instead of video** — the `muted` attribute is missing
|
|
291
|
+
(autoplay blocked), or the URL isn't the exact one the command printed.
|
|
@@ -12,7 +12,7 @@ or a video decal.
|
|
|
12
12
|
## When to use this vs. a static image or shader
|
|
13
13
|
|
|
14
14
|
- **Use `npx genex video`** for moving footage you can describe — "static-y CRT
|
|
15
|
-
news broadcast", "swirling
|
|
15
|
+
news broadcast", "swirling ink in water", "rain running down glass". You get a real
|
|
16
16
|
mp4.
|
|
17
17
|
- **Use `$genex-ai-image`** for a single still picture, or
|
|
18
18
|
`$genex-threejs-procedural-vfx` for parametric real-time effects (particles,
|
|
@@ -22,7 +22,7 @@ or a video decal.
|
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
npx genex video "<prompt>"
|
|
25
|
-
npx genex video "
|
|
25
|
+
npx genex video "drifting autumn leaves, seamless loop" --loop # seamless loop for screens/backdrops
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Video takes a **minute or two** end to end (queue + generation). If you're building
|
|
@@ -132,10 +132,17 @@ See `$genex-threejs-multiplayer` for the `shared` channel rules and the room API
|
|
|
132
132
|
- `--loop` — a seamless loop (for screens, ambient backdrops, video decals).
|
|
133
133
|
- `--duration <sec>` — clip length 1–15; default 5. Only raise it when the content
|
|
134
134
|
genuinely needs more — longer clips cost more and take longer.
|
|
135
|
-
- `--
|
|
136
|
-
|
|
135
|
+
- `--frame <url>` — one generated image as BOTH first and last frame — the
|
|
136
|
+
seamless-loop mode (motion must return to its start).
|
|
137
|
+
- `--first-frame <url>` / `--last-frame <url>` — two-frame motion between two
|
|
138
|
+
stills (a genuine state change; expect a loop seam).
|
|
139
|
+
- `--no-wait` — enqueue and return immediately, without the URL. Fire-and-forget
|
|
140
|
+
only: re-running the command creates (and bills) a NEW video.
|
|
137
141
|
- `--api-url <url>` — override the API base (local dev).
|
|
138
142
|
|
|
143
|
+
Menu backdrops belong to `$genex-ai-menu`; a cohesive art-directed HUD sprite
|
|
144
|
+
set belongs to `$genex-ai-hud` — both build on `npx genex image`/`video`.
|
|
145
|
+
|
|
139
146
|
## Troubleshooting
|
|
140
147
|
|
|
141
148
|
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
@@ -38,7 +38,7 @@ npx genex skybox "golden hour over mountains" # a 360° sky + lighting
|
|
|
38
38
|
npx genex sfx "punchy laser zap" --duration 2 # a sound effect (mp3)
|
|
39
39
|
npx genex texture "mossy cobblestone" --terrain # a tiling surface texture
|
|
40
40
|
npx genex image "vintage travel poster" # a picture (poster/sign/sprite/decal)
|
|
41
|
-
npx genex video "
|
|
41
|
+
npx genex video "waterfall mist drifting" --loop # a video clip (screen/backdrop)
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
(Run them inside your project — the `@genex-ai/cli-demo` dev dependency makes
|
|
@@ -46,7 +46,10 @@ npx genex video "swirling neon portal" --loop # a video clip (screen/backdrop)
|
|
|
46
46
|
|
|
47
47
|
Each has a focused skill with the exact loader code — `$genex-ai-model`,
|
|
48
48
|
`$genex-ai-skybox`, `$genex-ai-sfx`, `$genex-ai-texture`, `$genex-ai-image`,
|
|
49
|
-
`$genex-ai-video`.
|
|
49
|
+
`$genex-ai-video`. For generated game UI there are two workflow skills built
|
|
50
|
+
on the same commands: `$genex-ai-menu` (a cinematic menu — looping video
|
|
51
|
+
backdrop + DOM buttons) and `$genex-ai-hud` (a production HUD sprite set with
|
|
52
|
+
masked fills).
|
|
50
53
|
|
|
51
54
|
## Identity & saves (every game)
|
|
52
55
|
|