oddsprig

Local asset authoring · 3.0.0

Mouth & Teeth Studio

Start with a species, then sculpt its flesh, individual crowns and tongue. Export textured assets in meters.

AI / backend controls

Instructions (TXT): people & AI agents · HTTP API schema

Use the existing stateless HTTP API or window.MouthStudio. No account, API key or credentials are required. HTTP GLB is geometry-only; browser textured GLB embeds PNG albedo, normal and ORM.

Randomization requests & recipe editing examples

Send Content-Type: application/json; the complete body must be at most 256 KiB. Successful validate/randomize responses supply a full normalized recipe. See the TXT guide for all scopes, locks and errors.

POST /api/game-assets/mouth/preset
{"config":{},"id":"cat","scope":"mouth","preserveStyle":false}
POST /api/game-assets/mouth/random-preset
{"config":{},"options":{"seed":174,"strength":0.35,"preserveStyle":false}}

New random mouth chooses a complete animal profile. Vary keeps the current profile; Preserve anatomy protects its tooth classes, counts, rows, gaps, dental pad, beak type and whole-mouth art style. Turn it off for freeform experiments.

POST /api/game-assets/mouth/randomize
{"config":{"shape":{"jawOpenDeg":35}},"options":{"scope":"all","seed":174,"strength":0.35,"locks":{"teeth":true}}}

POST /api/game-assets/mouth/randomize
{"config":{},"options":{"scope":"tooth","seed":175,"strength":0.35,"locks":{"teeth":false},"toothId":"upper-r0-t3"}}

Scopes: all, shape, teeth, tongue, textures, style, tooth. HTTP tooth scope requires options.toothId and respects the teeth lock. Omit options.locks to use the recipe's locks.

A part recipe uses defaults for omitted fields; HTTP does not merge with an earlier request or the browser editor:

POST /api/game-assets/mouth/validate
{"config":{"tongue":{"curl":0.3}}}

For a full recipe edit, obtain a normalized recipe (or load your saved one), change a field, validate it and generate geometry. This same-origin browser example preserves its other categories:

const base = "/api/game-assets/mouth/";
async function post(route, body) {
  const response = await fetch(base + route, {
    method: "POST", headers: {"Content-Type": "application/json"},
    body: JSON.stringify(body)
  });
  const data = await response.json();
  if (!response.ok) throw new Error(data.error.message);
  return data;
}
const full = (await post("validate", {config:{}})).config;
full.tongue.curl = 0.3;
const checked = await post("validate", {config:full});
const generated = await post("generate", {config:checked.config,tier:"preview"});

Browser randomization example after ready: MouthStudio.randomize({scope:"tongue",seed:174,strength:0.35,locks:{shape:true},variationBand:"natural"}). variationBand is subtle, natural, bold or wild. MouthStudio.randomPreset({seed:174,strength:0.35,variationBand:"bold",family:"living"}) starts a new mouth; omit family for every species, or pass a catalog family, living, prehistoric or fantasy. MouthStudio.listPartPresets("teeth"|"tongue"|"gums") and MouthStudio.setPartPreset(scope,id) read and apply one part. Choosing a species or part preset does not change the asset until Apply. Use MouthStudio.exportTexturedGLB({tier:"game"}) for embedded PBR maps; HTTP /export.glb returns geometry-only bytes.

Loading the mouth model. If loading does not finish, read the guide and reload.

Preparing the local 3D preview…

Drag to orbit · Scroll or pinch to zoom · +Y up · +Z forward

Preparing geometry…

Quality

Detail, map size and preview triangles appear after the model builds.

Low-poly, Game and Detailed set geometry detail and the shared map size. They do not change art style. Custom means the current detail or map size is not one of those presets. Figures above are the values in use.

Studio lighting & background

Studio illumination is a viewing aid. Exported PBR materials respond to the destination scene's lights.

Selected texture size is the actual shared atlas width and height. Geometry sliders reuse its cached maps. Click a tooth or choose any slot, including absent teeth.

Author the asset

Mouth library

Choose a species, then apply it. The asset does not change until Apply. Teeth only fits crowns to the current jaw width and keeps the mouth shape, tongue and style. New random mouth uses the filter: All sends no family; Living, Prehistoric and Fantasy send that era; a named family sends that catalog family. Each apply is one undo action.

Part presets

Choose a teeth, tongue or gum preset. The mouth stays unchanged until you apply that part.

Each apply writes only that part and is one undo action. Other categories stay as they are.

Vary current mouth

Uses the variation band, the seed and strength in Seeded variation, and the category locks in Studio. Each successful click advances the variation seed.

Seeded variation

Category locks are in Studio. The variation seed controls the draw; it does not replace the recipe's geometry seed.

Surface colors in part tabs are tints: white preserves the atlas. Textures owns the anatomical base colors. Material roughness multiplies the texture's roughness.

Individual tooth

Export & recipes

Both tiers use the geometry detail slider. Game sampling uses fewer subdivisions; ceilings are limits, not claimed quality levels.

GLB embeds actual PNG maps at the selected 640–4096 shared atlas size. Recipes contain settings only; loading replaces the recipe and migrates version 1 fields.