@genex-ai/cli-demo 0.6.2 → 0.8.0

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/dist/index.js CHANGED
@@ -788,32 +788,71 @@ async function deployGame(sshUrl, opts, log) {
788
788
  return false;
789
789
  }
790
790
  const gitDir = await fs6.mkdtemp(path7.join(os2.tmpdir(), "genex-deploy-"));
791
- const gitEnv = { GIT_DIR: gitDir, GIT_WORK_TREE: siteDir };
791
+ const base = { GIT_DIR: gitDir };
792
+ const ident = {
793
+ GIT_AUTHOR_NAME: "genex",
794
+ GIT_AUTHOR_EMAIL: "agent@genex.local",
795
+ GIT_COMMITTER_NAME: "genex",
796
+ GIT_COMMITTER_EMAIL: "agent@genex.local"
797
+ };
798
+ const EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
792
799
  try {
793
- if ((await run("git", ["init", "-q"], gitEnv)).code !== 0) {
800
+ if ((await run("git", ["init", "-q"], base)).code !== 0) {
794
801
  log.warn("git init failed \u2014 the game was not pushed.");
795
802
  return false;
796
803
  }
797
- await run("git", ["add", "-A"], gitEnv);
798
- const tracked = await run("git", ["ls-files"], gitEnv);
799
- if (/(^|\/)genex_key(\.pub)?$/m.test(tracked.out)) {
804
+ await fs6.writeFile(
805
+ path7.join(gitDir, "info", "exclude"),
806
+ ["node_modules/", "dist/", ".git/", KEY_NAME, `${KEY_NAME}.pub`, ".genex/", ""].join("\n")
807
+ );
808
+ const stage = async (workTree, indexName) => {
809
+ const env = { ...base, GIT_WORK_TREE: workTree, GIT_INDEX_FILE: path7.join(gitDir, indexName) };
810
+ await run("git", ["add", "-A"], env);
811
+ const tracked = await run("git", ["ls-files"], env);
812
+ if (/(^|\/)genex_key(\.pub)?$/m.test(tracked.out)) throw new Error("KEY_STAGED");
813
+ if (!tracked.out.trim()) return null;
814
+ const tree = (await run("git", ["write-tree"], env)).out.trim();
815
+ return tree || null;
816
+ };
817
+ const commitTree = async (tree, message) => (await run("git", ["commit-tree", tree, "-m", message], { ...base, ...ident })).out.trim();
818
+ let mainTree;
819
+ try {
820
+ mainTree = await stage(siteDir, "index-main");
821
+ } catch {
800
822
  log.error(`Refusing to deploy: ${KEY_NAME} is staged. Add it to .gitignore and retry.`);
801
823
  return false;
802
824
  }
803
- const commit = await run(
804
- "git",
805
- ["-c", "user.email=agent@genex.local", "-c", "user.name=genex", "commit", "-q", "-m", "build"],
806
- gitEnv
807
- );
808
- if (commit.code !== 0 && !/nothing to commit/i.test(commit.out + commit.err)) {
825
+ if (!mainTree || mainTree === EMPTY_TREE) {
809
826
  log.warn("Nothing to commit \u2014 the build produced no files.");
810
827
  return false;
811
828
  }
829
+ await run("git", ["update-ref", "refs/heads/main", await commitTree(mainTree, "build")], base);
830
+ let pushSource = false;
831
+ if (siteDir !== cwd) {
832
+ try {
833
+ const srcTree = await stage(cwd, "index-source");
834
+ if (srcTree && srcTree !== EMPTY_TREE) {
835
+ await run("git", ["update-ref", "refs/heads/source", await commitTree(srcTree, "source")], base);
836
+ pushSource = true;
837
+ }
838
+ } catch {
839
+ log.dim(" (Couldn't publish source for remixing \u2014 the deploy key was in the way.)");
840
+ }
841
+ }
812
842
  log.step("Pushing your game over SSH\u2026");
813
- const push = await run("git", ["push", "-q", sshUrl, "+HEAD:main"], {
814
- ...gitEnv,
815
- GIT_SSH_COMMAND: `ssh -i ${keyPath} -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new`
816
- });
843
+ const refspecs = ["+refs/heads/main:main"];
844
+ if (pushSource) refspecs.push("+refs/heads/source:source");
845
+ const push = await run(
846
+ "git",
847
+ ["push", "-q", ...pushSource ? ["--atomic"] : [], sshUrl, ...refspecs],
848
+ {
849
+ ...base,
850
+ // Quote the key path: git splits GIT_SSH_COMMAND with shell-like rules, so a
851
+ // project folder with a space (e.g. "fly drone") otherwise breaks the `-i`
852
+ // argument and ssh fails with "Could not resolve hostname …".
853
+ GIT_SSH_COMMAND: `ssh -i "${keyPath}" -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new`
854
+ }
855
+ );
817
856
  if (push.code === 0) {
818
857
  log.success("Pushed.");
819
858
  if (opts.playUrl) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "0.6.2",
3
+ "version": "0.8.0",
4
4
  "description": "Set up your ~/.claude workspace, authorize, create a game project, generate AI assets, and publish (genex CLI).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,15 +1,16 @@
1
1
  # Genex workspace
2
2
 
3
- These files were installed into your `~/.claude` directory by `genex init`.
4
- They give your coding agent a starter workspace for making 3D games in the
5
- browser.
3
+ These files were installed by `genex init` into your coding agent's workspace
4
+ Claude Code (`~/.claude`), Codex (`~/.codex/skills`), and Cursor
5
+ (`~/.cursor/skills`), whichever it detected. They give your agent superpowers
6
+ for making 3D games in the browser.
6
7
 
7
8
  Genex is built around agent superpowers for browser games: Three.js skills,
8
- one-click publishing, multiplayer-ready architecture, and team workflows. The
9
- installed files are yours to edit, extend, and keep with each project.
9
+ one-click publishing, multiplayer-ready architecture, and team workflows.
10
10
 
11
- Existing files are never overwritten. Re-running `genex init` only adds files
12
- you do not already have.
11
+ Files whose names start with `genex-` are managed by Genex: re-running
12
+ `genex init` refreshes them to the latest version. Anything you add yourself is
13
+ never touched.
13
14
 
14
15
  - `skills/` - reusable Genex skills for 3D game creation.
15
16
  - `agents/` - example subagent definitions.
@@ -23,12 +23,14 @@ are never touched).
23
23
 
24
24
  Start with `$genex-threejs-skill-router` for broad game or graphics requests.
25
25
  It routes the agent to focused skills for cameras, procedural geometry,
26
- materials, atmosphere, water, VFX, post-processing, and visual validation.
26
+ materials, atmosphere, water, weather, VFX, post-processing, and visual
27
+ validation.
27
28
 
28
29
  ## Generating real assets
29
30
 
30
31
  Beyond procedural code, Genex can generate **real, AI-made assets** from a prompt
31
- and drop them into `./assets/` (committed when you publish):
32
+ and drop them into `public/assets/` (shipped with your published game; load them
33
+ as `./assets/...` — the `public/` prefix is stripped when served):
32
34
 
33
35
  ```bash
34
36
  npx genex model "weathered wooden barrel" # a 3D mesh (GLB)
@@ -43,18 +45,20 @@ npx genex texture "mossy cobblestone" --terrain # a tiling surface texture
43
45
  Each has a focused skill with the exact loader code — `$genex-ai-model`,
44
46
  `$genex-ai-skybox`, `$genex-ai-sfx`, `$genex-ai-texture`.
45
47
 
46
- Your existing files were left untouched. `genex init` only adds what is missing.
48
+ Your own files were left untouched. `genex init` only adds missing files and
49
+ refreshes the genex-owned ones.
47
50
 
48
51
  ## Re-running setup
49
52
 
50
- Safe to run any time; it never overwrites your files:
53
+ Safe to run any time genex-owned skills are refreshed to the latest version,
54
+ and your own files are never touched:
51
55
 
52
56
  ```bash
53
57
  npx @genex-ai/cli-demo@latest init
54
58
  ```
55
59
 
56
- Use `--force` only if you intentionally want to overwrite installed templates
57
- with the latest versions.
60
+ Use `--force` only if you intentionally want your own existing files overwritten
61
+ by the bundled templates too.
58
62
 
59
63
  ## Authorization
60
64
 
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: genex-threejs-precipitation-surfaces
3
+ description: Build coupled precipitation and weather-affected surfaces for Genex Three.js games. Use for falling snow, snow accumulation, model snow caps, rain, wet asphalt puddles, procedural ripple normals, splash flipbooks, rain streaks, shared weather envelopes, and surface wetness or coverage transitions.
4
+ ---
5
+
6
+ # Genex Three.js Precipitation Surfaces
7
+
8
+ Treat weather as a coupled event, particle, and surface-response system. Do not
9
+ add rain or snow particles that are visually disconnected from the ground.
10
+
11
+ ## Build order
12
+
13
+ ```text
14
+ weather envelope
15
+ -> falling precipitation volume
16
+ -> world/object surface mask
17
+ -> displaced or optical surface response
18
+ -> impact residue and splashes
19
+ -> shared lighting/post presentation
20
+ ```
21
+
22
+ Read [references/precipitation-surfaces.md](references/precipitation-surfaces.md)
23
+ for snow accumulation, object capping, wrapped precipitation volumes, wet
24
+ puddle masks, procedural ripple normals, splash placement, and debug outputs.
25
+
26
+ For the base ground surface under the wetness or snow (asphalt, dirt, stone),
27
+ generate a real texture with `npx genex texture` and load it via
28
+ `$genex-ai-texture`, then build the precipitation response on top of it.
29
+ Splash flipbook atlases and ripple normals stay procedural (for example a
30
+ canvas-drawn expanding-ring atlas) — they are not generated assets.
31
+
32
+ ## Required controls
33
+
34
+ - precipitation density and speed;
35
+ - wind direction and strength;
36
+ - shared weather progress or coverage;
37
+ - wetness, snow, or puddle mask threshold and softness;
38
+ - ripple or drift normal strength;
39
+ - surface roughness response;
40
+ - particle/splash opacity;
41
+ - debug modes for masks, normals, particles, and event progress.
42
+
43
+ ## Failure conditions
44
+
45
+ - falling precipitation ignores the wind or timing used by surface response;
46
+ - snow height and snow normals come from different fields;
47
+ - model snow sticks to vertical faces without an upward-facing filter;
48
+ - puddles only lower roughness without a mask, normal response, or ripples;
49
+ - splashes appear on downward or hidden faces;
50
+ - rain streaks allocate per drop or fail to wrap around the camera;
51
+ - temporal wetness is faked with unrelated time noise.
52
+
53
+ ## Routing boundary
54
+
55
+ Use `$genex-threejs-water-optics` for bounded pool simulation, caustics, Fresnel,
56
+ refraction, and Beer-Lambert water volumes. Use `$genex-threejs-procedural-vfx` for
57
+ general sparks, plasma, trails, and non-weather particles. Use
58
+ `$genex-threejs-temporal-surfaces` for screen-space touch history or frost clearing.
59
+ This skill owns precipitation events and the surfaces they visibly alter.
@@ -0,0 +1,181 @@
1
+ # Precipitation Surface Systems
2
+
3
+ Precipitation reads as real only when particles, surface masks, normals,
4
+ roughness, and impact residue share the same event state. The following
5
+ contracts describe two reusable families: snow accumulation and wet rain
6
+ puddles.
7
+
8
+ ## Contents
9
+
10
+ - Weather state contract
11
+ - Wrapped precipitation volume
12
+ - Snow accumulation contract
13
+ - Object snow capping
14
+ - Wet puddle contract
15
+ - Rain streaks and splashes
16
+ - Debug outputs
17
+ - Boundaries and failure modes
18
+
19
+ ## Weather state contract
20
+
21
+ Use a small shared state object for weather systems. The state is passed by
22
+ reference into both particles and surfaces.
23
+
24
+ ```js
25
+ const weather = {
26
+ uTime: { value: 0 },
27
+ uWind: { value: new THREE.Vector3(1.2, 0, 0.5) },
28
+ uProgress: { value: 0 },
29
+ };
30
+
31
+ function updateWeather(delta, target) {
32
+ weather.uTime.value += delta;
33
+ weather.uProgress.value = THREE.MathUtils.damp(
34
+ weather.uProgress.value,
35
+ target,
36
+ 0.9,
37
+ delta,
38
+ );
39
+ }
40
+ ```
41
+
42
+ Do not give rain particles one clock and puddle ripples another. Do not sample
43
+ wind in screen space for particles and world space for surfaces. The wind vector
44
+ is horizontal and is interpreted as world units per second for moving
45
+ precipitation, while scalar progress controls wetness or coverage.
46
+
47
+ ## Wrapped precipitation volume
48
+
49
+ A camera-centered volume avoids finite emitter edges. Each instance stores a
50
+ normalized spawn point and a random seed. The vertex shader turns that into a
51
+ world position and wraps all axes with `mod`.
52
+
53
+ ```glsl
54
+ vec3 origin = uCameraPos - vec3(vol.x * 0.5, vol.y * 0.4, vol.z * 0.5);
55
+ float speed = uSpeed * (0.6 + 0.7 * aRand);
56
+ vec3 base = aSeed * vol;
57
+ vec3 disp = vec3(uWind.x, -speed, uWind.z) * uTime + sway;
58
+ vec3 pos = mod(base + disp - origin, vol) + origin;
59
+ ```
60
+
61
+ For snow, use soft round camera-facing billboards with opacity around `0.9`,
62
+ flake radius around `0.07`, speed around `3.2`, and a horizontal sway near
63
+ `0.5`. For rain, use narrow vertical or uneven-capsule billboards and a faster
64
+ fall speed, commonly around `5` world units per second in an inspection-scale
65
+ scene.
66
+
67
+ ## Snow accumulation contract
68
+
69
+ Ground snow needs one height function. The same function displaces vertices and
70
+ feeds finite-difference normals.
71
+
72
+ ```glsl
73
+ float snowMaskAt(vec2 worldXZ) {
74
+ vec2 p = worldXZ * uSnowScale + uSnowSeed;
75
+ float n = fbm(p) * 0.5 + 0.5;
76
+ float threshold = 1.0 - uSnowCoverage;
77
+ return smoothstep(threshold - uSnowEdge, threshold + uSnowEdge, n);
78
+ }
79
+
80
+ float snowHeightAt(vec2 worldXZ) {
81
+ float mask = snowMaskAt(worldXZ);
82
+ float drift = fbm(worldXZ * uSnowBumpScale) * 0.5 + 0.5;
83
+ float h = mask * (1.0 - 0.4 * uSnowBumpStrength +
84
+ 0.4 * uSnowBumpStrength * drift);
85
+ vec2 edge = smoothstep(10.0, 8.0, abs(worldXZ));
86
+ return uSnowDepth * h * edge.x * edge.y;
87
+ }
88
+
89
+ vec3 groundSurfaceNormal(vec2 worldXZ) {
90
+ float e = 0.08;
91
+ float h0 = snowHeightAt(worldXZ);
92
+ float hx = snowHeightAt(worldXZ + vec2(e, 0.0));
93
+ float hz = snowHeightAt(worldXZ + vec2(0.0, e));
94
+ vec2 grad = vec2(hx - h0, hz - h0) / e;
95
+ return normalize(vec3(-grad.x, 1.0, -grad.y));
96
+ }
97
+ ```
98
+
99
+ The snow material response should override albedo toward a cool white, push
100
+ roughness to roughly `0.82`, and add sparse sparkle only inside the snow mask.
101
+ The sparkle is a material response, not a separate particle layer.
102
+
103
+ ## Object snow capping
104
+
105
+ Object snow must be model-locked. Compute a world-to-model matrix for the host
106
+ object and sample coverage in that coordinate space so moving or rotating the
107
+ object does not slide the snow pattern.
108
+
109
+ ```glsl
110
+ float snowAccumAt(vec3 worldNormal, vec2 modelXZ) {
111
+ float up = clamp(worldNormal.y, 0.0, 1.0);
112
+ float top = smoothstep(uSnowFlatThreshold, 1.0, up);
113
+ return top * snowCoverageMask(modelXZ);
114
+ }
115
+ ```
116
+
117
+ Typical controls are `uSnowFlatThreshold = 0.35`, `uSnowThickness = 0.06`,
118
+ `uSnowCoverage = 0.7`, and `uSnowEdge = 0.15`. Displace along the object normal
119
+ but convert from world units to local units using the mapped normal length.
120
+
121
+ ## Wet puddle contract
122
+
123
+ Wet asphalt is a material transition driven by rain progress. Use separate
124
+ progress bands: roughness changes early, ripple normals arrive as the rain
125
+ becomes heavy.
126
+
127
+ ```glsl
128
+ float roughnessProgress = smoothstep(0.0, 0.75, uRainFactor);
129
+ float normalProgress = smoothstep(0.75, 1.0, uRainFactor);
130
+ float puddleNoise = getPuddle(vPosition.xy * 15.0);
131
+ float puddleMask = smoothstep(0.0, 1.0, puddleNoise) * normalProgress;
132
+ ```
133
+
134
+ The puddle roughness is intentionally collapsed toward the `0.0..0.1` range
135
+ inside the mask. Ripple normals are analytic: every local cell emits expanding
136
+ rings with finite-difference slope estimation. Keep the ripple normal separate
137
+ from the static asphalt normal until the final normal handoff.
138
+
139
+ ## Rain streaks and splashes
140
+
141
+ Rain streaks can be instanced quads. Their fragment shape may use an uneven
142
+ capsule SDF and alpha around `0.1 * rainProgress`. Splash placement should use
143
+ surface sampling weighted by upward normals.
144
+
145
+ ```js
146
+ const skyWeight = normal.dot(new THREE.Vector3(0, 1, 0)) >= 0 ? 1 : 0;
147
+ geometry.setAttribute("skyWeight", new THREE.BufferAttribute(weights, 1));
148
+ sampler.setWeightAttribute("skyWeight");
149
+ ```
150
+
151
+ Each splash instance owns a progress attribute. A flipbook shader maps progress
152
+ to a tile in a `4 x 5` atlas, fades by rain progress, and uses additive
153
+ blending. The splash mesh should face the camera around Y.
154
+
155
+ ## Debug outputs
156
+
157
+ Expose at least:
158
+
159
+ - `final`: complete weather and surface response;
160
+ - `mask`: snow or puddle coverage only;
161
+ - `normals`: accumulated snow normal or ripple normal;
162
+ - `particles`: precipitation density and fall volume;
163
+ - `progress`: shared rain or snow envelope.
164
+
165
+ Diagnostics should report active instance count, coverage, and whether the
166
+ surface response is reading the same time/wind uniforms as particles.
167
+
168
+ ## Boundaries and failure modes
169
+
170
+ Use a water-volume skill when the system needs refraction through a bounded
171
+ water body, caustics, or Beer-Lambert thickness. Use a general VFX skill for
172
+ non-weather particles. Use a screen-space temporal-surface skill for touch
173
+ history, not for world-space wetness.
174
+
175
+ Known failure modes:
176
+
177
+ - snow silhouettes rise but normals stay flat;
178
+ - object snow uses world coordinates and slides under animation;
179
+ - puddle masks are independent of roughness and normal changes;
180
+ - splashes sample all triangles and appear under objects;
181
+ - rain progress affects particles but not the material, or the reverse.
@@ -29,7 +29,8 @@ Read [references/architecture-systems.md](references/architecture-systems.md) be
29
29
  - Compile by material slot to reduce draw calls without destroying material separation.
30
30
  - Preserve real dimensions for floor height, bay width, trim projection, and texture density.
31
31
  - Randomness may select among valid designs; it must not repair invalid geometry.
32
- - Provide topology, placement, material-slot, and UV-density debug modes.
32
+ - Provide topology, façade ownership, material/geometry, and shadow diagnostics
33
+ appropriate to the renderer path.
33
34
 
34
35
  ## Acceptance
35
36
 
@@ -73,7 +73,7 @@ Seeded randomness perturbs constrained decisions:
73
73
 
74
74
  ```text
75
75
  towerScale = clamp(
76
- authoredTowerScale + random(-0.05, 0.04),
76
+ settings.towerScale + random(-0.05, 0.04),
77
77
  0.62,
78
78
  0.96
79
79
  )
@@ -43,11 +43,6 @@ Read [references/field-systems.md](references/field-systems.md)
43
43
  before implementation. It records sphere, terrain, water, and
44
44
  structured-placement field contracts plus common parity defects.
45
45
 
46
- Read the
47
- [procedural planet surface](../threejs-procedural-planets/examples/procedural-planet-surface/planet-system.js)
48
- for a shared CPU/GLSL field bundle whose height, continents, climate, biomes,
49
- roughness, and normals remain independently inspectable.
50
-
51
46
  ## Non-negotiable rules
52
47
 
53
48
  - Independent noise per channel produces visual soup. Share structure.
@@ -21,11 +21,6 @@ Read [references/mesh-systems.md](references/mesh-systems.md)
21
21
  for the exact sculpted-frame profile, rail emission, tree rings, semantic mesh
22
22
  writer, and their observed scaling limits.
23
23
 
24
- Read the
25
- [authored financial tower compiler](../threejs-procedural-architecture/examples/authored-financial-tower/building-system.js)
26
- for semantic placement compilation and material-slot instancing at building
27
- scale.
28
-
29
24
  ## Failure conditions
30
25
 
31
26
  - profile orientation flips along a curve;
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: genex-threejs-procedural-materials
3
- description: Author production procedural materials for Genex Three.js games. Use for PBR identity, terrain materials, atlas filtering, specular anti-aliasing, wetness, biome surfaces, dissolves, procedural normals, roughness variation, and readable materials across gameplay distances.
3
+ description: Author production procedural materials for Genex Three.js games. Use for PBR identity, terrain materials, atlas filtering, specular anti-aliasing, wetness, lava and hot emissive surfaces, raymarched material fields, biome surfaces, dissolves, procedural normals, roughness variation, and readable materials across gameplay distances.
4
4
  ---
5
5
 
6
6
  # Genex Three.js Procedural Materials
@@ -23,21 +23,6 @@ Read [references/material-systems.md](references/material-systems.md)
23
23
  for atlas filtering, specular AA, planetary coordinates,
24
24
  world-height wetness, per-instance dissolve, and authored PBR response bundles.
25
25
 
26
- Read the
27
- [sculpted gallery frame geometry](../threejs-procedural-geometry/examples/sculpted-gallery-frame/frame-geometry.js)
28
- for walnut, antique-gold, and ebony texture/roughness/metalness/clearcoat
29
- bundles under a grazing-light setup.
30
-
31
- Read the
32
- [procedural planet surface](../threejs-procedural-planets/examples/procedural-planet-surface/planet-system.js)
33
- for shared geological, climate, water, biome, roughness, and derivative-normal
34
- causes on a procedural planetary surface.
35
-
36
- Read the
37
- [analytic wave optics](../threejs-water-optics/examples/analytic-wave-optics/water-system.js)
38
- for coupled reflection, refraction, absorption, filtered microstructure,
39
- resolved crest response, and their diagnostic channels.
40
-
41
26
  ## Required controls
42
27
 
43
28
  - real or perceptual texture scale;
@@ -46,7 +31,7 @@ resolved crest response, and their diagnostic channels.
46
31
  - the causal fields required by the selected material pattern;
47
32
  - distance/derivative filtering;
48
33
  - specular antialiasing;
49
- - channel and mask debug modes.
34
+ - channel and mask debug modes;
50
35
  - emissive-material debug modes when the material owns glow or volumetric
51
36
  accumulation.
52
37
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: genex-threejs-procedural-vegetation
3
- description: Generate procedural vegetation for Genex Three.js games. Use for trees, trunks, roots, recursive branches, canopies, leaf cards, grass clumps, species presets, deterministic variation, growth forces, wind deformation, and vegetation that supports navigation or scene readability.
3
+ description: Generate procedural vegetation for Genex Three.js games. Use for trees, trunks, roots, recursive branches, canopies, leaf cards, stylized meadow grass, GPU-computed grass fields, grass clumps, species presets, deterministic variation, growth forces, rooted blade and leaf wind, wind deformation, and vegetation that supports navigation or scene readability.
4
4
  ---
5
5
 
6
6
  # Genex Three.js Procedural Vegetation
@@ -24,10 +24,20 @@ Represent a plant as a growth hierarchy plus rendering adaptations. Do not model
24
24
 
25
25
  Read [references/vegetation-systems.md](references/vegetation-systems.md) and preserve its preset, continuation, child-placement, leaf, material, wind, and composition contracts before tuning.
26
26
 
27
+ ## Grass fields
28
+
29
+ Grass is either instanced blade clusters (per-instance origin, facing, and
30
+ height, with circular-arc rooted wind that bends blades from the ground up) or
31
+ GPU-generated blade fields (blades written in render targets with Voronoi clump
32
+ variation, folded blade curvature, and distance-based density falloff). Both
33
+ keep terrain height and clump identity as shared causes; scattering blades with
34
+ uniform randomness produces lawn noise, not a meadow.
35
+
27
36
  ## Visual failure conditions
28
37
 
29
38
  - branches form visible helices;
30
39
  - every child emerges at the same relative height;
40
+ - dense grass ignores terrain height or clump-level variation;
31
41
  - bark texture scale changes with branch radius;
32
42
  - leaves reveal flat card normals under rotation;
33
43
  - leaf wind moves card roots instead of remaining anchored;
@@ -35,5 +35,7 @@ spark/debris pools, HDR hierarchy, and implementation limits.
35
35
  ## Routing boundary
36
36
 
37
37
  Use `$genex-threejs-temporal-surfaces` only for the screen-space
38
- frost/touch-history pipeline. Keep ship-space plasma, generated wakes, sparks,
38
+ frost/touch-history pipeline. Use `$genex-threejs-precipitation-surfaces` for
39
+ falling rain or snow, splash flipbooks, and weather events that alter ground
40
+ materials. Keep ship-space plasma, generated wakes, sparks,
39
41
  and pooled debris in this skill.
@@ -19,11 +19,6 @@ Use a single shadow map only when its receiver region is genuinely bounded. For
19
19
 
20
20
  Read [references/shadow-systems.md](references/shadow-systems.md) before implementing a large-world directional light.
21
21
 
22
- Read the
23
- [cached shadow clipmaps](../threejs-procedural-architecture/examples/authored-financial-tower/shadow-clipmaps.js)
24
- for three light-space square levels, per-level texel snapping, containment
25
- cross-fades, cached coarse updates, scaled bias, and unshadowed outside weight.
26
-
27
22
  ## Failure conditions
28
23
 
29
24
  - projection centers move by fractions of a texel;
@@ -20,13 +20,14 @@ map, execution order, and acceptance gate.
20
20
  | reusable scalar/vector fields, domain warping, causal masks, procedural normals | `$genex-threejs-procedural-fields` |
21
21
  | atlas-filtered blocks, planetary surfaces, terrain wetness, lava/emissive procedural surfaces, authored frame PBR, specular AA | `$genex-threejs-procedural-materials` |
22
22
  | sculpted rails/frames, branch rings, semantic mesh writers, material groups | `$genex-threejs-procedural-geometry` |
23
- | trees, stylized grass, branching organisms, roots, foliage, rooted wind deformation | `$genex-threejs-procedural-vegetation` |
23
+ | trees, stylized grass, GPU-computed grass fields, branching organisms, roots, foliage, rooted wind deformation | `$genex-threejs-procedural-vegetation` |
24
24
  | buildings, façade grammars, profiles, ornaments, modular mesh writers | `$genex-threejs-procedural-architecture` |
25
25
  | planets, terrain, craters, biome fields, coastlines, spherical detail | `$genex-threejs-procedural-planets` |
26
26
  | sky scattering, planetary shells, depth-based aerial perspective | `$genex-threejs-atmosphere-aerial-perspective` |
27
27
  | weather-driven raymarched clouds and cloud shadows | `$genex-threejs-volumetric-clouds` |
28
28
  | FFT oceans, hybrid FFT/Gerstner clear water, stylized above/below ocean optics, spectral cascades, choppy derivatives, Jacobian whitecaps | `$genex-threejs-spectral-ocean` |
29
29
  | authored analytic waves, bounded heightfield pools, object ripples, differential-area caustics, ray-traced pool volume optics, shared normals, heuristic refraction, fallback absorption, crest foam | `$genex-threejs-water-optics` |
30
+ | falling snow, snow accumulation, model snow caps, wet asphalt puddles, procedural ripple normals, splash flipbooks, rain streaks, shared weather envelopes, surface wetness | `$genex-threejs-precipitation-surfaces` |
30
31
  | curved-ray black holes, accretion disks, wormholes | `$genex-threejs-raymarched-space-effects` |
31
32
  | particles, trails, plasma, shockwaves, layered event effects | `$genex-threejs-procedural-vfx` |
32
33
  | accumulated screen frost, touch clearing, reduced blur, and refraction masks | `$genex-threejs-temporal-surfaces` |
@@ -48,7 +49,9 @@ When the user wants a **specific, recognizable asset** (a named object, a descri
48
49
  sky, a particular sound or surface) rather than something authored in code, generate
49
50
  it with an `npx genex` command (run inside the project, where the `@genex-ai/cli-demo`
50
51
  dev dependency makes `genex` resolve to the right CLI). Each drops a real file into
51
- `./assets/` (committed by `npx genex publish`), and its skill has the exact Three.js
52
+ `public/assets/<kind>/` so it ships with the built game load it at runtime as
53
+ `./assets/...` (the `public/` prefix is stripped when served; a bare `./assets/` dir
54
+ would be dropped from the production build). Each skill has the exact Three.js
52
55
  loader code.
53
56
 
54
57
  | Work needed | Generate with | Skill |
@@ -18,7 +18,7 @@ Three.js release or branch, and do not blindly copy demo architecture.
18
18
  1. Define the game contract: player verb, win/interaction loop, target device,
19
19
  camera distance, scene scale, motion, and frame budget.
20
20
  2. Select the minimum scene-generation skills: geometry, materials, vegetation,
21
- architecture, planets, water, clouds, or VFX.
21
+ architecture, planets, water, precipitation, clouds, or VFX.
22
22
  3. Add camera direction when framing, controls, transitions, or scale perception
23
23
  affect play.
24
24
  4. Add procedural animation when object motion needs authored phases,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: genex-threejs-spectral-ocean
3
- description: Build large procedural oceans for Genex Three.js games. Use for FFT-style wave spectra, multi-cascade wave bands, choppy displacement, derivatives, whitecaps, temporal foam, ocean shading, camera-scale transitions, and GPU-budgeted open-water scenes.
3
+ description: Build large procedural oceans for Genex Three.js games. Use for FFT-style wave spectra, multi-cascade wave bands, hybrid FFT plus Gerstner clear water, stylized above/below-surface ocean optics, choppy displacement, derivatives, Jacobian whitecaps, temporal foam, underwater absorption, crest scatter, ocean shading, camera-scale transitions, and GPU-budgeted open-water scenes.
4
4
  ---
5
5
 
6
6
  # Genex Three.js Spectral Ocean
@@ -22,6 +22,16 @@ Treat an ocean as a sampled stochastic wave field with explicit frequency-space
22
22
 
23
23
  Read [references/spectral-ocean.md](references/spectral-ocean.md) before implementing or auditing a spectral ocean.
24
24
 
25
+ ## Hybrid and stylized variants
26
+
27
+ For clear shallow water, a hybrid ocean may add a few authored Gerstner swells on
28
+ top of the FFT cascades — never instead of them — with Beer–Lambert depth color,
29
+ sand-bed caustics, and sharp sun highlights. A stylized ocean meant to be seen
30
+ from above and below can drive color from height gradients, add sun-path glints
31
+ and crest scatter, and composite an underwater Beer–Lambert tint from scene
32
+ depth. Both variants keep the spectral core, its derivatives, and Jacobian foam
33
+ as the single source of surface truth.
34
+
25
35
  ## Non-negotiable gates
26
36
 
27
37
  - Require a power-of-two grid and a passing FFT impulse/frequency test.
@@ -36,4 +36,6 @@ coupling, and implementation defects that must be corrected.
36
36
  ## Routing boundary
37
37
 
38
38
  Use `$genex-threejs-procedural-vfx` for world- or object-space residue, particles, and
39
- dissolves. This skill owns screen-space persistent history and its composite.
39
+ dissolves. Use `$genex-threejs-precipitation-surfaces` for rain wetness, puddles,
40
+ snow accumulation, and weather-surface coupling in world space. This skill owns
41
+ screen-space persistent history and its composite.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: genex-threejs-water-optics
3
- description: Build analytic water surfaces for Genex Three.js games. Use for rivers, pools, lakes, shoreline water, shared wave displacement, normals, Fresnel, refraction, absorption, crest foam, underwater color, and cheaper water than a full spectral ocean.
3
+ description: Build analytic water surfaces for Genex Three.js games. Use for rivers, pools, lakes, shoreline water, bounded heightfield pool simulation, object-driven ripples, differential-area caustics, ray-traced pool volume optics, shared wave displacement, normals, Fresnel, refraction, absorption, crest foam, underwater color, and cheaper water than a full spectral ocean.
4
4
  ---
5
5
 
6
6
  # Genex Three.js Water Optics
@@ -25,6 +25,16 @@ Read [references/water-optics.md](references/water-optics.md)
25
25
  for the exact five-wave displaced ocean, six-band normal-only water, optical
26
26
  hierarchy, and the limits that distinguish both from the spectral-ocean skill.
27
27
 
28
+ ## Bounded pool volumes
29
+
30
+ A bounded pool couples a small RGBA heightfield simulation (height and velocity,
31
+ with local drop injection and moving-object displacement) with the optical
32
+ layer: normals derive from the simulated heights and feed differential-area
33
+ caustics on the pool floor, and the water volume is shaded by ray-tracing
34
+ against the pool bounds. Keep the simulation, the normal derivation, and the
35
+ caustics reading the same field — a caustic pattern detached from the simulated
36
+ surface is a failure condition below.
37
+
28
38
  ## Failure conditions
29
39
 
30
40
  - normal texture motion does not agree with displaced crests;
@@ -40,6 +50,8 @@ hierarchy, and the limits that distinguish both from the spectral-ocean skill.
40
50
  ## Routing boundary
41
51
 
42
52
  Use `$genex-threejs-spectral-ocean` for stochastic directional spectra, FFT
43
- cascades, Jacobian breaking, and persistent ocean foam. This skill owns
53
+ cascades, Jacobian breaking, and persistent ocean foam. Use
54
+ `$genex-threejs-precipitation-surfaces` for rain-driven puddle wetness, ripple
55
+ masks, and weather-coupled splashes on ground surfaces. This skill owns
44
56
  authored analytic waves, bounded heightfield simulation, ray-traced
45
57
  pool-volume optics, and bounded-water optics.