@call-me-sensei/toonlab 0.4.19 → 0.4.21

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.
Files changed (123) hide show
  1. package/NPM-LIBRARY.md +230 -0
  2. package/README.md +78 -36
  3. package/agents/PROMPTS.md +91 -0
  4. package/agents/README.md +9 -14
  5. package/agents/claude/CLAUDE.md +8 -0
  6. package/agents/codex/AGENTS.md +161 -0
  7. package/agents/cursor/toonlab.mdc +37 -0
  8. package/agents/references/mcp-asset-discovery.md +12 -9
  9. package/agents/references/runtime-entry-points.md +5 -4
  10. package/agents/skills/claude/asset-sourcing/SKILL.md +9 -6
  11. package/agents/skills/claude/rock-ground-shaders/SKILL.md +16 -0
  12. package/agents/skills/claude/vegetation-sky/SKILL.md +7 -4
  13. package/agents/skills/codex/asset-sourcing/SKILL.md +9 -6
  14. package/agents/skills/codex/rock-ground-shaders/SKILL.md +16 -0
  15. package/agents/skills/codex/vegetation-sky/SKILL.md +7 -4
  16. package/cli/toonlab.mjs +3 -2
  17. package/database/fal-patina.mjs +131 -0
  18. package/database/generation-service.mjs +108 -7
  19. package/database/migrations/0007_creation_revisions.sql +80 -0
  20. package/database/migrations/0008_creation_revision_hardening.sql +98 -0
  21. package/database/migrations/0009_creation_revision_delete_integrity.sql +11 -0
  22. package/database/migrations/0010_external_catalog_assets.sql +28 -0
  23. package/database/providers.mjs +195 -16
  24. package/database/repository.mjs +518 -70
  25. package/database/seeds/catalog/0003_2026-08-open-assets.sql +159086 -0
  26. package/database/seeds/catalog/0004_2026-08-c7-rocks.sql +39405 -0
  27. package/mcp/public-catalog.mjs +4 -52
  28. package/mcp/server.mjs +175 -12
  29. package/mcp/vite-plugin.mjs +78 -2
  30. package/package.json +32 -12
  31. package/scripts/generate-catalog-seed.mjs +34 -7
  32. package/src/asset-policy/catalogLicenses.js +64 -6
  33. package/src/assetlib/loadImported.js +15 -1
  34. package/src/catalog/officialCatalogAssetRuntime.js +13 -2
  35. package/src/catalog/officialCatalogLod.js +34 -1
  36. package/src/catalog/officialCatalogPlacement.js +29 -14
  37. package/src/character/animationRetarget.js +2 -0
  38. package/src/character/characterRig.js +6 -1
  39. package/src/character/characterRuntime.js +175 -7
  40. package/src/environment/environmentMaterialAdapter.js +30 -0
  41. package/src/environment/environmentPresets.js +90 -0
  42. package/src/environment/environmentSunShadowPass.js +42 -0
  43. package/src/environment/toonLabSurfaceLighting.js +108 -10
  44. package/src/environment/urbanPropMaterial.js +104 -2
  45. package/src/lighting/lightingSystem.js +65 -10
  46. package/src/renderer/index.js +7 -0
  47. package/src/renderer/styleComparison.js +985 -0
  48. package/src/rock-shader/index.js +5 -0
  49. package/src/rock-shader/rockGeometryDetail.js +701 -0
  50. package/src/rock-shader/rockMaterial.js +782 -39
  51. package/src/rock-shader/rockRegionRuntime.js +185 -0
  52. package/src/rock-shader/rockSemanticMaterialRuntime.js +337 -0
  53. package/src/rock-shader/rockShaderRuntime.js +354 -67
  54. package/src/rock-shader/rockShaderSettings.js +246 -16
  55. package/src/rock-shader/rockTangentIntegrity.js +136 -0
  56. package/src/rock-shader/rockTextureIntegrity.js +115 -0
  57. package/src/rockgen/index.js +1 -0
  58. package/src/rockgen/rockDocument.js +27 -3
  59. package/src/rockgen/surface/c7GeologySurface.js +372 -0
  60. package/src/shaders-tsl/water.js +8 -0
  61. package/src/sky/cloudShadow.js +25 -1
  62. package/src/sky/skySystem.js +9 -0
  63. package/src/styles/index.js +23 -0
  64. package/src/styles/neutralStylePresets.js +712 -0
  65. package/src/styles/sceneStyleRuntime.js +51 -4
  66. package/src/styles/styleAdapters.js +13 -2
  67. package/src/styles/styleBundle.js +1 -1
  68. package/src/texgen/evaluateTexture.js +30 -3
  69. package/src/texgen/textureGenerators.js +63 -31
  70. package/src/texgen/textureSettings.js +25 -8
  71. package/src/toon/toonSettings.js +96 -2
  72. package/src/vegetation/branchTree.js +327 -42
  73. package/src/vegetation/index.js +24 -2
  74. package/src/vegetation/scatter.js +372 -1
  75. package/src/vegetation/stylizedTree.js +312 -126
  76. package/src/vegetation/stylizedTreeFoliage.js +229 -7
  77. package/src/vegetation/treeSurfaceTextures.js +328 -0
  78. package/src/version.js +1 -1
  79. package/src/water/waterSettings.js +15 -7
  80. package/types/asset-policy/catalogLicenses.d.ts +2 -0
  81. package/types/asset-policy/index.d.ts +2 -0
  82. package/types/assetlib/loadImported.d.ts +3 -1
  83. package/types/catalog/officialCatalogLod.d.ts +63 -5
  84. package/types/character/characterRig.d.ts +59 -0
  85. package/types/character/characterRuntime.d.ts +1 -0
  86. package/types/environment/environmentMaterialAdapter.d.ts +3 -1
  87. package/types/environment/toonLabSurfaceLighting.d.ts +20 -3
  88. package/types/index.d.ts +89 -7
  89. package/types/lighting/lightingSystem.d.ts +7 -0
  90. package/types/react/index.d.ts +20 -0
  91. package/types/renderer/index.d.ts +1 -0
  92. package/types/renderer/styleComparison.d.ts +409 -0
  93. package/types/rock-shader/index.d.ts +5 -0
  94. package/types/rock-shader/rockGeometryDetail.d.ts +300 -0
  95. package/types/rock-shader/rockMaterial.d.ts +3 -0
  96. package/types/rock-shader/rockRegionRuntime.d.ts +86 -0
  97. package/types/rock-shader/rockSemanticMaterialRuntime.d.ts +29 -0
  98. package/types/rock-shader/rockShaderRuntime.d.ts +2 -0
  99. package/types/rock-shader/rockShaderSettings.d.ts +19 -5
  100. package/types/rock-shader/rockTangentIntegrity.d.ts +51 -0
  101. package/types/rock-shader/rockTextureIntegrity.d.ts +61 -0
  102. package/types/rockgen/index.d.ts +1 -0
  103. package/types/rockgen/rockDocument.d.ts +29 -1
  104. package/types/rockgen/surface/c7GeologySurface.d.ts +8 -0
  105. package/types/sky/cloudShadow.d.ts +1 -0
  106. package/types/styles/index.d.ts +1 -0
  107. package/types/styles/neutralStylePresets.d.ts +944 -0
  108. package/types/styles/sceneStyleRuntime.d.ts +20 -0
  109. package/types/vegetation/branchTree.d.ts +4 -0
  110. package/types/vegetation/index.d.ts +9 -7
  111. package/types/vegetation/scatter.d.ts +1 -0
  112. package/types/vegetation/stylizedTree.d.ts +1 -2
  113. package/types/vegetation/stylizedTreeFoliage.d.ts +1 -0
  114. package/types/version.d.ts +1 -1
  115. package/agents/references/geology-playbook.md +0 -118
  116. package/agents/skills/claude/karst-cliff-construction/SKILL.md +0 -258
  117. package/agents/skills/claude/outdoor-world/SKILL.md +0 -492
  118. package/agents/skills/claude/outdoor-world/references/coastal-landform-formation.md +0 -100
  119. package/agents/skills/codex/karst-cliff-construction/SKILL.md +0 -258
  120. package/agents/skills/codex/outdoor-world/SKILL.md +0 -492
  121. package/agents/skills/codex/outdoor-world/references/coastal-landform-formation.md +0 -100
  122. package/src/vegetation/legacyTreePresets.js +0 -120
  123. package/types/vegetation/legacyTreePresets.d.ts +0 -22
@@ -1,258 +0,0 @@
1
- ---
2
- name: karst-cliff-construction
3
- description: Experimental research guidance for assembling a stylized cliff, gorge, karst tower, or sea stack from catalog rocks, including silhouette selection, parent geology, transform grammar, and measurable rubble-pile rejection gates; not a supported automatic cliff builder.
4
- ---
5
-
6
- # Experimental cliff construction from catalog rocks
7
-
8
- This is retained as research and review guidance. ToonLab can find rocks,
9
- report their dimensions/taxonomy, and shade supplied geometry, but neither the
10
- package nor an LLM is currently qualified to turn those assets into a polished
11
- cliff automatically. Use it only for an explicit experiment, record every
12
- manual placement/transform decision, and do not present success as a stable
13
- one-shot feature.
14
-
15
- This is the assembly craft that sits between `rockgen` (which makes a rock) and
16
- the `outdoor-world` skill (which owns the whole scene). Read
17
- `../outdoor-world/SKILL.md` first for the landform-before-props ordering and the
18
- rejection gates; this skill is how you actually execute the rock layer. Read
19
- the agent-neutral
20
- [geology playbook](../../../references/geology-playbook.md) for the compact
21
- morphology, course, burial, and verification reference.
22
-
23
- Everything here was derived by building a reference-driven karst gorge from the
24
- full catalog available during qualification and having it rejected
25
- several times. Catalog contents change; query the connected OSS or Pro MCP
26
- surface instead of assuming a fixed asset count or frozen family membership.
27
- The failure modes are listed as prominently as the method, because they are
28
- what cost the time.
29
-
30
- ## The single most important rule
31
-
32
- **A cliff is one mass. Individual rocks must not be legible as individual
33
- rocks.**
34
-
35
- Squint at the frame from the hero camera. If you can pick out separate boulders
36
- in the wall face, the formation has failed, no matter how good the rocks are or
37
- how correct the metrics look. Every rule below exists to serve that one read.
38
-
39
- The characteristic failure is an **angular rubble pile**: many modules at many
40
- orientations, each individually readable, with a sawtooth crest. It looks like
41
- quarry spoil. It happens because tumbling every rock feels like variety, and
42
- because an anti-repetition gate seems to demand it. It does not.
43
-
44
- ## Selection: look, do not read tags
45
-
46
- **Family names do not guarantee silhouette.** In the tested catalog snapshot,
47
- `column-field` contains no columnar geometry at all; `broad-wall` is mostly
48
- hourglass pedestals; the only assets that genuinely read as vertical fluting
49
- live in `vertical-face`. Selecting by `familyId` or by tag produces the wrong
50
- formation when the current previews disagree with the label.
51
-
52
- So: **render contact sheets and choose visually.** Download the catalog
53
- thumbnails, lay them out in a labelled grid per family, and look at every one
54
- before choosing. Better still, render the actual GLBs under a single flat
55
- material at the intended camera azimuth — thumbnails show baked material colour,
56
- which is discarded at runtime (see below), so silhouette is the only thing that
57
- matters and the thumbnail can mislead you about it.
58
-
59
- Budget an hour for this. It is the highest-leverage hour in the whole job.
60
-
61
- **Use the published donor dimensions.** Current OSS and Pro rock search results
62
- include positive `dimensionsMeters.width`, `.height`, and `.depth`. Reject a
63
- record with missing, zero, negative, or axis-ambiguous dimensions before
64
- download. Load a finalist only to verify silhouette/material compatibility,
65
- not to discover its size. Drive placement from **target metres**, never from a
66
- raw scale multiplier. A project helper such as `place({ height: 40 })` is
67
- reviewable; `scale: 6.3` is not a ToonLab contract or an art-direction decision.
68
-
69
- ## Geology: one parent rock, many catalog families
70
-
71
- A formation must read as **one lithology**. Limestone, sandstone and granite do
72
- not alternate between adjacent modules unless the level authors a readable fault.
73
-
74
- This can conflict with selecting by silhouette, because useful shapes may span
75
- families with different `taxonomy.geology`. Treat geology as meaningful search
76
- metadata, but allow an intentional stylized donor override when the visible
77
- morphology is compatible and one material treatment makes the formation read
78
- as a deliberate parent rock. Record that override; never imply that replacing
79
- albedo changes the source mesh's physical morphology.
80
-
81
- So the working method is:
82
-
83
- 1. Select every rock by **role and silhouette**, ignoring its geology tag.
84
- 2. Apply the rock shader to the whole formation root with one settings object.
85
- 3. Verify that every included part reports the same intended texture source and
86
- material profile. One root call is the safest way to prevent call-site drift;
87
- repeated calls with byte-identical settings are visually equivalent.
88
-
89
- Two consequences worth knowing before you are surprised by them:
90
-
91
- - Baked green grass caps on some catalog rocks **disappear** under `replace`.
92
- Re-create caps deliberately, via the shader's grass layer or via vegetation.
93
- - Per-part calls invite accidental settings drift. Prefer the formation root
94
- unless a deliberately distinct lithology needs its own documented pass.
95
-
96
- For a genuinely different stone in the same frame — a quarried quay against a
97
- natural cliff — mark those meshes `userData.rockShaderExclude = true`, run the
98
- main pass, then clear the flag and run a second pass over just that group.
99
- Order matters: setting the flag before your own pass silently disables it.
100
-
101
- ### Matching geology to real morphology
102
-
103
- Choose donors by what the landform actually does, not by name:
104
-
105
- | Landform feature | What to look for |
106
- |---|---|
107
- | Rillenkarren (vertical dissolution runnels on karst) | Parallel vertical prism relief — columnar-basalt donors read as this almost exactly |
108
- | Broad fluted wall envelope | Barrel-curved faces with wide vertical creases |
109
- | Bedding partings | Donors with true horizontal lips and shelf stacks |
110
- | Undercut karst tower | Inverted flares — wider at mid-height than at the base |
111
- | Solution notch at the waterline | River-worn blocks with a rounded overhanging lip |
112
- | Collapse product below a wall | Jointed angular blocks, tumbled freely — the one place tumbling is correct |
113
-
114
- ## The transform grammar
115
-
116
- Per role, and these ranges are the difference between a landform and a pile:
117
-
118
- **Primary wall faces.** Share a near-common up axis and a near-common facing.
119
- Yaw varies the silhouette *edge*, not the rock's orientation. Pitch and roll
120
- near zero — fluting is gravity-parallel, and a tilted flute reads as a mistake.
121
- Bury 30–60 % of module depth. Present the face, not the corners.
122
-
123
- **Corners and terminations.** Yaw is set by the turn, not jittered. Turn the
124
- broad mass toward the coastline change and bury the return face into its
125
- neighbour so it never shows a free edge.
126
-
127
- **Shelves and bedding ledges.** Rotate a useful plane upward, crop the rear into
128
- the parent mass, and support the underside with a face or buttress so the
129
- overhang is a shadowed recess rather than a lit floating slab.
130
-
131
- **Crevice wedges.** The one primary role where roll is large — 8–15° — because a
132
- wedge is *supposed* to be jammed at an angle.
133
-
134
- **Talus and waterline blocks.** Free three-axis rotation, 0.7–1.4 non-uniform
135
- scale, always resting in contact with the surface below.
136
-
137
- ### Scale discipline
138
-
139
- **Cap the uniform scale, and audit it.** Blowing a 6 m donor up 22× is what makes
140
- a wall read as stretched rather than stacked: the projected texture smears, the
141
- silhouette loses its authored detail, and one module tries to do the work of a
142
- course. Prefer more modules near native size over fewer giant ones.
143
-
144
- Instrument it. Report per-role mean and max uniform scale and the worst axis
145
- ratio, and warn loudly when a role exceeds its ceiling, so a wall module cannot
146
- silently stretch a donor. A run that measured `mean 6.35, max 22.3, worst axis
147
- ratio 4.08` was visibly stretched and nobody noticed until an art director said
148
- "why is it stretched".
149
-
150
- ### Placement helpers must not reinterpret intent
151
-
152
- An oversized authored wall module must never silently become a jittered stack.
153
- Make any over-ceiling substitution **explicit and refusable**: accept an option
154
- such as `onOverCeiling: 'reject' | 'shrink' | 'stack'`, default load-bearing wall
155
- roles to `reject`, and return/report the actual strategy and placement count.
156
- Reserve `stack` for an intentional course plan; reserve tumbling for talus.
157
-
158
- Keep course variation separate from scatter variation. Load-bearing faces use
159
- `courseJitter: 0` unless the author requests a measured, small range; they must
160
- not inherit free yaw/roll jitter from a rubble scatter helper. Likewise, label
161
- Euler rotations by their local-axis order. A field named `pitch` is not a
162
- world-space lean after yaw. Prefer a world-space contract such as
163
- `leanInto: { direction, angle }`, or document and test the exact local axis.
164
-
165
- ## Anti-repetition, correctly understood
166
-
167
- The gate is **recognizable repetition**, not a repeated asset id. Reusing a good
168
- modular rock is normal environment modelling.
169
-
170
- Two copies of one id must not present the same camera-facing silhouette. Satisfy
171
- at least three of: yaw differs ≥ 25° against the camera-facing normal; different
172
- tier; uniform scale differs ≥ 25 %; burial fraction differs ≥ 8 points so a
173
- different portion of the outline survives; different overlapping neighbour.
174
-
175
- Absolute prohibitions: no twins within ~35 m at the same tier; no regular
176
- spacing interval; no kit rows.
177
-
178
- **Audit it, but do not trust the audit.** A placement-based audit scores
179
- positions and transforms — it cannot see the rendered silhouette. Zero offences
180
- and a rubble pile are entirely compatible. The audit is a floor, not approval.
181
-
182
- ## Structural coherence
183
-
184
- **Bedding must be continuous across formations.** Beds are the same beds. Derive
185
- one elevation ladder for the whole scene — ideally from the terrain's own
186
- terracing, so rock and parent mass agree — and place every bedding ledge on it.
187
- Bands that line up across neighbouring towers at equal elevation is the single
188
- detail that sells a karst formation.
189
-
190
- **Publish it.** The wall that computes the ladder should expose it, and every
191
- other formation should read it rather than re-deriving. Be aware of build order:
192
- if a composer builds parts in sequence, a later part cannot read an earlier
193
- part's published values through a context object that is only assigned after the
194
- whole composer returns. Pass shared values through the composer explicitly, or
195
- have each part fall back to a documented constant and log which path ran.
196
-
197
- Publish a shared **face plane** as well as the terrain/height envelope. Shelves,
198
- bridges, falls, vegetation lips, and sibling wall modules must read the same
199
- world-space surface contract instead of hard-coding a standoff against a wall
200
- revision that can move later.
201
-
202
- **Bridge every seam.** After the primary masses, rasterise their footprints,
203
- find pairs with a traceable boundary, and wedge shelves, buttresses and crevice
204
- slabs across them, each with a corbel tucked beneath so the overhang is a
205
- shadowed recess. Terrain must never show through a gap between rocks.
206
-
207
- **Do not let painted detail do geometry's job.** Horizontal stratification drawn
208
- into a projected texture becomes a stretched line on a scaled rock, and thin
209
- crack layers alias into dashed "stitched" lines at any realistic tile
210
- resolution. Deliver bedding as **stacked silhouettes** — real courses with real
211
- overhangs — and reserve the texture for surface grain.
212
-
213
- ## Build order
214
-
215
- Do not start by scattering rocks.
216
-
217
- 1. **Macro landform.** A continuous heightfield with the full silhouette:
218
- headlands, bays, terraces, the channel, the bed. Approve it untextured. If
219
- the macro silhouette is wrong, no rock dressing saves it.
220
- 2. **Primary structure.** Large faces at structural events only — noses,
221
- re-entrants, terminations, terrace breaks. Subordinate to the macro mass.
222
- 3. **Secondary structure.** Bridging shelves, buttresses, crevice wedges.
223
- 4. **Tertiary dressing.** Waterline notch, submerged continuation, minimal
224
- talus, story detail.
225
-
226
- Talus quantity is a geology decision, not a dressing preference. A dissolution
227
- gorge has almost none; a frost-shattered alpine face has fans. An evenly spread
228
- scree carpet is always wrong.
229
-
230
- ## Verification
231
-
232
- Numeric checks reject obvious failure; only looking can approve.
233
-
234
- - **Isolate before blaming.** Render subsystems alone — with their light rig, or
235
- you get black — to attribute a defect. A "flowing water" texture on the cliffs
236
- turned out to be the terrain's ground shader, not the waterfalls, and only an
237
- isolation capture settled it.
238
- - **Scan for outliers.** Traverse the scene for meshes above a size threshold and
239
- print path, world extent and position. This catches the 104 m slab damming a
240
- 72 m channel that nobody sees because it reads as "background".
241
- - **Squint at the silhouette first**, before texture, before colour. One mass or
242
- a pile.
243
- - **Judge from every approved camera**: hero, wide, close, flyover, top-down. A
244
- formation can read as one mass from the hero and as a kit row from above.
245
- - **Settle the scene before screenshotting.** Modules resolve async work — GLB
246
- loads, render passes — after their factory returns. Wait for a stable scene
247
- graph, not a fixed frame count, or you will review a frame with subsystems
248
- missing while the manifest claims they are present.
249
-
250
- ## Performance notes that shape the art
251
-
252
- - The rock shader creates a **material per mesh**, so instancing is unavailable
253
- and every tertiary rock costs a draw call. Budget the tertiary layer.
254
- - Catalog GLBs carry baked LODs; use the higher indices for distant modules.
255
- - Catalog GLBs can require KTX2/Draco decoders. Create one shared transcoder set
256
- with `createModelAssetTranscoders({ decoderBasePath, renderer })`, pass it to
257
- every `loadModelAsset(url, { transcoders })` call, and dispose it once after
258
- all model loads. Do not construct decoder/transcoder resources per rock.