@genex-ai/cli-demo 0.93.0 → 0.94.0-dev.249
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 +26 -5
- package/package.json +1 -1
- package/templates/skills/genex-ai-model/SKILL.md +3 -2
- package/templates/skills/genex-ai-skybox/SKILL.md +4 -4
- package/templates/skills/genex-ai-texture/SKILL.md +1 -1
- package/templates/skills/genex-ai-video/SKILL.md +1 -1
- package/templates/skills/genex-game-director/SKILL.md +321 -411
- package/templates/skills/genex-game-director/references/design-contract.md +130 -179
- package/templates/skills/genex-game-director/references/routing-map.md +242 -362
- package/templates/skills/genex-getting-started/SKILL.md +2 -2
- package/templates/skills/genex-threejs-exposure-color-grading/SKILL.md +3 -7
- package/templates/skills/genex-threejs-multiplayer/SKILL.md +19 -2
- package/templates/skills/genex-threejs-procedural-assets/SKILL.md +112 -0
- package/templates/skills/genex-threejs-procedural-materials/SKILL.md +3 -7
- package/templates/skills/genex-threejs-procedural-vfx/SKILL.md +6 -11
- package/templates/skills/genex-threejs-shadow-systems/SKILL.md +2 -3
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +0 -4
- package/templates/skills/genex-updates/SKILL.md +1 -1
- package/templates/skills/genex-threejs-atmosphere-aerial-perspective/SKILL.md +0 -46
- package/templates/skills/genex-threejs-atmosphere-aerial-perspective/references/atmosphere.md +0 -213
- package/templates/skills/genex-threejs-bloom/SKILL.md +0 -44
- package/templates/skills/genex-threejs-bloom/references/bloom.md +0 -187
- package/templates/skills/genex-threejs-exposure-color-grading/references/exposure-grading.md +0 -205
- package/templates/skills/genex-threejs-game-content/SKILL.md +0 -198
- package/templates/skills/genex-threejs-game-content/references/content-tables.md +0 -269
- package/templates/skills/genex-threejs-image-pipeline/SKILL.md +0 -56
- package/templates/skills/genex-threejs-image-pipeline/references/image-pipeline.md +0 -197
- package/templates/skills/genex-threejs-lighting-design/SKILL.md +0 -144
- package/templates/skills/genex-threejs-lighting-design/references/light-recipes.md +0 -137
- package/templates/skills/genex-threejs-open-world/SKILL.md +0 -149
- package/templates/skills/genex-threejs-open-world/references/terrain-streaming.md +0 -215
- package/templates/skills/genex-threejs-precipitation-surfaces/SKILL.md +0 -59
- package/templates/skills/genex-threejs-precipitation-surfaces/references/precipitation-surfaces.md +0 -181
- package/templates/skills/genex-threejs-procedural-architecture/SKILL.md +0 -50
- package/templates/skills/genex-threejs-procedural-architecture/references/architecture-systems.md +0 -509
- package/templates/skills/genex-threejs-procedural-fields/SKILL.md +0 -61
- package/templates/skills/genex-threejs-procedural-fields/references/field-systems.md +0 -232
- package/templates/skills/genex-threejs-procedural-geometry/SKILL.md +0 -39
- package/templates/skills/genex-threejs-procedural-geometry/references/mesh-systems.md +0 -202
- package/templates/skills/genex-threejs-procedural-materials/references/material-systems.md +0 -198
- package/templates/skills/genex-threejs-procedural-planets/SKILL.md +0 -48
- package/templates/skills/genex-threejs-procedural-planets/references/planet-systems.md +0 -498
- package/templates/skills/genex-threejs-procedural-vegetation/SKILL.md +0 -52
- package/templates/skills/genex-threejs-procedural-vegetation/references/vegetation-systems.md +0 -314
- package/templates/skills/genex-threejs-procedural-vfx/references/vfx-systems.md +0 -218
- package/templates/skills/genex-threejs-raymarched-space-effects/SKILL.md +0 -37
- package/templates/skills/genex-threejs-raymarched-space-effects/references/space-effects.md +0 -194
- package/templates/skills/genex-threejs-screen-space-ambient-occlusion/SKILL.md +0 -35
- package/templates/skills/genex-threejs-screen-space-ambient-occlusion/references/ambient-occlusion.md +0 -441
- package/templates/skills/genex-threejs-spectral-ocean/SKILL.md +0 -52
- package/templates/skills/genex-threejs-spectral-ocean/references/spectral-ocean.md +0 -473
- package/templates/skills/genex-threejs-temporal-surfaces/SKILL.md +0 -41
- package/templates/skills/genex-threejs-temporal-surfaces/references/temporal-surfaces.md +0 -207
- package/templates/skills/genex-threejs-visual-validation/references/visual-validation.md +0 -427
- package/templates/skills/genex-threejs-volumetric-clouds/SKILL.md +0 -49
- package/templates/skills/genex-threejs-volumetric-clouds/references/volumetric-clouds.md +0 -579
- package/templates/skills/genex-threejs-water-optics/SKILL.md +0 -57
- package/templates/skills/genex-threejs-water-optics/references/water-optics.md +0 -195
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
# HDR bloom systems
|
|
2
|
-
|
|
3
|
-
Use this reference to choose bloom ownership, signal order, selective contribution, and scene-relative emissive ranges without making bloom responsible for the underlying form.
|
|
4
|
-
|
|
5
|
-
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project. Either way the effect obeys the device tier (`$genex-threejs-adaptive-quality`): expensive passes are desktop-tier, and on WebGPU the per-target MSAA sample count is a runtime knob the governor may drive.
|
|
6
|
-
|
|
7
|
-
## Contents
|
|
8
|
-
|
|
9
|
-
- production WebGPU pipeline signal order
|
|
10
|
-
- production WebGPU pipeline bloom controls
|
|
11
|
-
- selective gallery pipeline selective ownership
|
|
12
|
-
- Material substitution invariant
|
|
13
|
-
- atlas-based renderer baseline
|
|
14
|
-
- pooled VFX system HDR hierarchy
|
|
15
|
-
- Implementation limits
|
|
16
|
-
- Diagnostics
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
## production WebGPU pipeline signal order
|
|
20
|
-
|
|
21
|
-
The WebGPU pipeline owns bloom before exposure and render output:
|
|
22
|
-
|
|
23
|
-
```text
|
|
24
|
-
scene pass
|
|
25
|
-
-> optional GTAO composite
|
|
26
|
-
-> optional atmosphere
|
|
27
|
-
-> bloom node
|
|
28
|
-
-> sampled scene + bloom
|
|
29
|
-
-> eye-adaptation exposure
|
|
30
|
-
-> renderOutput / tone map
|
|
31
|
-
-> optional 3D LUT
|
|
32
|
-
-> optional FXAA
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The render pipeline disables its automatic output color transform and assigns
|
|
36
|
-
one final output node. Preserve this one-owner rule when adapting to current
|
|
37
|
-
Three.js `RenderPipeline`.
|
|
38
|
-
|
|
39
|
-
## production WebGPU pipeline bloom controls
|
|
40
|
-
|
|
41
|
-
Bloom defaults:
|
|
42
|
-
|
|
43
|
-
```text
|
|
44
|
-
enabled = false
|
|
45
|
-
strength = 0
|
|
46
|
-
radius = 0.35
|
|
47
|
-
threshold = 0.72
|
|
48
|
-
smooth width = 0.08
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The Three.js bloom node reads the HDR texture produced after atmosphere. Its
|
|
52
|
-
strength becomes zero when disabled; radius, threshold, and smooth width remain
|
|
53
|
-
independently updateable.
|
|
54
|
-
|
|
55
|
-
This path does not implement a custom pyramid. Its contract is signal placement
|
|
56
|
-
and parameter ownership around the renderer’s bloom node.
|
|
57
|
-
Verify the installed Three.js node API before using the exact constructor or
|
|
58
|
-
property names.
|
|
59
|
-
|
|
60
|
-
## selective gallery pipeline selective ownership
|
|
61
|
-
|
|
62
|
-
The gallery uses two separate selective bloom pipelines:
|
|
63
|
-
|
|
64
|
-
```text
|
|
65
|
-
neon layer -> neon UnrealBloomPass
|
|
66
|
-
chandelier layer -> chandelier UnrealBloomPass
|
|
67
|
-
base scene -> final composer
|
|
68
|
-
|
|
69
|
-
final = base + neon bloom + chandelier bloom
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Each bloom composer renders off-screen. A final shader adds both bloom textures
|
|
73
|
-
to the base render, then an `OutputPass` performs display output.
|
|
74
|
-
|
|
75
|
-
Separate ownership lets neon animation change strength/radius without forcing
|
|
76
|
-
the chandelier glow to share the same threshold or spread.
|
|
77
|
-
|
|
78
|
-
Chandelier bulbs, filaments, and glow meshes use unlit materials; bulb and
|
|
79
|
-
filament materials set `toneMapped = false`. The pipeline therefore combines
|
|
80
|
-
explicit layer membership with material-level HDR/display behavior.
|
|
81
|
-
|
|
82
|
-
## Material substitution invariant
|
|
83
|
-
|
|
84
|
-
For each selective pass, selective gallery pipeline traverses visible meshes and replaces every
|
|
85
|
-
non-member material with one shared black material.
|
|
86
|
-
|
|
87
|
-
Required transaction:
|
|
88
|
-
|
|
89
|
-
```text
|
|
90
|
-
set active bloom layer
|
|
91
|
-
traverse visible meshes
|
|
92
|
-
record { mesh, original material }
|
|
93
|
-
replace non-members with shared black material
|
|
94
|
-
try:
|
|
95
|
-
render bloom composer
|
|
96
|
-
finally:
|
|
97
|
-
restore every recorded material
|
|
98
|
-
clear restoration list
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Support material arrays by storing the complete original `mesh.material`
|
|
102
|
-
value. Also toggle the high-detail and simplified
|
|
103
|
-
chandelier representations so only the intended version contributes.
|
|
104
|
-
|
|
105
|
-
The `finally` block is non-negotiable. Without it, a render error permanently
|
|
106
|
-
blackens scene meshes.
|
|
107
|
-
|
|
108
|
-
## atlas-based renderer baseline
|
|
109
|
-
|
|
110
|
-
atlas-based renderer wraps `UnrealBloomPass` with:
|
|
111
|
-
|
|
112
|
-
```text
|
|
113
|
-
strength = 0.30
|
|
114
|
-
radius = 0.50
|
|
115
|
-
threshold = 0.05
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Composer order:
|
|
119
|
-
|
|
120
|
-
```text
|
|
121
|
-
scene -> SSAO -> volumetrics -> bloom -> lens flare -> fog/color
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
This is a useful comparison, not the quality target — note its fog/color stage runs AFTER bloom, deviating from the canonical order in $genex-threejs-image-pipeline (fog belongs before bloom so bright fog does not glow). The threshold is very low
|
|
125
|
-
and can bloom ordinary bright surfaces. The wrapper exposes only enabled,
|
|
126
|
-
strength, and threshold, while radius stays at its constructor value.
|
|
127
|
-
|
|
128
|
-
## pooled VFX system HDR hierarchy
|
|
129
|
-
|
|
130
|
-
pooled VFX system assigns compact effect luminance before bloom:
|
|
131
|
-
|
|
132
|
-
```text
|
|
133
|
-
spark initial RGB multiplier = 80
|
|
134
|
-
homing projectile = 30
|
|
135
|
-
laser = 10
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
These values establish a material-level contribution hierarchy, but they do
|
|
139
|
-
not define the bloom pass. Validate them against actual renderer exposure
|
|
140
|
-
before reuse.
|
|
141
|
-
|
|
142
|
-
Use the relationship, not the raw numbers:
|
|
143
|
-
|
|
144
|
-
```text
|
|
145
|
-
short spark flash
|
|
146
|
-
> projectile core
|
|
147
|
-
> persistent laser
|
|
148
|
-
> ordinary lit surface
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Implementation limits
|
|
152
|
-
|
|
153
|
-
- selective gallery pipeline renders the scene multiple times for selective bloom. This is
|
|
154
|
-
acceptable for its bounded gallery but expensive for large scenes.
|
|
155
|
-
- Temporary material substitution can trigger shader/program changes and must
|
|
156
|
-
account for newly added meshes.
|
|
157
|
-
- The final selective gallery pipeline composite adds bloom textures directly; energy is
|
|
158
|
-
artistic, not physically conserved.
|
|
159
|
-
- atlas-based renderer’s low threshold is not evidence for a general HDR calibration.
|
|
160
|
-
- production WebGPU pipeline depends on version-sensitive Three.js bloom-node behavior.
|
|
161
|
-
- pooled VFX system material multipliers are scene-relative and cannot be treated as
|
|
162
|
-
exposure-independent units.
|
|
163
|
-
|
|
164
|
-
Prefer a dedicated contribution target when MRT/backend architecture supports
|
|
165
|
-
it and the scene cannot afford multiple full renders. Validate that decision
|
|
166
|
-
against the target scene’s measured cost and contribution masks.
|
|
167
|
-
|
|
168
|
-
## Diagnostics
|
|
169
|
-
|
|
170
|
-
Expose:
|
|
171
|
-
|
|
172
|
-
```text
|
|
173
|
-
HDR scene before bloom
|
|
174
|
-
false-color luminance
|
|
175
|
-
neon contribution
|
|
176
|
-
chandelier contribution
|
|
177
|
-
each bloom result
|
|
178
|
-
base without bloom
|
|
179
|
-
final composite
|
|
180
|
-
active layer membership
|
|
181
|
-
material restoration count and leak assertion
|
|
182
|
-
transparent-emitter contribution
|
|
183
|
-
bloom GPU time per render
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
Acceptance requires the base frame to retain form and material hierarchy with
|
|
187
|
-
both bloom textures disabled.
|
package/templates/skills/genex-threejs-exposure-color-grading/references/exposure-grading.md
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
# Scene-referred exposure and color pipeline
|
|
2
|
-
|
|
3
|
-
Use this reference for a measured HDR-to-display path with encoded luminance readback, asymmetric adaptation, one tone-map owner, and a generated display-domain 3D LUT.
|
|
4
|
-
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- Exact pipeline order
|
|
8
|
-
- Luminance meter
|
|
9
|
-
- Exposure target and adaptation
|
|
10
|
-
- 3D LUT construction
|
|
11
|
-
- LUT placement
|
|
12
|
-
- Tone mapping ownership
|
|
13
|
-
- Observed limitations
|
|
14
|
-
- Diagnostics
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## Exact pipeline order
|
|
18
|
-
|
|
19
|
-
The pipeline computes:
|
|
20
|
-
|
|
21
|
-
```text
|
|
22
|
-
HDR scene after AO/atmosphere
|
|
23
|
-
-> bloom added in HDR
|
|
24
|
-
-> multiply by adapted exposure
|
|
25
|
-
-> renderOutput using renderer tone mapping
|
|
26
|
-
-> saturate to LUT domain
|
|
27
|
-
-> sample 3D LUT
|
|
28
|
-
-> blend LUT intensity
|
|
29
|
-
-> optional FXAA
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
`RenderPipeline.outputColorTransform` is disabled and one output node owns the
|
|
33
|
-
final conversion. Renderer tone-mapping mode and renderer exposure are still
|
|
34
|
-
configuration inputs to `renderOutput`.
|
|
35
|
-
|
|
36
|
-
## Luminance meter
|
|
37
|
-
|
|
38
|
-
The implementation renders a `64 x 36` meter target using unsigned bytes. It encodes
|
|
39
|
-
unbounded luminance:
|
|
40
|
-
|
|
41
|
-
```text
|
|
42
|
-
encoded = luminance / (luminance + 1)
|
|
43
|
-
decoded = encoded / max(0.0001, 1 - encoded)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Readback occurs asynchronously every `12` frames by default. While one readback
|
|
47
|
-
is pending, another is not started.
|
|
48
|
-
|
|
49
|
-
CPU reduction uses weighted log average:
|
|
50
|
-
|
|
51
|
-
```text
|
|
52
|
-
weight = 1.0 when luminance > 0.002
|
|
53
|
-
weight = 0.15 otherwise
|
|
54
|
-
|
|
55
|
-
average =
|
|
56
|
-
exp(sum(log(max(luminance, 0.0001)) * weight) / sum(weight))
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
This suppresses black-pixel dominance without requiring a histogram.
|
|
60
|
-
|
|
61
|
-
## Exposure target and adaptation
|
|
62
|
-
|
|
63
|
-
Defaults:
|
|
64
|
-
|
|
65
|
-
```text
|
|
66
|
-
minimum exposure = 0.45
|
|
67
|
-
maximum exposure = 1.85
|
|
68
|
-
middle gray = 0.18
|
|
69
|
-
compensation = 0 EV
|
|
70
|
-
speed up = 3.2
|
|
71
|
-
speed down = 1.1
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Target:
|
|
75
|
-
|
|
76
|
-
```text
|
|
77
|
-
target =
|
|
78
|
-
clamp(
|
|
79
|
-
middleGray / averageLuminance
|
|
80
|
-
* 2^exposureCompensation,
|
|
81
|
-
minExposure,
|
|
82
|
-
maxExposure
|
|
83
|
-
)
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Frame-rate-independent adaptation:
|
|
87
|
-
|
|
88
|
-
```text
|
|
89
|
-
speed = target > current ? speedUp : speedDown
|
|
90
|
-
amount = 1 - exp(-max(deltaSeconds, 0) * speed)
|
|
91
|
-
current += (target - current) * amount
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
When disabled, current and target reset to `1`.
|
|
95
|
-
|
|
96
|
-
## 3D LUT construction
|
|
97
|
-
|
|
98
|
-
Build a `32^3` RGBA `Data3DTexture` with linear filtering, clamp wrapping, no
|
|
99
|
-
mipmaps, and unsigned-byte storage.
|
|
100
|
-
|
|
101
|
-
Each preset recipe owns:
|
|
102
|
-
|
|
103
|
-
```text
|
|
104
|
-
contrast
|
|
105
|
-
saturation
|
|
106
|
-
vibrance
|
|
107
|
-
black/white point
|
|
108
|
-
per-channel gamma
|
|
109
|
-
shadow/midtone/highlight tint
|
|
110
|
-
strength for each tonal range
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Recipe order:
|
|
114
|
-
|
|
115
|
-
```text
|
|
116
|
-
normalize black/white range
|
|
117
|
-
S-curve blend, fixed amount 0.44
|
|
118
|
-
contrast around 0.5
|
|
119
|
-
shadow tint
|
|
120
|
-
midtone tint
|
|
121
|
-
highlight tint
|
|
122
|
-
per-channel gamma
|
|
123
|
-
saturation
|
|
124
|
-
vibrance
|
|
125
|
-
small highlight glow bias
|
|
126
|
-
clamp to [0, 1]
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Tonal weights are calculated from pre-grade luminance:
|
|
130
|
-
|
|
131
|
-
```text
|
|
132
|
-
shadow = 1 - smoothstep(0.12, 0.54, luma)
|
|
133
|
-
highlight = smoothstep(0.48, 0.92, luma)
|
|
134
|
-
midtone = max(0, 1 - abs(luma - 0.5) * 2)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## LUT placement
|
|
138
|
-
|
|
139
|
-
The LUT samples tone-mapped display-linear RGB after saturation:
|
|
140
|
-
|
|
141
|
-
```text
|
|
142
|
-
uv = saturate(displayColor.rgb) * ((32 - 1) / 32) + 0.5 / 32
|
|
143
|
-
graded = texture3D(lut, uv)
|
|
144
|
-
final = mix(displayColor, graded, lutIntensity)
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
This means the included recipes are authored for a bounded post-tone-map
|
|
148
|
-
domain. Do not move them before tone mapping without rebuilding the recipes and
|
|
149
|
-
documenting a scene-linear or log domain.
|
|
150
|
-
|
|
151
|
-
## Tone mapping ownership
|
|
152
|
-
|
|
153
|
-
Available renderer modes include:
|
|
154
|
-
|
|
155
|
-
```text
|
|
156
|
-
None, Linear, Reinhard, Cineon, ACES, AgX, Neutral
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Color defaults:
|
|
160
|
-
|
|
161
|
-
```text
|
|
162
|
-
tone mapping = ACES
|
|
163
|
-
renderer exposure = 0.72
|
|
164
|
-
LUT = Real Daylight
|
|
165
|
-
LUT intensity = 1
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
The feature factory initially disables LUT intensity and eye adaptation until
|
|
169
|
-
enabled through settings. Distinguish configuration defaults from active
|
|
170
|
-
feature state.
|
|
171
|
-
|
|
172
|
-
## Observed limitations
|
|
173
|
-
|
|
174
|
-
- The meter has no center weighting, percentile clipping, sky mask, or UI mask.
|
|
175
|
-
- Unsigned-byte encoding loses precision near extreme luminance.
|
|
176
|
-
- Readback cadence is frame-count based, so wall-clock cadence changes with
|
|
177
|
-
frame rate.
|
|
178
|
-
- A failed readback resets target exposure to `1`, which can cause a visible
|
|
179
|
-
adaptation shift.
|
|
180
|
-
- LUT generation clamps every entry to `[0,1]`; it is display-domain grading,
|
|
181
|
-
not HDR scene-referred grading.
|
|
182
|
-
- The pipeline exposes both renderer `toneMappingExposure` and a separate
|
|
183
|
-
adapted exposure multiplier. Their combined ownership must be documented to
|
|
184
|
-
avoid accidental double exposure.
|
|
185
|
-
- FXAA is applied after grading, but dithering/gamut compression are absent.
|
|
186
|
-
|
|
187
|
-
## Diagnostics
|
|
188
|
-
|
|
189
|
-
Expose:
|
|
190
|
-
|
|
191
|
-
```text
|
|
192
|
-
meter source
|
|
193
|
-
encoded meter target
|
|
194
|
-
decoded luminance
|
|
195
|
-
weight mask
|
|
196
|
-
measured average
|
|
197
|
-
target/current exposure over time
|
|
198
|
-
readback pending and cadence
|
|
199
|
-
HDR before exposure
|
|
200
|
-
tone-mapped before LUT
|
|
201
|
-
neutral versus selected LUT
|
|
202
|
-
per-recipe tonal weights
|
|
203
|
-
clipped/out-of-domain mask
|
|
204
|
-
final with one exposure stage disabled at a time
|
|
205
|
-
```
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: genex-threejs-game-content
|
|
3
|
-
description: Turn a content-shaped request — quests, NPCs, dialogue, shops, loot, XP — into a countable content contract and the data-driven systems that ship it. Use when the ask names game content in the plural or a content genre (RPG, adventure, story, open world), BEFORE the asset batch, and before calling such a game done.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Genex Three.js Game Content
|
|
7
|
-
|
|
8
|
-
The most common way a content-shaped request fails is not bad code — it is the
|
|
9
|
-
ask silently shrinking: "quests" ships as one hardcoded integer, "NPCs" as
|
|
10
|
-
empty textured huts, "a big world" as one small fogged plane, while every
|
|
11
|
-
visual floor passes, because content is invisible to a screenshot. This skill
|
|
12
|
-
gives content the same teeth the look has: a countable contract written up
|
|
13
|
-
front, data-driven systems that make each contract line cheap to ship, and a
|
|
14
|
-
floor that gates publish.
|
|
15
|
-
|
|
16
|
-
## The content contract — write it before the asset batch
|
|
17
|
-
|
|
18
|
-
Run this the moment the game concept is locked, in the SAME plan message as
|
|
19
|
-
`$genex-threejs-game-ui`'s UI gate, whenever the request names content in the
|
|
20
|
-
plural (quests, enemies, bosses, locations, spells, items, factions…) or a
|
|
21
|
-
content genre (an RPG, an adventure, an open world, a story game, a survival
|
|
22
|
-
game). **Walk every plural noun of the request and make each one a countable
|
|
23
|
-
line.** The template:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
CONTENT CONTRACT — <game>
|
|
27
|
-
world: <size class, as a number: one arena | a district (~500 m) | open world (km-class — $genex-threejs-open-world)>
|
|
28
|
-
ground: <the terrain as a DECISION: flat plane | rolling relief | heightfield; water: none | river/lake/sea>
|
|
29
|
-
locations: <N, named: village, crypt, bandit camp, watchtower, boss lair…>
|
|
30
|
-
quests: <N total — a main chain of M gated steps + side quests; each giver named>
|
|
31
|
-
NPCs: <N speaking (quest givers, merchants) + M flavor villagers>
|
|
32
|
-
enemies: <N types + where they spawn; which are bosses and what makes each boss FIGHT differently>
|
|
33
|
-
progression: <what grows: XP/levels, gear tiers, learnable abilities — the numbers and their rewards>
|
|
34
|
-
economy: <currency sources AND sinks — what the player earns and what they spend it on>
|
|
35
|
-
minute ten: <one sentence: what is the player DOING ten minutes in, and why is it different from minute one?>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Rules that make the contract real:
|
|
39
|
-
|
|
40
|
-
- **It comes before the asset batch.** The asset set derives from the
|
|
41
|
-
contract — a world with six locations and four enemy types needs a
|
|
42
|
-
different `npx genex model` list than one arena, and finding that out after
|
|
43
|
-
the batch means the world gets shaped around the wrong assets.
|
|
44
|
-
- **Every line is a floor.** Publish and the final handoff wait for the
|
|
45
|
-
contract's countables exactly the way they wait for the sprite HUD: a
|
|
46
|
-
request that said "quests" is not done with one; a request that said "big
|
|
47
|
-
world" is not done with an arena.
|
|
48
|
-
- **Scope belongs to the user.** Building a small first slice is the right
|
|
49
|
-
ORDER (`$genex-threejs-game-ui`'s v0 beat still applies) — but the slice is
|
|
50
|
-
a milestone on the way to the contract, never a quiet replacement for it.
|
|
51
|
-
If the full ask genuinely doesn't fit, shrinking any line is a
|
|
52
|
-
question to the user with real options — never a silent cut justified as
|
|
53
|
-
"standard practice". (Use your question tool when you have one; if you
|
|
54
|
-
have none, a short numbered list in chat.)
|
|
55
|
-
- **Minute ten is the design test.** If the honest answer is "the same sixty
|
|
56
|
-
seconds, again", the contract needs another beat (a new area unlocks, a
|
|
57
|
-
quest chain escalates, a build comes online) before any polish work.
|
|
58
|
-
- **The `ground:` line is a decision, not a default.** Flat is fine when
|
|
59
|
-
DECIDED — but the concept frame the user approved is a promise: if it shows
|
|
60
|
-
rolling hills or a shoreline and the game ships a flat plane, that visible
|
|
61
|
-
gap goes through one plain line to the user, exactly like any other cut
|
|
62
|
-
($genex-threejs-open-world owns real relief when the answer is yes).
|
|
63
|
-
|
|
64
|
-
## Data-driven, or you won't finish in one session
|
|
65
|
-
|
|
66
|
-
The reason a solo agent can ship seven quests and seventeen items in an
|
|
67
|
-
afternoon is architecture, not typing speed:
|
|
68
|
-
|
|
69
|
-
- **Systems read tables; content lives in tables.** The quest engine, the
|
|
70
|
-
dialogue walker, the merchant screen, and the spawner are each written
|
|
71
|
-
ONCE; quest #5, item #12, and enemy #4 are table rows. If adding a quest
|
|
72
|
-
means touching engine code, the engine is wrong.
|
|
73
|
-
- **Hand-author the beats, table-drive the bulk, seed the placement.** Quest
|
|
74
|
-
prose, boss mechanics, and location identities deserve human-quality
|
|
75
|
-
authoring; stats, stocks, and rewards are data; trees, rocks, and chest
|
|
76
|
-
scatter come from a seeded RNG so "more world" costs zero authoring.
|
|
77
|
-
- **One event bus.** Quests advance on events the game already emits
|
|
78
|
-
(`enemy:died`, `item:pickup`, `chest:opened`, `npc:talked`, `zone:entered`)
|
|
79
|
-
— the quest system subscribes; combat and loot never know quests exist.
|
|
80
|
-
This is also what makes quest logic testable in isolation.
|
|
81
|
-
|
|
82
|
-
The full engine — quest defs + state machine, dialogue trees with quest
|
|
83
|
-
hooks, merchant stocks, XP curve — is in
|
|
84
|
-
[references/content-tables.md](references/content-tables.md) as copy-paste
|
|
85
|
-
modules. Copy them and fill the tables; don't re-derive the shape.
|
|
86
|
-
|
|
87
|
-
## Quests: defs + events, never an integer
|
|
88
|
-
|
|
89
|
-
The minimum honest quest system is a table of defs and an event-driven state
|
|
90
|
-
machine (`locked → available → active → ready → done`), with prereq gating for
|
|
91
|
-
the main chain:
|
|
92
|
-
|
|
93
|
-
```ts
|
|
94
|
-
type Objective =
|
|
95
|
-
| { kind: "kill"; target: string; count: number }
|
|
96
|
-
| { kind: "collect"; item: string; count: number }
|
|
97
|
-
| { kind: "reach"; location: string }
|
|
98
|
-
| { kind: "talk"; npc: string };
|
|
99
|
-
|
|
100
|
-
type QuestDef = {
|
|
101
|
-
id: string;
|
|
102
|
-
giver: string; // NPC id — every quest has a face, not a board
|
|
103
|
-
prereq?: string; // quest id that must be done first (main chain)
|
|
104
|
-
title: string;
|
|
105
|
-
brief: string; // 2–3 sentences of authored prose, not filler
|
|
106
|
-
objective: Objective;
|
|
107
|
-
rewards: { gold?: number; xp?: number; items?: string[] };
|
|
108
|
-
};
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Progress comes only from the event bus (see the reference for the ~60-line
|
|
112
|
-
engine). A tracked quest gets a compass/journal marker
|
|
113
|
-
(`$genex-threejs-game-ui` inventories the journal as a screen element), and
|
|
114
|
-
turn-in happens in dialogue — handing in a quest should feel like talking to
|
|
115
|
-
a person, not watching a counter flip.
|
|
116
|
-
|
|
117
|
-
## Dialogue: trees with quest hooks
|
|
118
|
-
|
|
119
|
-
Quest givers and merchants speak. The walker is a dozen lines (reference file)
|
|
120
|
-
over nodes of `{ text, options: [{ label, next | action }] }`; what makes it a
|
|
121
|
-
QUEST system is three dynamic option states injected per NPC: **offer** (quest
|
|
122
|
-
available → "I might have work for you"), **remind** (active → restate the
|
|
123
|
-
objective), **turn-in** (ready → hand rewards, open the next chain link). Add
|
|
124
|
-
a couple of lore branches per named NPC — three authored lines is the
|
|
125
|
-
difference between a person and a signpost. A quest board is an acceptable
|
|
126
|
-
extra for arcade-shaped games; it is never the replacement for speaking
|
|
127
|
-
NPCs when the ask said "NPCs".
|
|
128
|
-
|
|
129
|
-
## Items, shops, and an economy that closes
|
|
130
|
-
|
|
131
|
-
An item catalog (id, kind, price, stats), stack-based inventory, and merchant
|
|
132
|
-
stock tables per vendor NPC — all data (reference file). The rule that keeps
|
|
133
|
-
it a game: **currency needs sinks.** Gold the player can only accumulate is a
|
|
134
|
-
score with a coin icon; gold that buys potions, a better sword, and a spell
|
|
135
|
-
tome is an economy. Price the first upgrade to be affordable after the first
|
|
136
|
-
quest, and let drops + chest loot + quest rewards all feed the same wallet.
|
|
137
|
-
|
|
138
|
-
## Progression: something must grow
|
|
139
|
-
|
|
140
|
-
Pick at least one growth axis and wire its rewards into the quest/enemy
|
|
141
|
-
tables: an XP curve (`xpNext = 100 * level ** 1.4` is a fine default) with
|
|
142
|
-
flat stat gains per level, gear tiers on the merchant, or learnable abilities
|
|
143
|
-
gated behind tomes/trainers. The contract names which; "nothing grows" is what
|
|
144
|
-
makes minute ten feel like minute one.
|
|
145
|
-
|
|
146
|
-
## NPCs: the minimum that reads as alive
|
|
147
|
-
|
|
148
|
-
A named NPC with a role, a home spot, an idle bob, a face-the-player turn
|
|
149
|
-
within a few meters, and dialogue reads as a person — schedules and pathing
|
|
150
|
-
are optional upgrades, speech is not. Place speaking NPCs (givers, merchants)
|
|
151
|
-
by hand at their locations; scatter flavor villagers with one-line barks from
|
|
152
|
-
a table. An empty textured hut village fails the "NPCs" line of any contract.
|
|
153
|
-
For host-simulated NPCs/enemies in multiplayer, `$genex-threejs-multiplayer`
|
|
154
|
-
owns the authority rules.
|
|
155
|
-
|
|
156
|
-
## Content that can't dead-end — check before shipping
|
|
157
|
-
|
|
158
|
-
- A kill/collect quest counts progress made BEFORE acceptance (or the brief
|
|
159
|
-
says why not) — "kill 5 bandits" accepted after clearing the camp must not
|
|
160
|
-
strand at 0/5.
|
|
161
|
-
- A quest item from a unique source (a boss drop, a one-time chest) must
|
|
162
|
-
persist until picked up — the source never respawns, so expiring the drop
|
|
163
|
-
dead-ends the chain.
|
|
164
|
-
- The main chain gates on prereqs, not on geography alone — reaching the
|
|
165
|
-
final lair early should show a locked door or a warning, not a sequence
|
|
166
|
-
break that skips the story.
|
|
167
|
-
- The turn-in NPC is reachable after the objective (didn't die in the wave,
|
|
168
|
-
isn't locked behind the boss arena).
|
|
169
|
-
- Saves restore quest state AND its world side-effects — the opened chest
|
|
170
|
-
stays open, the armed boss stays armed. Quest stages, inventory, XP, and
|
|
171
|
-
gold go in the per-player slot via `$genex-threejs-embed-auth`.
|
|
172
|
-
|
|
173
|
-
## Wiring into the rest of the pack
|
|
174
|
-
|
|
175
|
-
- World layout, terrain, and location placement at scale:
|
|
176
|
-
`$genex-threejs-open-world` (the contract's `world:` line decides whether
|
|
177
|
-
it loads).
|
|
178
|
-
- Quest journal, tracker, toasts, vendor screens: inventory them at
|
|
179
|
-
`$genex-threejs-game-ui`'s gate — they are screen elements like any other.
|
|
180
|
-
- Level-ups, quest completion, and boss kills are exactly the "moments" the
|
|
181
|
-
feel pass layers feedback on: `$genex-threejs-game-feel` + a real
|
|
182
|
-
`npx genex sfx` fanfare (`$genex-ai-sfx`).
|
|
183
|
-
- Location set pieces and speaking-NPC meshes: `$genex-ai-model` /
|
|
184
|
-
`$genex-ai-character` — generated assets decorate the contract's landmarks;
|
|
185
|
-
they never decide how many exist.
|
|
186
|
-
|
|
187
|
-
## Failure modes to catch
|
|
188
|
-
|
|
189
|
-
- "Quests" (plural, in the ask) shipped as one quest — a stage integer with
|
|
190
|
-
hardcoded strings and no giver.
|
|
191
|
-
- A village of textured huts where nobody speaks.
|
|
192
|
-
- A gold counter with nothing to spend it on.
|
|
193
|
-
- No growth axis: the player at minute thirty plays exactly like minute one.
|
|
194
|
-
- The contract posted, then quietly abandoned when the first slice previewed
|
|
195
|
-
well — the slice is a milestone, not the destination.
|
|
196
|
-
- Contract lines silently shrunk without a structured question to the user.
|
|
197
|
-
- The approved concept frame shows rolling hills or water; the game ships one
|
|
198
|
-
flat plane and nobody said so.
|