@genex-ai/cli-demo 0.90.0-dev.227 → 0.92.0-dev.229
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 +4 -1
- package/dist/index.js +598 -91
- package/package.json +1 -1
- package/templates/controllers/NOTICE.md +6 -4
- package/templates/controllers/character/player-character.ts +217 -0
- package/templates/skills/genex-ai-character/SKILL.md +91 -25
- package/templates/skills/genex-ai-character/references/motion-generation.md +125 -0
- package/templates/skills/genex-ai-image/SKILL.md +5 -1
- package/templates/skills/genex-ai-menu/SKILL.md +14 -6
- package/templates/skills/genex-ai-skybox/SKILL.md +19 -6
- package/templates/skills/genex-game-director/SKILL.md +29 -11
- package/templates/skills/genex-game-director/references/routing-map.md +4 -3
- package/templates/skills/genex-threejs-character-controller/SKILL.md +105 -52
- package/templates/skills/genex-threejs-character-controller/references/animations.md +62 -50
- package/templates/skills/genex-threejs-creatures/SKILL.md +14 -4
- package/templates/skills/genex-threejs-embed-auth/SKILL.md +5 -3
- package/templates/skills/genex-threejs-multiplayer/SKILL.md +10 -8
- package/templates/skills/genex-threejs-multiplayer/references/host-physics.md +8 -7
- package/templates/skills/genex-threejs-procedural-animation/SKILL.md +2 -2
- package/templates/skills/genex-ai-character/references/motion.md +0 -145
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
# Custom animations with `genex motion` — the full procedure
|
|
2
|
-
|
|
3
|
-
Text → raw motion takes on the platform GPU service → objective verify →
|
|
4
|
-
YOUR pick → local compile → a rig-independent set the vendored runtime plays
|
|
5
|
-
on any humanoid. The skeleton is a 27-joint humanoid core at 20 fps; takes
|
|
6
|
-
arrive as `.npz` files plus a machine verify report. Everything after `gen`
|
|
7
|
-
runs locally and free — regenerate compiled sets as often as you like.
|
|
8
|
-
|
|
9
|
-
**Rig limits (say them to the user before promising a move):** biped,
|
|
10
|
-
human-proportioned characters only. Rigs without finger bones (many Meshy
|
|
11
|
-
characters) cannot curl fingers around a grip — prefer weapon-carry looks
|
|
12
|
-
that read well with flat hands there, or use a rig with fingers for hero
|
|
13
|
-
characters. Takes are 2–10 seconds.
|
|
14
|
-
|
|
15
|
-
## The loop
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# 1. Generate (bills per take, default 4; ALWAYS --no-wait — jobs run minutes)
|
|
19
|
-
npx genex motion gen "soldier rifle low-ready idle, fully upright, head held high" --takes 4 --no-wait
|
|
20
|
-
npx genex wait <id> # prints one URL per take + the report
|
|
21
|
-
|
|
22
|
-
# 2. Download the takes it printed and RENAME them — filenames drive everything
|
|
23
|
-
mkdir -p takes && curl -o takes/rifle-idle.npz "<take-url>"
|
|
24
|
-
|
|
25
|
-
# 3. Verify locally (same math the service ran; free, reproducible)
|
|
26
|
-
npx genex motion verify takes/
|
|
27
|
-
|
|
28
|
-
# 4. Pick the takes whose MOTION reads right (the report is data, not taste),
|
|
29
|
-
# then compile the set
|
|
30
|
-
npx genex motion compile takes/ --out src/motion/rifle.json
|
|
31
|
-
|
|
32
|
-
# 5. Vendor the runtime once per game (+ the proven rifle starter set)
|
|
33
|
-
npx genex motion install --set rifle
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Take naming — the routing contract
|
|
37
|
-
|
|
38
|
-
`verify` and `compile` classify each take by its FILENAME stem. Rename
|
|
39
|
-
downloaded takes before running them:
|
|
40
|
-
|
|
41
|
-
| Stem pattern | Compiles into |
|
|
42
|
-
|---|---|
|
|
43
|
-
| `<set>-run-forward` / `-back` | `forward` / `back` gait |
|
|
44
|
-
| `<set>-strafe-left` / `-strafe-right` | `strafeLeft` / `strafeRight` |
|
|
45
|
-
| `<set>-run-fl` / `-fr` / `-bl` / `-br` | the four diagonal gaits |
|
|
46
|
-
| `<set>-idle` or `…stance…` | the `idle` loop |
|
|
47
|
-
| `…jump…` (`jump-stand`, `jump-run`) | `jumpStand` / `jumpRun` one-shots |
|
|
48
|
-
| anything else | a named freeform loop |
|
|
49
|
-
|
|
50
|
-
A stem containing `aim`, `rifle`, or `pistol` marks the take as a WEAPON
|
|
51
|
-
HOLD: verify adds the hold-shape gates, and compile grip-line-normalizes the
|
|
52
|
-
idle (the whole body blades as one) and plucks `aim0`/`aim0Up`/`aim0Dn`
|
|
53
|
-
upper-body mask poses from the hold takes.
|
|
54
|
-
|
|
55
|
-
## The prompt wording ladder (hard-won — wrong words cost paid takes)
|
|
56
|
-
|
|
57
|
-
- **Never ask for "sights" or a "cheek weld"** — you get a hunched
|
|
58
|
-
face-height hold that reads absurd on game rigs. Ask for the third-person
|
|
59
|
-
hold: *"weapon at chest height, arms extended"*, *"low-ready"* as the
|
|
60
|
-
fallback.
|
|
61
|
-
- **Always add "fully upright, head held high"** — the model's prior slouches.
|
|
62
|
-
- **Describe hand geometry literally** (*"left hand forward on the handguard,
|
|
63
|
-
right hand at the grip"*), not by weapon jargon.
|
|
64
|
-
- The model NEVER squares a two-handed hold to the pelvis — real marksmen
|
|
65
|
-
blade, and compile normalizes the heading by the grip line. Do not fight
|
|
66
|
-
it with prompt words; it is not a defect.
|
|
67
|
-
- **Gaits need constraints, not prose.** Direction words alone drift; pin
|
|
68
|
-
the trajectory:
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
npx genex motion constraints --dir strafe-left --speed 2.5 --duration 5 --out strafe-left.json
|
|
72
|
-
npx genex motion gen "soldier strafing with a rifle at low-ready" --constraints strafe-left.json --no-wait
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
The constraint pins the root path AND the heading (facing stays +Z) — that
|
|
76
|
-
pin is what makes a strafe a strafe. One direction per request; a full
|
|
77
|
-
8-direction set is 8 requests + one idle (run them in parallel with
|
|
78
|
-
`--no-wait`, like any batch).
|
|
79
|
-
|
|
80
|
-
## Verify semantics
|
|
81
|
-
|
|
82
|
-
`PASS` (≥70) / `WARN` (≥50) / `FAIL`, with a hard-zero cap: a zero on any
|
|
83
|
-
load-bearing gate fails the take no matter the average. The reasons column
|
|
84
|
-
names the defect in plain words (feet skate, grip line wanders, cheek weld…).
|
|
85
|
-
The report is DATA — freeform verbs have no semantic gate, so watch the take
|
|
86
|
-
on the rig before shipping it. Tune bands via `--gates gates.json` (partial
|
|
87
|
-
JSON, deep-merged: `{"aim": {"hunch": {"bad": 25}}}`).
|
|
88
|
-
|
|
89
|
-
## Compile semantics + tunables
|
|
90
|
-
|
|
91
|
-
Compile cuts loop cycles at left-foot strikes (gaits) or the best seam window
|
|
92
|
-
(idles), removes the linear trajectory (residual sway + full Y bob stay),
|
|
93
|
-
normalizes heading to +Z, phase-aligns gaits (frame 0 = left strike), and for
|
|
94
|
-
weapon holds levels the arm assembly, raises the gaze, clamps tall stances,
|
|
95
|
-
and yaws mask poses in the SPINE. All rigid whole-body/assembly operations —
|
|
96
|
-
no joint ever moves relative to another (the no-bake law; it is why compiled
|
|
97
|
-
sets survive retargeting). Every threshold lives in
|
|
98
|
-
`src/motion/motion.config.json` after install — pass `--config` to use it.
|
|
99
|
-
|
|
100
|
-
## Wiring the runtime
|
|
101
|
-
|
|
102
|
-
`genex motion install` puts the runtime IN YOUR GAME — `src/motion/rigs.js`
|
|
103
|
-
(both retarget formulas + the load-time normalizations), `anim-runtime.js`
|
|
104
|
-
(ClipSet/Animator/dir8Weights/aimMaskStep), `ik.js`, and the config. They are
|
|
105
|
-
yours: read them, tune them, the comments explain every formula. Load order
|
|
106
|
-
matters:
|
|
107
|
-
|
|
108
|
-
```js
|
|
109
|
-
import { loadRig, captureRestAnkle, reanchorFeet, groundCalibrate, curlFingers } from "./motion/rigs.js";
|
|
110
|
-
import { ClipSet, Animator, dir8Weights, aimMaskStep } from "./motion/anim-runtime.js";
|
|
111
|
-
|
|
112
|
-
const set = await (await fetch("./motion-sets/rifle.json")).json(); // copy sets where your bundler serves them
|
|
113
|
-
const rig = await loadRig("./assets/character.glb", set, modelFrame); // GLB or VRM — auto-detected
|
|
114
|
-
rig.computeCorrection();
|
|
115
|
-
const restAnkle = captureRestAnkle(rig, scene); // BIND pose, before any clip
|
|
116
|
-
reanchorFeet(rig, set, scene); // steep-boot fix — BEFORE ClipSet
|
|
117
|
-
const clipSet = new ClipSet(rig, set, set.gaits);
|
|
118
|
-
groundCalibrate(rig, clipSet, scene, restAnkle); // short-leg fix — AFTER ClipSet
|
|
119
|
-
curlFingers(rig, scene); // grips (no-op on finger-less rigs)
|
|
120
|
-
const anim = new Animator(clipSet);
|
|
121
|
-
|
|
122
|
-
// per frame: your input → blend weights; the mask follows the COMMAND magnitude
|
|
123
|
-
anim.setLoops({ idle: 1 - mag, ...dir8Weights(x, z, mag) }, dt);
|
|
124
|
-
maskW = aimMaskStep(maskW, { mag, grounded, pitch, dt });
|
|
125
|
-
anim.setMask("aim0", maskW, pitch / 0.6); // ±40° at pitch extremes
|
|
126
|
-
anim.update(dt);
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
- Physics owns the world transform: hips play LOCAL values only (residual
|
|
130
|
-
x/z + absolute y); your character root carries position + yaw.
|
|
131
|
-
- Jumps: `anim.playOneShot("jumpRun", { yCap: 0.1 })` — cap hips Y when the
|
|
132
|
-
physics capsule owns the jump, and gate the impulse on the clip's own
|
|
133
|
-
takeoff frame. The `--set rifle` install includes the shared jumps set;
|
|
134
|
-
merge it: `Object.assign(clipSet.tracks, new ClipSet(rig, jumps, jumps.gaits).tracks)`.
|
|
135
|
-
- The aim mask WINS over one-shots on masked bones — a jump keeps aiming.
|
|
136
|
-
- Standing aim = the UNMASKED bladed idle; the spine-yawed mask pose is only
|
|
137
|
-
for moving/airborne/pitched states. `aimMaskStep` already encodes this.
|
|
138
|
-
|
|
139
|
-
## Cost + discipline
|
|
140
|
-
|
|
141
|
-
Per-take billing (a 4-take request ≈ one model generation). One regenerate
|
|
142
|
-
per verb is a fair budget when takes fail the gates — reword with the ladder
|
|
143
|
-
above before spending again, and compare candidates from ONE batch first
|
|
144
|
-
(that is what `--takes 4` is for). Never re-run `motion gen` to "pick up" a
|
|
145
|
-
result — `genex wait <id>` re-attaches free.
|