@call-me-sensei/toonlab 0.4.21 → 0.4.23

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 (129) hide show
  1. package/NPM-LIBRARY.md +87 -27
  2. package/README.md +11 -10
  3. package/agents/PROMPTS.md +17 -3
  4. package/agents/README.md +13 -3
  5. package/agents/claude/CLAUDE.md +3 -0
  6. package/agents/codex/AGENTS.md +112 -159
  7. package/agents/cursor/toonlab.mdc +7 -3
  8. package/agents/examples/game-foundation.mjs +104 -0
  9. package/agents/references/game-lifecycle.md +57 -0
  10. package/agents/references/runtime-entry-points.md +26 -0
  11. package/agents/references/style-bundles.md +4 -1
  12. package/agents/skills/claude/asset-sourcing/SKILL.md +7 -4
  13. package/agents/skills/claude/environment/SKILL.md +4 -0
  14. package/agents/skills/claude/game-dev/SKILL.md +63 -87
  15. package/agents/skills/claude/lighting/SKILL.md +36 -0
  16. package/agents/skills/claude/post-processing/SKILL.md +8 -3
  17. package/agents/skills/claude/rock-ground-shaders/SKILL.md +10 -15
  18. package/agents/skills/claude/rockgen/SKILL.md +52 -21
  19. package/agents/skills/claude/scene-style-application/SKILL.md +4 -0
  20. package/agents/skills/claude/style-presets/SKILL.md +11 -8
  21. package/agents/skills/claude/toon-shading/SKILL.md +4 -0
  22. package/agents/skills/claude/vegetation-sky/SKILL.md +13 -7
  23. package/agents/skills/claude/visual-verification/SKILL.md +45 -119
  24. package/agents/skills/claude/water/SKILL.md +6 -2
  25. package/agents/skills/codex/asset-sourcing/SKILL.md +7 -4
  26. package/agents/skills/codex/environment/SKILL.md +4 -0
  27. package/agents/skills/codex/game-dev/SKILL.md +63 -87
  28. package/agents/skills/codex/lighting/SKILL.md +36 -0
  29. package/agents/skills/codex/post-processing/SKILL.md +8 -3
  30. package/agents/skills/codex/rock-ground-shaders/SKILL.md +10 -15
  31. package/agents/skills/codex/rockgen/SKILL.md +52 -21
  32. package/agents/skills/codex/scene-style-application/SKILL.md +4 -0
  33. package/agents/skills/codex/style-presets/SKILL.md +11 -8
  34. package/agents/skills/codex/toon-shading/SKILL.md +4 -0
  35. package/agents/skills/codex/vegetation-sky/SKILL.md +13 -7
  36. package/agents/skills/codex/visual-verification/SKILL.md +45 -119
  37. package/agents/skills/codex/water/SKILL.md +6 -2
  38. package/database/apply-one-catalog-seed.mjs +63 -0
  39. package/database/providers.mjs +1 -0
  40. package/database/seeds/catalog/0005_2026-08-c8-first12.sql +1101 -0
  41. package/database/seeds/catalog/0006_2026-09-c8-first100.sql +14245 -0
  42. package/database/seeds/catalog/0007_2026-09-c8-first100-primary-model.sql +14845 -0
  43. package/mcp/lab-management.mjs +11 -8
  44. package/mcp/public-catalog.mjs +0 -16
  45. package/mcp/tree-lab-contract.mjs +2381 -0
  46. package/mcp/vite-plugin.mjs +5 -1
  47. package/package.json +29 -18
  48. package/src/catalog/officialCatalog.js +1 -0
  49. package/src/catalog/officialCatalogAssetRuntime.js +98 -1
  50. package/src/catalog/officialCatalogLod.js +160 -16
  51. package/src/catalog/officialCatalogPlacement.js +52 -12
  52. package/src/catalog/officialCatalogProvider.js +79 -8
  53. package/src/catalog/officialCatalogRockPackage.js +172 -0
  54. package/src/cloud/cloudReprojection.js +40 -7
  55. package/src/cloud/cloudVolume.js +44 -7
  56. package/src/cloud/noise/baseShapeVolume.js +8 -6
  57. package/src/cloud/noise/cirrusMap.js +2 -1
  58. package/src/cloud/noise/curlNoise.js +2 -1
  59. package/src/cloud/noise/erosionVolume.js +2 -1
  60. package/src/cloud/noise/textureCache.js +77 -0
  61. package/src/cloud/noise/weatherMap.js +2 -1
  62. package/src/core/sha256.js +83 -0
  63. package/src/ground-shader/groundShaderMaterial.js +12 -3
  64. package/src/rock-shader/rockMaterial.js +205 -28
  65. package/src/rock-shader/rockShaderRuntime.js +17 -1
  66. package/src/rock-shader/rockShaderSettings.js +16 -0
  67. package/src/rockgen/index.js +9 -0
  68. package/src/rockgen/lod/index.js +1 -0
  69. package/src/rockgen/lod/rockDenseFieldPolicy.js +143 -0
  70. package/src/rockgen/rockDocument.js +899 -35
  71. package/src/rockgen/surface/c7GeologySurface.js +39 -9
  72. package/src/rockgen/surface/naturalRockSurface.js +1948 -0
  73. package/src/shaders-tsl/chunks/projected-water-caustics.js +14 -2
  74. package/src/shaders-tsl/chunks/water-foam.js +6 -6
  75. package/src/shaders-tsl/chunks/water-lighting.js +28 -5
  76. package/src/shaders-tsl/chunks/water-shore-state.js +5 -2
  77. package/src/shaders-tsl/chunks/water-waves.js +10 -5
  78. package/src/shaders-tsl/flower.js +7 -4
  79. package/src/shaders-tsl/grass.js +4 -3
  80. package/src/shaders-tsl/water-shore-state-simulation.js +3 -2
  81. package/src/shaders-tsl/water.js +209 -41
  82. package/src/sky/skySystem.js +30 -7
  83. package/src/toon/settings/perspectiveRemovalSettings.js +1 -1
  84. package/src/toon/toonSettings.js +74 -0
  85. package/src/vegetation/stylizedFlower.js +6 -0
  86. package/src/version.js +1 -1
  87. package/src/water/waterDetailSpectrum.js +91 -0
  88. package/src/water/waterDynamics.js +422 -0
  89. package/src/water/waterFoamParticles.js +196 -0
  90. package/src/water/waterFoamTexture.js +57 -0
  91. package/src/water/waterHydrodynamics.js +209 -0
  92. package/src/water/waterMaterial.js +1 -0
  93. package/src/water/waterRenderExtension.js +107 -0
  94. package/src/water/waterScenePasses.js +14 -6
  95. package/src/water/waterSettings.js +53 -26
  96. package/src/water/waterShoreMaterial.js +38 -14
  97. package/src/water/waterSpectralOcean.js +137 -0
  98. package/src/water/waterStageSettings.js +19 -1
  99. package/src/water/waterSurface.js +62 -18
  100. package/src/water/waterUnderwaterAtmosphere.js +30 -3
  101. package/types/catalog/officialCatalog.d.ts +1 -0
  102. package/types/catalog/officialCatalogPlacement.d.ts +4 -0
  103. package/types/catalog/officialCatalogRockPackage.d.ts +68 -0
  104. package/types/cloud/noise/baseShapeVolume.d.ts +1 -1
  105. package/types/cloud/noise/textureCache.d.ts +12 -0
  106. package/types/core/sha256.d.ts +2 -0
  107. package/types/index.d.ts +30 -0
  108. package/types/rock-shader/rockMaterial.d.ts +3 -0
  109. package/types/rock-shader/rockShaderSettings.d.ts +2 -0
  110. package/types/rockgen/index.d.ts +1 -0
  111. package/types/rockgen/lod/index.d.ts +1 -0
  112. package/types/rockgen/lod/rockDenseFieldPolicy.d.ts +181 -0
  113. package/types/rockgen/rockDocument.d.ts +654 -71
  114. package/types/rockgen/surface/naturalRockSurface.d.ts +100 -0
  115. package/types/shaders-tsl/chunks/projected-water-caustics.d.ts +7 -1
  116. package/types/shaders-tsl/chunks/water-lighting.d.ts +4 -3
  117. package/types/shaders-tsl/water.d.ts +2 -1
  118. package/types/version.d.ts +1 -1
  119. package/types/water/waterDetailSpectrum.d.ts +13 -0
  120. package/types/water/waterDynamics.d.ts +89 -0
  121. package/types/water/waterFoamParticles.d.ts +32 -0
  122. package/types/water/waterFoamTexture.d.ts +1 -0
  123. package/types/water/waterHydrodynamics.d.ts +49 -0
  124. package/types/water/waterRenderExtension.d.ts +16 -0
  125. package/types/water/waterScenePasses.d.ts +1 -1
  126. package/types/water/waterSettings.d.ts +1 -0
  127. package/types/water/waterSpectralOcean.d.ts +17 -0
  128. package/types/water/waterStageSettings.d.ts +1 -1
  129. package/types/water/waterUnderwaterAtmosphere.d.ts +19 -4
@@ -3,19 +3,23 @@ name: style-presets
3
3
  description: Explicitly select and record the intended ToonLab style or preset at every style-aware call site, distinguish neutral-default factories from Call Me Sensei-default factories, and audit overrides before reporting a custom integration note. Use before authoring environment, vegetation, grass, water, rock, ground, sky, cloud, or post settings, and whenever a subsystem looks unexpectedly unstyled.
4
4
  ---
5
5
 
6
+ References beginning `agents/` resolve from the installed ToonLab package root
7
+ (normally `node_modules/@call-me-sensei/toonlab/`), even when this skill is copied.
8
+
9
+
6
10
  # Name the preset
7
11
 
8
12
  This skill makes an individual call site explicit; it does not imply that every
9
13
  listed subsystem is part of a live Lab. Sky and Cloud focused authoring is live.
10
- Weather, Climate, and automatic full-world composition remain lower-level APIs
11
- for users who want to assemble those systems in their own application.
14
+ Weather and Climate engines remain repository-only; agents may author host
15
+ scene conditions without claiming unsupported npm entry points.
12
16
 
13
17
  Style-aware ToonLab factories take a `preset`, a `style`, or both. Some
14
18
  factories intentionally resolve a neutral/default treatment when the selector
15
19
  is omitted; Rock and Ground already default to Call Me Sensei, while
16
20
  Cloud has no named style at all since the volumetric rebuild retired them.
17
- Always pass the intended selector anyway so the call site and capture manifest
18
- are auditable. Never claim that every omitted selector falls back to neutral.
21
+ Pass the intended selector where the API has one; do not invent a selector
22
+ for a parameter-only API. Never claim that every omitted selector falls back to neutral.
19
23
 
20
24
  Omitting a selector on the neutral-default factories is one of the most
21
25
  expensive mistakes a ToonLab agent can make. In one capability test it hit
@@ -65,10 +69,9 @@ report against ToonLab before the cause was found:
65
69
  - A bare `createVegetationShaderScopeSettings()` plus ~25 hand-authored fields —
66
70
  three revisions of look development on the wrong base.
67
71
 
68
- So: **before overriding a preset field, state why the shipped value is wrong for
69
- this scene**, in a comment, naming the scene fact the shared IP treatment cannot
70
- know plane extent, bed depth, camera distance, a specific art-direction target
71
- with a measured value. If you cannot name one, do not override it.
72
+ Document meaningful overrides with the scene requirement they serve, such as
73
+ bed depth, camera distance, material identity or the requested art direction.
74
+ Routine art iteration is allowed; do not add an approval step for every value.
72
75
 
73
76
  ## When a subsystem looks wrong
74
77
 
@@ -3,6 +3,10 @@ name: toon-shading
3
3
  description: Help developers use ToonLab character toon shading, toon settings, presets, material roles, outlines, shadows, highlights, fur, or stickers.
4
4
  ---
5
5
 
6
+ References beginning `agents/` resolve from the installed ToonLab package root
7
+ (normally `node_modules/@call-me-sensei/toonlab/`), even when this skill is copied.
8
+
9
+
6
10
  # Toon Shading
7
11
 
8
12
  Use this skill when a developer wants ToonLab character toon materials, toon
@@ -3,6 +3,10 @@ name: vegetation-sky
3
3
  description: Help users apply ToonLab grass, flowers, trees, Tree/Grass/Flower shader profiles, and the live Sky/Cloud authoring surfaces to an existing scene.
4
4
  ---
5
5
 
6
+ References beginning `agents/` resolve from the installed ToonLab package root
7
+ (normally `node_modules/@call-me-sensei/toonlab/`), even when this skill is copied.
8
+
9
+
6
10
  # Vegetation, Sky, and Cloud
7
11
 
8
12
  Use these focused systems on an existing scene with host-supplied placements,
@@ -85,7 +89,7 @@ User guidance:
85
89
  MCP's `search_public_gallery` and `get_public_gallery_asset` tools, then
86
90
  instantiate its portable recipe with `StylizedTree`. Use `BranchTree` when
87
91
  the developer explicitly wants
88
- recursive branching, five broadleaf silhouettes, leaf color/texture plus a
92
+ recursive branching and the supported `BRANCH_TREE_LEAF_SHAPES`, leaf color/texture plus a
89
93
  portable lit/shadow/crown palette, independent leaf `coverageScale`, bark
90
94
  color/texture, authored trunk bend/twist/taper, roots, portable documents,
91
95
  and the shared Tree Shader. `branches.children` counts lateral children;
@@ -104,7 +108,8 @@ User guidance:
104
108
  and use `trunkSurfaceProfile: 'none'` only for a deliberate flat-color art
105
109
  direction. Verify every trunk both casts and receives in shared-pass
106
110
  coverage telemetry.
107
- Do not select, invent, or claim support for a botanical species. The large
111
+ Use supported morphology and texture controls for the requested appearance;
112
+ do not claim botanical fidelity from a named leaf shape alone. The large
108
113
  taxonomy/species roster visible in repository labs is experimental and is
109
114
  not a package API.
110
115
  - Author and route the independent `TREE_SHADER_PROFILE`,
@@ -118,8 +123,8 @@ User guidance:
118
123
  - Use the public versioned Grass, vegetation-shader, BranchTree/flower recipe, and Sky
119
124
  preset document APIs for portable data; do not copy lab-local validators.
120
125
  - Treat Sky as one integrated World System, not a separate Shader Lab. Its
121
- shader, sun, clouds, stars, and procedural motion form one system preset with
122
- exactly 46 portable art fields; dome radius and quality are not in it.
126
+ atmosphere, sun, cloud, night-sky, noise, god-ray and time blocks use the
127
+ current `SKY_PARAMS_FIELD_SCHEMA`; quality is a separate runtime choice.
123
128
  - Cloud is a raymarched volumetric deck. The painted source/composition/card
124
129
  pipeline was replaced outright: `createCloudSourceDocument`,
125
130
  `createCloudCompositionDocument`, `createCloudField` and
@@ -132,9 +137,10 @@ User guidance:
132
137
  - `sky.settings` is the authored baseline and `sky.renderedSettings` is the
133
138
  current named-layer composition. Give Lighting, Weather, and other scene
134
139
  owners unique `setSceneOverrideLayer` ids and clear only their own id.
135
- - For world integration, let the host game own the sun/light adapter. Lighting
136
- is not a stable public package or bundle domain; coordinate project-local
137
- lighting through explicit Sky, Weather, Water, and vegetation adapters.
140
+ - For world integration, prefer `createSceneStyleRuntime()` and its public
141
+ lighting slot for the sun, probe and shared shadows. The host still owns
142
+ time progression and authored local lights. Coordinate custom scene inputs
143
+ through the documented adapters.
138
144
  - The composed-world sun adapter is `setSun({ direction, color, sky })`; it
139
145
  keeps the real light/shadows and Grass, Flower, Forest, Ambient FX, Sky, and
140
146
  Water scene inputs aligned without changing their portable presets.
@@ -1,136 +1,62 @@
1
1
  ---
2
2
  name: visual-verification
3
- description: How to prove a ToonLab scene actually looks right settling the scene before screenshotting, isolating a subsystem to attribute a defect, measuring colour against sampled targets with CIEDE2000, scanning the scene graph for outliers, and running an adversarial critic loop. Use whenever judging, reviewing, or iterating on a rendered scene, and before reporting that any visual defect is a ToonLab limitation.
3
+ description: Verify ToonLab rendered output and gameplay with settled frames, relevant camera views, subsystem isolation and measurable evidence. Use for visual reviews or diagnosing a suspected rendering defect.
4
4
  ---
5
5
 
6
- # Verifying that it looks right
6
+ # Verify rendered output
7
7
 
8
- A passing build is not visual approval, and a screenshot is not evidence unless
9
- you know what was in the frame when it was taken. This skill is the measurement
10
- discipline that turns "it looks wrong" into "this surface, this value, this
11
- owner".
8
+ References beginning `agents/` resolve from the installed ToonLab package root.
9
+ A passing build does not establish visual correctness. Choose checks that match
10
+ the requested change, the art direction and the cameras the game actually uses.
12
11
 
13
- ## Settle the scene before you screenshot
12
+ ## Readiness and capture
14
13
 
15
- ToonLab subsystems keep resolving work **after their factory returns** GLB
16
- loads, render-target passes, texture uploads. Screenshotting on a fixed frame
17
- count produces frames with whole subsystems missing while your manifest happily
18
- reports them as present.
14
+ Await every readiness promise exposed by the host, render through its real
15
+ pipeline, and check required objects/textures have loaded. For static fixtures,
16
+ stable drawable counts across frames are a necessary signal, not proof of GPU
17
+ compilation or successful rendering. Animated/procedural scenes may legitimately
18
+ change counts; use their explicit readiness signals instead.
19
19
 
20
- Observed: the same command produced 273,520 triangles with the entire lagoon
21
- absent on one run and 606,056 on the next.
20
+ Inspect pixels from the output (a small `readPixels` grid or the captured image).
21
+ Check that intended surfaces are visible, with useful coverage and valid alpha.
22
+ Do not hardcode black as the only empty-frame value; an empty scene may match a
23
+ sky-colored or transparent background. Check relevant console/network errors
24
+ and failed textures. Do not dismiss a failed required resource because the rest
25
+ of the scene renders. Record the camera, readiness signals and capture path.
22
26
 
23
- So: await every readiness promise the host exposes, render through the real
24
- pipeline, and re-read the scene graph until triangle and drawable counts are
25
- **unchanged across several consecutive reads**. Treat count stability as a
26
- necessary signal, not proof that GPU compilation, render targets, or external
27
- loads succeeded. Then screenshot. Report `settled`, the readiness signals, and
28
- a non-zero rendered frame count in the capture manifest, and **fail the
29
- capture** if any required signal is wrong. A black or half-built frame must
30
- never be able to pass as a render.
27
+ ## Diagnose before attributing a defect
31
28
 
32
- Before accepting the final frame, inspect pixels from the real output (a
33
- small `readPixels` grid or the captured image). Fail when nearly every sample
34
- matches the renderer clear/background color, when useful RGB variance or
35
- non-background coverage is effectively zero, or when alpha is invalid. Do not
36
- hardcode black as the only empty-frame value: sky blue, transparent, and custom
37
- clear colors can hide the same failure. Record the distinct-color count or
38
- coverage ratio with the capture.
29
+ Isolate the suspect subsystem while retaining its lighting and required passes.
30
+ Compare with and without post-processing when appropriate. Keep camera, pose,
31
+ exposure, lighting and source textures fixed for before/after comparisons.
32
+ Inspect world-space bounds, scale and material contracts when an object has an
33
+ unexpected silhouette, repeated pattern or stretched surface.
39
34
 
40
- Also fail on any browser console error. A texture that failed to decode is a
41
- defect, not a warning.
35
+ For palette-matching tasks, sample corresponding material regions and compare
36
+ small patches in a perceptual color space such as CIEDE2000. Confirm the probe
37
+ hits the intended surface. For ordinary feature work, clear visual inspection
38
+ and targeted telemetry are enough; do not invent numeric color gates without a
39
+ reference or require measurement tools unrelated to the requested result.
42
40
 
43
- ## Isolate before you blame
41
+ ## View and interaction coverage
44
42
 
45
- Render subsystems alone to attribute a defect and include the light rig, or
46
- you get a black frame and learn nothing.
43
+ Use gameplay cameras first. For 3D assets or formations, choose relevant views
44
+ from hero, wide, close, flyover, top-down; include angles that expose seams or
45
+ repetition. A fixed-camera UI change does not need a five-camera asset audit.
46
+ Check near/far and lit/shadowed behavior when LOD or lighting is affected.
47
47
 
48
- A "flowing water" texture smeared over every cliff was investigated as a
49
- waterfall bug for two review cycles. One isolated capture of terrain plus its
50
- lighting settled it in a minute: the ground shader was painting it.
48
+ For a game slice, exercise movement, collision, interaction, success/failure and
49
+ restart where present. Test resize, focus loss/resume and teardown when changing
50
+ lifecycle ownership. Confirm post-processing is the final render path when used.
51
51
 
52
- Support a query flag that takes a **list** (`?only=terrain,lighting,sky`), and a
53
- flag that bypasses post. Most attribution questions collapse to two captures.
52
+ ## Review and report
54
53
 
55
- ## Measure colour, do not argue about it
54
+ Take a separate review pass against the requested acceptance criteria. When
55
+ active tools and developer authorization permit an independent agent/thread,
56
+ that reviewer should capture fresh evidence. Otherwise review locally; do not
57
+ spawn agents or create user tasks without authorization.
56
58
 
57
- Sample the frame at fixed points and compare against your target values in
58
- **CIEDE2000**, not by eye and not by RGB distance. Average a small patch rather
59
- than a single pixel so dithering does not decide the answer.
60
-
61
- Two disciplines that matter more than the metric:
62
-
63
- - **Probe the right surface.** A probe that lands on terrain when you think it
64
- is on rock will report a rock defect that does not exist. Prove it: change the
65
- suspected material's value and re-measure. If the probe does not move, it is
66
- not on that material. This exact check revealed that two "rock" probes were
67
- reading the ground shader.
68
- - **Probe where the reference has that material.** A probe placed at coordinates
69
- the reference fills with sky, on a frame where your scene has a cliff, measures
70
- a composition difference and reports it as a colour failure.
71
-
72
- Keep a second sampler for arbitrary points, so a question like "is the shaded
73
- wall darker than the lit one, and by how much" is one command.
74
-
75
- ## Scan the scene graph for outliers
76
-
77
- Traverse for meshes above a size threshold and print path, world-space extent
78
- and position. This catches the things nobody sees because they read as
79
- background:
80
-
81
- - a 104 m slab lying across a 72 m channel, damming it;
82
- - "cliff-top caps" built at 70–90 m across when the tower crown is 20 m.
83
-
84
- Both survived several visual reviews. A ten-line traversal found each in
85
- seconds.
86
-
87
- Audit transforms the same way. Report per-role mean and max uniform scale and
88
- the worst axis ratio; a mean scale of 6× with a max of 22× is a stretched
89
- surface, and it is visible long before anyone can articulate why.
90
-
91
- ## Judge from every approved camera
92
-
93
- A formation can read as one coherent mass from the hero camera and as a kit row
94
- from above. Fix a small set of cameras — hero, wide, close, flyover, top-down —
95
- and require all of them before approving a change. Never approve from one view.
96
-
97
- ## Run an adversarial critic
98
-
99
- Separate the builder from the judge. When the active tool surface and developer
100
- authorization permit an independent agent/thread, have that critic capture its
101
- **own** fresh evidence rather than trusting the builder's screenshots. Otherwise
102
- perform a separate critic pass after clearing builder assumptions. Read the
103
- module source and return structured blockers: region, expected, actual, fix,
104
- owner.
105
-
106
- Make the critic's standard a specific shipped frame, not "good". Give it the
107
- sampled palette and an explicit auto-fail list, and require a verdict field that
108
- is hard to fudge — a boolean like `readsAsOneMass` forces a judgement that a
109
- score can blur.
110
-
111
- Then feed the blockers back to the builder with instructions not to argue but to
112
- disprove with a capture if it disagrees. Loop until the critic passes it.
113
-
114
- In the qualifying run, independent critics scored subsystems 1.5–3.0 out of 10
115
- with 9–11 blockers each and drove the useful visual fixes. Code inspection
116
- still found contract defects; rendered evidence determined whether they were
117
- visible and whether a correction actually improved the target frame.
118
-
119
- ## Keep the harness honest under parallelism
120
-
121
- If several agents capture at once:
122
-
123
- - give each run its own port, or they fight over a fixed one;
124
- - serialise the browser through a small semaphore — GPU-backed browsers
125
- exhaust WASM memory a few instances in, and the failure surfaces to an agent
126
- as a broken module rather than as machine pressure;
127
- - expect transient failures from another agent's mid-edit file, and retry rather
128
- than "fixing" a module you do not own.
129
-
130
- ## Record the measurement, not the conclusion
131
-
132
- Write down the number and the command that produced it. "The wall is too blue"
133
- ages badly; "left wall `#4B6E97` L105 against target `#93A9C6` L168, from
134
- `capture --view hero` then a point sample at 300,250" can be re-checked after
135
- the scene has moved on — and it repeatedly turned out that the conclusion was
136
- wrong while the measurement was still useful.
59
+ Describe concrete defects with location, expected result, observed result and
60
+ likely owner. Fix them and repeat affected checks. Report evidence and remaining
61
+ limitations without treating every host-owned feature as a ToonLab limitation.
62
+ Use a standalone fixture to support claims about package defects.
@@ -3,6 +3,10 @@ name: water
3
3
  description: Help developers use ToonLab water materials, waves, ripple simulation, breakers, splashes, rain, kelp, or water settings.
4
4
  ---
5
5
 
6
+ References beginning `agents/` resolve from the installed ToonLab package root
7
+ (normally `node_modules/@call-me-sensei/toonlab/`), even when this skill is copied.
8
+
9
+
6
10
  # Water
7
11
 
8
12
  Use this skill when a developer wants WaterSurface, water material settings,
@@ -65,8 +69,8 @@ Developer guidance:
65
69
  composition. Live scene owners use unique `setSceneOverrideLayer` ids and
66
70
  clear only their own id; they must not write composed values back to a preset.
67
71
  - In a composed world, let the host game own lighting and pass current light
68
- state through Water's explicit scene adapters. Lighting is not a stable
69
- public package or bundle domain.
72
+ state through Water's explicit scene adapters. The public lighting slot and `createSceneStyleRuntime()` coordinate the
73
+ supported lighting and shared-shadow contract.
70
74
  - Preserve the host renderer's depth convention. Water supports both standard
71
75
  and reversed depth; qualify contact foam and refraction using the host's
72
76
  actual `reversedDepthBuffer` setting rather than silently changing it.
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createHash } from 'node:crypto';
4
+ import { readFile } from 'node:fs/promises';
5
+ import path from 'node:path';
6
+
7
+ import { closeDatabase, getPool, withTransaction } from './client.mjs';
8
+
9
+ const fileArgument = process.argv[2];
10
+ if (!fileArgument) throw new Error('Usage: node database/apply-one-catalog-seed.mjs database/seeds/catalog/NNNN_release.sql');
11
+ const file = path.resolve(fileArgument);
12
+ const catalogSeedRoot = `${path.resolve('database/seeds/catalog')}${path.sep}`;
13
+ if (!file.startsWith(catalogSeedRoot) || !/^\d{4}_[a-z0-9._-]+\.sql$/iu.test(path.basename(file))) {
14
+ throw new Error('Only one numbered catalog seed below database/seeds/catalog may be applied.');
15
+ }
16
+
17
+ const sql = await readFile(file, 'utf8');
18
+ const hash = createHash('sha256').update(sql).digest('hex');
19
+ const name = path.basename(file);
20
+ const release = sql.match(/^-- Release: ([a-z0-9._-]+)$/im)?.[1];
21
+ const assetCount = Number(sql.match(/^-- Asset count: (\d+)$/m)?.[1]);
22
+ if (!release || !Number.isSafeInteger(assetCount) || assetCount < 0) {
23
+ throw new Error(`${name}: missing generated release metadata.`);
24
+ }
25
+
26
+ try {
27
+ const pool = await getPool();
28
+ await pool.query(
29
+ `create table if not exists catalog_seed_batches (
30
+ name text primary key,
31
+ sha256 text not null,
32
+ release text,
33
+ asset_count integer not null default 0,
34
+ applied_at timestamptz not null default now()
35
+ )`,
36
+ );
37
+ const result = await withTransaction(async (client) => {
38
+ await client.query('select pg_advisory_xact_lock(hashtext($1))', ['toonlab:catalog_seed_batches']);
39
+ const existing = await client.query('select sha256 from catalog_seed_batches where name = $1', [name]);
40
+ if (existing.rowCount) {
41
+ if (existing.rows[0].sha256 !== hash) throw new Error(`${name} changed after it was applied`);
42
+ return { status: 'unchanged' };
43
+ }
44
+ await client.query(sql);
45
+ await client.query(
46
+ `insert into catalog_seed_batches (name, sha256, release, asset_count)
47
+ values ($1, $2, $3, $4)`,
48
+ [name, hash, release, assetCount],
49
+ );
50
+ const published = await client.query(
51
+ `select count(*)::int as count from catalog_assets
52
+ where release = $1 and availability_status = 'active'`,
53
+ [release],
54
+ );
55
+ if (Number(published.rows[0].count) !== assetCount) {
56
+ throw new Error(`${release}: expected ${assetCount} active assets after seed.`);
57
+ }
58
+ return { published: Number(published.rows[0].count), status: 'applied' };
59
+ });
60
+ process.stdout.write(`${JSON.stringify({ assetCount, hash, name, release, ...result }, null, 2)}\n`);
61
+ } finally {
62
+ await closeDatabase();
63
+ }
@@ -291,6 +291,7 @@ async function runOpenAiOrArk(provider, request, key) {
291
291
  { content: request.user ?? request.prompt ?? '', role: 'user' },
292
292
  ],
293
293
  model: request.model || (provider === 'openai' ? 'gpt-5-mini' : ''),
294
+ ...(request.kind === 'texture-recipe' ? { max_completion_tokens: 4096 } : {}),
294
295
  ...(request.jsonMode === true ? { response_format: { type: 'json_object' } } : {}),
295
296
  }),
296
297
  headers: {