Using the npm package
@call-me-sensei/toonlab is the public runtime behind the visible ToonLab Lab artifacts: an anime-style shading and content-integration toolkit for Three.js. It is WebGPU-first (TSL / NodeMaterial) with a WebGL2 fallback, MIT-licensed, and ships zero texture assets — water, sky, vegetation, and effects are procedural. Your app owns the renderer and the frame loop; ToonLab systems accept your objects.
npm install @call-me-sensei/toonlab/docs/reference.md for coding agents.Coordinate an existing scene
ToonLab does not invent a level layout or gameplay world. Your app owns the renderer, camera, frame loop, terrain shape, transforms, navigation, and dynamic physics. For an authored heightfield, createSceneSurfaceRuntime gives terrain-bound objects, grass, and shoreline water one shared heightAt(x, z) contract.
import { createSceneSurfaceRuntime } from '@call-me-sensei/toonlab/runtime';
// Your game authors terrain shape and layout once.
const surface = createSceneSurfaceRuntime({
bounds: { minX: -50, maxX: 50, minZ: -50, maxZ: 50 },
heightAt: terrainHeightAt,
waterLevel: 0,
});
// ToonLab derives consistent Y placement, grass, and shoreline state.
surface.place(tree, { anchor: 'bounds', x: 4, z: 8 });
const grass = await surface.createGrassField({ count: 12_000, seed: 42 });
const water = surface.createWaterSurface({
width: 80,
depth: 50,
position: { z: -25 },
});
scene.add(tree, grass, water);This high-level surface runtime grounds bounds-based props, keeps grass out of registered water footprints, connects water to the same bed/shore contract, and exposes a fail-closed readiness audit. It does not replace scene composition or final visual review.
What each import gives you
The package exports one subpath per cluster so your bundle only carries what you use. The big ones:
| Import | What you get |
|---|---|
| /toon, /toon-settings, /character | Anime character treatment, portable settings, loading, rig resolution, animation updates, and cleanup. |
| /environment, /ground-shader, /rock-shader | Semantic material classification and focused treatments for manufactured assets, terrain, and existing rock geometry. |
| /vegetation, /vegetation-shaders, /grass, /grass-palettes | Procedural trees, flowers and grass fields, deterministic clumps, palettes, masks, and surface-aware scatter helpers. |
| /water, /water-settings | Water surfaces, breakers, foam, caustics, interaction systems, shore state, and portable settings. |
| /sky, /cloud | The public Sky and Cloud Lab runtimes, including the coordinated physical sky and volumetric cloud deck. |
| /lighting | Versioned light recipes, budgets, runtime realization, and coordinated scene lighting. |
| /post, /post-processing | Post-processing settings and the compositor pipeline. |
| /rockgen, /texgen, /assetlib | Seeded rock documents, seamless CPU-baked PBR textures, and policy-aware asset utilities. |
| /styles, /runtime, /asset-policy, /loaders | Strict style-bundle application, scene surface coordination, source policy, and supported model loaders. |
This table is the supported package boundary. The installed artifact also includesNPM-LIBRARY.md, TypeScript declarations for every exported subpath,agents/PROMPTS.md, the local MCP executable, and its agent guidance. None of those workflows require GitHub access.
Customize a shader
Every ToonLab shader is driven by a settings object created from a schema — you never write GLSL/TSL to get a custom look. Create settings, override fields, apply. The same schemas power the labs, so anything you can click there is a field you can set in code.
import { applyToonShader, createToonSettings } from '@call-me-sensei/toonlab/toon';
// Every field ships a sensible default; override only what defines your look.
// 23 groups, 298 fields — see the Settings reference for all of them.
const settings = createToonSettings({
preset: 'default',
rimLight: { intensity: 0.35, mode: 'depth' },
outline: { thickness: 1.6 },
skinTone: { skinShadowBrightness: 0.94 },
});
applyToonShader(characterRoot, { settings });The intended workflow for a signature look: tune it visually in the Character Shader Lab, save it, and load the exported preset document in your game. Presets serialize to plain JSON:
import {
createToonPresetDocument,
serializeToonPreset,
} from '@call-me-sensei/toonlab/toon';
// Presets are plain JSON documents — the same format the labs export and
// the same format stored in your ToonLab library.
const doc = createToonPresetDocument('hero-look', {
label: 'Hero look',
settings,
});
const json = serializeToonPreset(doc);
await fetch('/my-presets/hero.json', { method: 'PUT', body: json });For looks beyond the schema, the shaders are open source TSL/NodeMaterial modules — fork the cluster and keep the preset contract.
Imported and generated environments use the manufactured environment material contract. The asset keeps stable physical and structural metadata; each shader supplies global look settings and sparse per-axis profiles, so changing a style does not require reclassifying the GLB.
Create assets
Assets come from three places: the focused procedural systems (including trees and rocks), the texture generator, and anything you import — especially CC0 assets your agent finds through MCP. Your host app keeps one placement and collision pipeline.
import { StylizedTree } from '@call-me-sensei/toonlab/vegetation';
import {
analyzeManufacturedAsset,
applyEnvironmentShader,
} from '@call-me-sensei/toonlab/environment';
// Approved procedural family; the host app owns placement, collision, and LOD.
const tree = new StylizedTree({ preset: 'call_me_sensei', seed: 7 });
// Imported models found through policy-aware MCP discovery receive an audit
// and the selected anime environment treatment before the host places them.
const audit = analyzeManufacturedAsset(importedGltf.scene);
if (audit.warnings.length) console.warn(audit.warnings);
await applyEnvironmentShader(importedGltf.scene, {
preset: 'call_me_sensei',
scenario: 'exteriorDay',
});import {
createTextureSettings, evaluateTextureMaps,
findTexturePreset, syncTextureMapTextures,
} from '@call-me-sensei/toonlab/texgen';
// 25 tileable generators, layered overlays (moss, rust, grime), a
// cel-capable color ramp, and derived normal/AO/roughness/ORM maps —
// all CPU-baked from a 60+ preset library. No texture assets shipped.
const settings = createTextureSettings(findTexturePreset('mossy-bricks').settings);
const maps = await evaluateTextureMaps(settings, { size: 1024 });
const textures = syncTextureMapTextures(maps); // THREE.DataTexture per map
material.map = textures.albedo;
material.normalMap = textures.normal;Apply a style bundle
A style bundle is a published document that selects an IP-wide style per visual system — toon shading, sky, water, post, and more — so a whole game can adopt a coherent art direction in one call. Asset presets and world-state scenarios remain independent runtime choices. Author bundles in the browser, publish, then fetch by slug:
import {
createSceneStyleRuntime,
fetchStyleBundle,
} from '@call-me-sensei/toonlab/styles';
// Label scene targets first; strict discovery fails closed on missing roles.
const { document } = await fetchStyleBundle('sakura-dusk'); // slug or full URL
const styleRuntime = createSceneStyleRuntime({ renderer, scene, sky, water, post });
await styleRuntime.apply(document, {
discovery: 'scene-labels',
mode: 'strict',
});
renderer.setAnimationLoop(() => {
styleRuntime.update(clock.getDelta(), camera);
renderer.render(scene, camera);
});Bundles resolve through GET /api/v1/bundles/:slug — public, no API key. Pass a full URL to fetchStyleBundle to use a self-hosted bundle instead.
Team plans can instead set a bundle and every creation it references to team. Those bundles appear in each member's Styles and Library views without being published. Members can inspect or fork them, and GET /api/v1/bundles/:id resolves them only for a signed-in member of the same team. A team bundle never makes its documents public.
Publish to the gallery
Library creations keep an immutable revision history in both ToonLab OSS and Pro. A meaningful save creates a revision; an identical sync is deduplicated. Open a creation to name a version, add version-only tags and notes, pin a milestone, download any snapshot, or restore it. Restore creates a new head revision, leaving the old and current versions in the audit trail. The revision number is not the portable document's version field, which continues to identify its schema.
Team-shared creations expose the same history to team members without making it public. Teammates can inspect and download versions; only the creation owner can name, tag, pin, or restore them. Style-bundle revisions lock referenced creation revisions so an older bundle resolves the same dependency documents after rollback.
Before publishing, organize reusable objects in Library. Its search covers names, descriptions, creation types, and durable tags—the same metadata an MCP coding agent queries through list_my_creations. Add up to ten concise ASCII lowercase slug tags on the creation page; punctuation becomes a hyphen, duplicate and empty tags are removed, and every tag is limited to 32 characters. They survive Lab synchronization and become Gallery search terms when a snapshot is published.
Everything you author — shader presets, water and sky systems, textures, style bundles, generated models — saves into your library as a portable document. Publishing is a visibility switch:
- Save from any lab (or via MCP
save_creation). New creations are private. - Open it in your library and set visibility:
private,team(visible to your team),unlisted(anyone with the link), orpublic. - Public creations get a permanent page at
/c/<slug>, appear in the gallery and on your profile, and can be loaded by anyone — including by reference from style bundles.
AI-generated creations are labeled as such in the gallery, and gallery search can filter them in or out.
Going deeper
- Manufactured environment materials — portable material classification for props, vehicles, buildings, and interiors.
- Settings reference — every field, type, default, and range, generated from the schemas.
- The 15 public Labs — the exact visible editors, creation types, runtime imports, controls, workflows, and preview-only boundaries.
- Local and hosted MCP — npm stdio setup, remote OAuth setup, discovery order, Lab document tools, Library operations, and generation gates.
- Prompt cookbook — drive all of the above with an AI coding agent.