---
title: "Juice and polish pass the presentation phase after the playtest proof"
description: "The loop already WORKS. `world_playtest_scenario` proved the player can act, the score changes, and the win phase fires (see playtest-verification-loop). The game is playable and plain: flat lighting, primitive-gray meshes, a functional but unframed camera, silence, no impact on contact. Polish is the next phase, and it is a distinct phase on purpose. Run it AFTER the proof so you are decorating a"
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/knowledge/playbooks/juice-and-polish-pass/
---

# Juice and polish pass the presentation phase after the playtest proof

## When to use

The loop already WORKS. `world_playtest_scenario` proved the player can act,
the score changes, and the win phase fires (see playtest-verification-loop).
The game is playable and plain: flat lighting, primitive-gray meshes, a
functional but unframed camera, silence, no impact on contact. Polish is the
next phase, and it is a distinct phase on purpose. Run it AFTER the proof so you
are decorating a real loop, not painting a scene that might still change shape.

Everything below is a real op verified in the tree. Where a juice idea has no
authorable op yet (screen shake, hitstop, squash), the honest gap is named in
game-feel-and-juice and in the roadmap, not faked here.

## The polish pass, in order

Run these as one pass. Earlier steps set the frame the later steps read (a
material palette reads better under a real lighting rig; a hero frame composes
the lit, textured scene).

1. LIGHTING AND SKY. Land a lighting rig and an atmosphere as world-build ops in
   the same document transaction (`world_build_apply_semantic_operations`):
   `lighting.rig.apply` for a sun-plus-fill rig, and the world-build operation
   environment.sky_atmosphere.apply (or environment.atmosphere.apply) for the
   sky and fog mood. Deep control of individual lights and local fog is on
   `LightComponent` and `LocalEnvironmentVolumeComponent` (see
   atmosphere-sky-and-lighting). A lit scene is the single biggest step up from
   plain.

2. MATERIAL PALETTE. Give the world a coherent look with `material.palette.apply`
   (world-build), then refine specific hero surfaces with the twelve ai_safe PBR
   ops through `apply_material_semantic_patch` (`project.material.patch.apply`):
   base color, metallic, roughness, emissive, alpha, texture slots (see
   materials-and-looks). Set a material once and reuse it across meshes so the
   palette stays coherent.

3. CAMERA HERO FRAME AND POST LOOK. Compose the shot with `camera.hero_frame.set`
   (or `camera.frame_target` to point at the objective). Tune the feel on
   `CameraComponent` directly: fov, follow smoothing, `toneMapping`, `exposure`,
   and the `postProcessing` block (`depthOfField`, `motionBlur`) (see
   camera-feel). Apply a global renderer grade with
   `renderer.visual_profile.apply` (MCP tool `world_apply_visual_profile`). Post
   settings are clamped by one policy authority against live backend
   capabilities, so a profile that the running backend cannot honor degrades
   safely rather than crashing.

4. WORLD-TEXT LABELS. Anchor readable labels to entities with a
   `TextRenderableComponent`: enemy nameplates, floating values, item labels, and
   quest markers, rendered through the MSDF atlas so they stay crisp at any
   distance. This is the diegetic-UI layer that a HUD panel (layer 4 of assembly)
   does not cover. A player's own name over their character is not this layer: it
   comes from the character policy nameplate setting, which stamps a server-written
   `NameplateComponent` (see player-characters-and-spawns), so do not hand-author
   a player name plate.

5. AUDIO. Audio is LIVE in production Play. The audio subsystem is mounted above
   the present-path branch (main-thread, serving both the Worker and main-thread
   present paths), so `AudioEmitterComponent` beds and `ctx.audio` one-shots are
   audible in a real session, not just a test fixture. Add looping ambience and
   background music with `ctx.audio.setBackgroundMusic` / an
   `AudioEmitterComponent`, and event stingers (a pickup chime, a hit thud) with
   `ctx.audio.play` / `playSpatial`, pitched and leveled per event (see
   audio-feedback). Need a bespoke stinger the catalog lacks? Generate one with
   `generation_create_job` (the `audio_generator` kind), import it as a project
   asset, and reference it from the emitter (credit-metered, see step 7).

6. IMPACT CUES (the juice moment). On a contact or score moment, fire the
   transient presentation cues through the script `fx` host: `particleBurst`
   for a one-shot spark or poof and `decal` for a scorch or paint mark (the
   `Fx.particleBurst` and `Fx.decal` script nodes). These ride the wired
   presentation cue lane (audience-scoped, replayed byte-identically from the cue
   id, never leaked to a non-recipient), and they are cosmetic by construction
   so they never mutate the authoritative sim. Layer them with a
   `HighlightComponent` flash pulse and a small `ctx.camera.addLookInput` kick to
   assemble a punchy hit (see game-feel-and-juice). Persistent effects (a
   torch's fire, a continuous stream) stay on `ParticleEmitterComponent` (see
   particles-and-visual-effects); the cue is for the one-shot.

7. HERO MODELS (replace the placeholders). The loop was proven with primitive
   placeholders (a gray box is a chest, a capsule is an enemy). For the HERO
   objects the player looks at, replace the placeholder with a generated 3D
   model: `generation_create_job` with a model capability (`model_generator`;
   providers include hunyuan3d21, trellis, sf3d) and `target.importOnSuccess:
   true` finalizes a variant-bearing project asset, which you then reference from
   a `RenderableComponent` shape mesh assetId and instance through the
   asset-to-instances corridor. COST NOTE: generation is an async, credit-metered
   job (quote it first with `generation_quote_job` when budget matters). Spend it
   on the few hero objects, not every prop; keep primitives or catalog reuse for
   background fill (see asset-acquisition-strategy).

   DISCLOSURE NORM: primitive placeholders and marker stand-ins (the
   `asset.placeholder.request` billboard, a cone-for-a-tree, a gray box for a
   chest) are legitimate mid-build state, but they are NOT finished fidelity. If
   any HERO object is still a placeholder when you hand back a scenery or
   look-and-feel brief, SAY SO in your summary by name: which objects remain
   primitives or markers, and that they await a generated or catalog mesh. The
   failure this prevents is reporting a scene as "polished" or "done" while the
   player would see cones and boxes. An honest summary names the remaining
   placeholders; it never lets structure being present read as fidelity being
   achieved.

## Why this is a separate phase, and its order

- Polish decorates a proven loop. If you light and texture before the loop is
  proven, a gameplay change that moves or deletes entities orphans the work. The
  playtest is the gate; polish comes after it.
- Lighting before materials: a palette is judged under the rig that will ship,
  not under flat default light.
- The camera hero frame after lighting and materials: you are framing the lit,
  textured scene, not a gray one.
- Generation (step 7) is last and selective because it is the one step that
  costs credits and runs asynchronously; everything above is synchronous authored
  state.

## What is NOT available (do not fake it)

- No native `screenShake`, `hitstop`, `squash`, or transform-tween op. Approximate
  a shake with an oscillating `ctx.camera.addLookInput` kick and a hitstop with a
  state-gated pause; these are approximations, not one-call effects (see
  game-feel-and-juice). Naming these as done is the failure mode this playbook
  exists to prevent.
- No transient full-screen post pulse (a damage vignette flash) as a cue;
  `renderer.visual_profile.apply` and the `CameraComponent` post fields are
  durable global writes, not one-shot pulses.

## Verify

- Reload the world and confirm it MOUNTS and renders the lit, textured, framed
  scene (a backend 200 is not proof; load the SPA).
- Trigger a contact moment in a playtest and confirm the particle burst fires,
  the sound plays, and the highlight flashes.
- `project_get_graph_snapshot`: the palette, camera, lighting, and any
  TextRenderableComponent labels and generated hero assets are present on the
  entities you expect.
- LOOK before you claim fidelity: a snapshot proves structure, not appearance.
  Frame the hero objects with `world_observe_entity_view` (see
  scenery-composition) to confirm they render as real meshes, not placeholders.
  If any hero is still a primitive or marker, or the render came back
  unavailable, disclose that in the summary rather than calling the scene done.
