@slatesvideo/shared 0.6.1 → 0.6.2
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.
- package/dist/clients/blender.d.ts +50 -0
- package/dist/clients/blender.js +195 -0
- package/dist/operations/index.d.ts +24 -0
- package/dist/operations/index.js +244 -1
- package/dist/prompts/reference-composer.d.ts +57 -0
- package/dist/prompts/reference-composer.js +70 -1
- package/dist/skills/content.js +5 -0
- package/package.json +1 -1
- package/skills/slates-blocking-to-prompt.md +250 -0
- package/skills/slates-camera-language.md +196 -0
- package/skills/slates-dialogue-blocking.md +134 -0
- package/skills/slates-previs-blocking.md +153 -0
- package/skills/slates-restyle-from-blocking.md +121 -0
package/dist/skills/content.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
// GENERATED — do not edit. Source: packages/shared/skills/*.md
|
|
2
2
|
// Regenerated by scripts/embed-skills.mjs on every build.
|
|
3
3
|
export const SKILLS = {
|
|
4
|
+
"slates-blocking-to-prompt": "---\nname: slates-blocking-to-prompt\ndescription: Write the generation prompt that matches a blocking clip second by second, so the reference video and the text agree instead of fighting. Use after rendering a previs blocking pass, when a generated shot ignores the reference video, when timings drift, or when the model invents shots and camera angles that are not in the blocking.\n---\n\n# Blocking → prompt\n\nYou have a blocking clip. This is how you write the prompt that goes with it.\n\n## The one idea\n\nThe clip already contains the camera, the cuts and the timing. **The prompt's job is to say what everything looks like — and, where the grey boxes are ambiguous, to disambiguate them.** It is not a second, competing description of the motion.\n\nState that contract inside the prompt, because the model needs it as much as you do:\n\n> Where a timeline line below names a camera position or move, it is a restatement of what the reference video already does at that timestamp — a disambiguation, never a new instruction.\n\nAnd give it a tie-break, because ambiguity is guaranteed:\n\n> If any text in this prompt appears to disagree with the reference video about camera, framing, direction, motion, timing or object placement, the reference video wins.\n\nThose two sentences do more work than any other part of the prompt.\n\n## Get the real numbers first\n\n```\nslates_blender_scene\n```\n\nWrite timings from `cutSeconds`, never from the shot list you intended to build. It resolves to the marker frames on a multi-camera edit and to the camera's own keyframes otherwise, so it is the one field that is never empty on a rig that has cuts. At 24fps cuts land on frame boundaries and the honest values are not round — `7.79s`, `9.33s`, `19.875s`. **Use the exact ones.** Rounding to `7.8` is a tenth of drift you are handing the model for free.\n\n## Structure\n\nOrder matters — contract, then globals, then timeline, then the re-assertion.\n\n```\nTITLE — one line: what this is, how long, that it is video-to-video\n\nLOGLINE — 2-4 sentences. The whole piece in plain language.\n\nACTIVE REFERENCES\n <one entry per reference: what it defines, and what is NOT inherited>\n\nTECHNICAL BLOCK (format, grade, lens, and the blanket negatives — see below)\n\nSTYLE / LOOK\nLIGHTING\nCOLOR\nCAMERA\nPHYSICS (only if things move, collide or deform)\n\nRULES (numbered — the invariants, see below)\n\nACTION TIMING (beat by beat, against the clip's real timestamps)\n\nAUDIO\n [Sound design] [Timed accents] [Dialogue] [Music]\n\nENDING LOCK (one line — where the film stops)\n\nHOLD FOR THE FULL TIMELINE\n <the 5-6 constraints most likely to drift, compressed>\n```\n\n## ACTIVE REFERENCES — every entry has an exclusion\n\nThe single highest-leverage format in this whole workflow. Each reference is a **positive claim plus an exclusion list**, because a reference the model over-reads is as damaging as one it ignores.\n\nLabel each by the badge code Slates echoes back (`IMG-A8`, `VID-C2`) or by an unmistakable role name, and use that same label everywhere below.\n\n**The blocking clip:**\n\n> VID-C2 = the blocking previz (30s, 720 frames, 24fps) — the MASTER for everything that moves and everything that stands. It defines the full edit one-to-one: every cut point, every camera position, angle, move and framing, all action timing, screen direction, and the geometry of the world. Its untextured grey surfaces, flat colours and viewport grid are NOT inherited — every grey proxy is dressed into a real object in the exact position the previz puts it. Proxies give position, angle, scale and motion only; never surface, shape detail or design.\n\nThat last sentence is the **placement-only clause** and it is not optional. Without it the model renders grey boxes.\n\n**A character sheet:**\n\n> IMG-A8 = the driver — defines his face, hair and wardrobe. Identity 100% consistent at every distance and through every motion blur. Background, lighting and pose are NOT inherited.\n\n**A location/style reference:**\n\n> IMG-B3 = the tunnel — defines location geometry, look and grade. Camera angle, framing and any people in it are NOT inherited; the camera comes exclusively from VID-C2.\n\n**An atmosphere or style master — a reference that is never a shot:**\n\n> IMG-D9 = ATMOSPHERE MASTER — NOT a keyframe, NOT a location to reproduce, NOT a frame that ever appears in the film: its own subject, framing and composition are never seen in any shot. It defines ONLY the weather, light, colour and grade: deep clean night just after rain, wet asphalt as a dark mirror, cool white-cyan lamps as the ambient key, teal-and-amber grade, deep clean blacks. Every shot is lit and graded in this regime for all 30 seconds.\n\nWithout those three NOTs the model reproduces the reference's composition as an actual shot — you get its street corner in your film. The same wording covers a rendering-style master; see `slates-restyle-from-blocking`.\n\n**References can be scheduled.** If something is only true for part of the timeline, say so: *the hooded panel applies only to 0–7.0s and 27.5–30s*, or per-reference: *Active for 00:03.3–00:06.7 only.* On a piece that travels through several locations, every location still carries its own window and the model stops blending two sets into one shot.\n\n## Translate the blocking's artifacts\n\nYour grey-box render contains things that are *notation*, not content. Every one needs an explicit reinterpretation or it gets rendered literally:\n\n| In the blocking | Say in the prompt |\n|---|---|\n| Colour-coded bodies | `red = the boss, green = the kid, blue = the driver` |\n| A marked face on a proxy | `RED face = the direction he faces, BLACK = his back` |\n| A checkered floor or wall | `the checkerboard is a scale reference, not a surface — it becomes <the real material>` |\n| Flat black background | `a PLACEHOLDER — replace with the location assigned below` |\n| A floor grid | `a motion-tracking aid — render as light on the surface, never as wireframe or tiles` |\n| A deliberate black gap | `CUT 7 (14.5-17.0, black gap in the reference) — <what fills it>` |\n| Frame goes dark mid-move | `the camera is passing through the ground — a doorway to the NEXT location, never back to a previous one` |\n| The source hard-resets mid-move | `each reset begins a NEW, completely different room — never a replay of one already seen` |\n| A proxy that is a PROP or VEHICLE | `the low-poly flying model in SHOT 18 is THE HELICOPTER · blocks on the rear bench are the luggage · the small dark block in his hand IS the pistol` |\n| A blocky proxy limb in a tight insert | `the blocky low-poly leg is a stand-in and must NOT be replicated — generate complete human anatomy: a real boot, a real trouser leg, a correct ankle at this exact camera angle` |\n| A stray object at the frame edge | `ignore it completely — never blend two sets into one shot` |\n\n## TECHNICAL BLOCK — format, lens, and the blanket negatives\n\nOne paragraph, before the timeline. It carries the things that are true of every frame and that no beat should have to repeat:\n\n> Cinematic, photoreal. 21:9. 30s. SFX only, no music. Kodak 500T film look, natural 35mm grain, organic colour, soft highlight roll-off, anamorphic lens character with oval bokeh and gentle barrel distortion at the edges, chromatic aberration creeping in at the frame edges, natural motion blur on every fast move, faint bloom on hot speculars. Every location well exposed — night interiors bright and readable, open shadows, no crushed blacks, no murk. NO CGI. NON-IP, no brand badges or logos anywhere, no text, no watermark.\n\nThree parts worth naming:\n\n- **Lens realism is a list, not an adjective.** Aberration, motion blur, depth of field, barrel distortion, bloom, grain. \"Cinematic\" buys you nothing; these buy you the look.\n- **Exposure needs saying on dark work.** Models crush night scenes into murk. *Night interiors bright and readable, open shadows, no crushed blacks* is what keeps a scene legible.\n- **The blanket negatives go here once** — `NON-IP`, no logos, no on-screen text, no subtitles, no watermark — rather than being scattered through the beats.\n\n## RULES — the invariants\n\nNumbered, short, absolute. These are the things that must hold in every frame, and they are where you put anything that has already gone wrong once.\n\nTwo patterns worth stealing outright:\n\n**Countable state.** Give the model arithmetic it can check itself against:\n\n> At every second: standing + fallen + on the lintel = 6. Never a seventh figure — no extras, no duplicates, no distant silhouettes, no half-bodies at frame edges.\n\n> Bodies on the ground count exactly: 0 before 12s → 1 → 2 → 3 → 4 at 12/13/14/16s → 5 at 20s → 6 at 26s. Never more.\n\n**Every mass is dressed, and nothing is invented.** The blocking is authority over what EXISTS, not just what moves — otherwise the model deletes the masses it finds boring and adds architecture you never blocked:\n\n> Every lamppost, guardrail, road and terrain mass visible in the reference exists in the output in the same place, at the same scale, in the same position in frame — the opening blocks are dark-brick warehouse facades, the roadside masses are the waterfront skyline, the finale rocks are the city's tower walls. Nothing is deleted, and no structure is invented where the reference shows none.\n\n**Anatomy is never inherited from a proxy.** Tight inserts on hands and feet are where blocking leaks straight into the render:\n\n> The reference shows only WHERE hands and feet are. In the output they are always complete human anatomy — a five-fingered gloved hand with natural knuckles, a real leg in wool trousers, a real foot in a leather shoe — never the proxy's blocky shape.\n\n**A ledger for anything that happens a countable number of times.** A ritual, a reload, a set of falls: state it as a linear sequence, each step exactly once, and close with the tally:\n\n> Strictly linear, six steps in fixed order, each happening EXACTLY ONCE and never repeating; once a step is done it is done for good, and the sequence only ever moves FORWARD, never backward. Count of weapon events in the entire video: one draw, one magazine insertion, one slide rack, one shot.\n\nWithout the ledger the model loops the most cinematic beat — it will rack the slide four times because racking looks good.\n\n**Named misreads.** When a generation gets something specifically wrong, do not rewrite the description — **name the wrong reading and kill it**:\n\n> The lamp is a man-made steel structure — NOT an animal, NOT a snake, NOT any living or organic shape.\n\n> The rear of the car and its tail lights are NOT visible in this shot.\n\nThis is the highest-value edit available after a failed roll, and it is why the prompt grows rather than changes between takes.\n\n## ACTION TIMING — the beats\n\nOne block per shot or beat. Two notations; pick one and hold it.\n\n**For a continuous take**, ranges with a camera note and a closing state audit:\n\n```\n8-12s — THE SWEEP (per VID-C2: elevated rear push, swinging to profile by 12s):\n<what happens, in prose, with sub-beats on tenths and → chaining cause to effect>\nEND 12s: bodies 1 (behind him as he steps past) · standing — four ahead, holding.\n```\n\n**For a cut edit**, numbered shots ending on their cut:\n\n```\n9.33-10.33s — SHOT 10 — Interior over the centre console as in VID-C2: <what the\nframe contains>. Hard cut at 10.33s.\n```\n\nThree habits that separate a beat that works from one that does not:\n\n- **Declare the frame's contents as a closed set** when the shot is tight: *the frame holds exactly the console, the lever, his hand, and the edges of both seats.* An open description invites additions.\n- **Chain cause to effect inside one sentence** with `→`. `he overcommits a lunge → the Hero drops low and sweeps his standing leg → he hits the earth at 12s`.\n- **Put events on tenths.** `11.7s`, `19.5s`, `22.5s`. Vague beats generate vague timing.\n\nDensity: roughly 60–130 words per second of screen time is what these prompts actually run at. That is much denser than a normal video prompt, and it is the point.\n\n## AUDIO\n\n`[Timed accents]` uses the same timestamps as the beats:\n\n> 3.1s tyres light up into the burnout squeal · 7.0s drift-entry screech · 10.1s hard mechanical shifter clack · 20.3s full-speed pass-by whoosh\n\n`[Dialogue]` is a closed list — count the lines, give each a window, quote it verbatim, and forbid everything else:\n\n> Exactly TWO vocal events in the entire 30 seconds, both screamed, in English, VERBATIM: 1. 17.3-18.6s \"STOOOOOP!!\" 2. 23.4-24.0s \"You crazy!\" Nothing else is ever spoken.\n\n**Then forbid the lines it will invent anyway.** A closed list is a rule; an enumerated blacklist is enforcement, and the phrases to list are the clichés the scene invites:\n\n> FORBIDDEN — she never says any of these and no one else says anything: \"they're behind us\", \"cops\", \"go go go\", \"are you crazy\", \"you're insane\", or ANY other invented phrase. All other human voice is wordless screaming or laughing.\n\n**When lines are lip-synced, give each one a timestamp** in the same list, and say that they change nothing else:\n\n> Timing: \"You wind up for this one?\" ~18.2s · \"Three full turns.\" ~19.0s · \"Company.\" ~24.3s. Every line lip-synced; the lines never change the camera.\n\nTwo rules that stop dialogue from breaking the edit:\n\n> DIALOGUE NEVER CREATES SHOTS: spoken lines happen inside the reference's takes exactly as blocked — no cutaways to a speaker, no reverse shots, no added close-ups. If a line plays while the camera is elsewhere, the line stays off-screen audio.\n\n> A line marked off-screen must STAY off-screen — never show the speaker, never move him into frame, never route the camera to him because he spoke.\n\nModel note: dialogue direction as separate layers is minimax-h3's seat; native synced audio is Veo's. Route per `slates-model-selection` and read the model's own prompting skill before writing the audio block.\n\n## ENDING LOCK\n\nOne line, and it is the cheapest fix in the document. Models drift at the end — they hold a frame too long, add a beat after the last one, or fade somewhere the reference does not:\n\n> The film ends exactly where the reference ends: the final take runs unbroken to its last frame, and that source frame IS the final frame of the film. Nothing follows. The last five seconds follow the source exactly as strictly as the first five.\n\n## HOLD FOR THE FULL TIMELINE\n\nClose with a terminal re-assertion of only the constraints most prone to drift — five or six lines, compressed, no new information:\n\n```\nHOLD FOR THE FULL TIMELINE\n- VID-C2 camera path 1:1 — any deviation = failure.\n- Six and only six figures; the count above holds at every second.\n- IMG-A8 identity constant at every distance and through motion blur.\n- The IMG-B3 location in every frame; no subtitles, no watermarks.\n```\n\nRestating is not redundancy here. It is the last thing the model reads.\n\n## Checklist before you generate\n\n- [ ] Timings taken from `slates_blender_scene`'s `cutSeconds`, frame-exact, not rounded\n- [ ] Every reference has an explicit \"NOT inherited\"\n- [ ] The placement-only clause is present\n- [ ] The tie-break clause is present\n- [ ] The disambiguation clause is present\n- [ ] Every blocking artifact is translated — colours, marked faces, checkers, grid, black background, gaps, dark dips, resets, prop proxies, proxy limbs, strays\n- [ ] Any style/weather reference is declared NOT a keyframe and never a shot\n- [ ] The every-mass-is-dressed / nothing-invented rule is present\n- [ ] Tight inserts on hands or feet demand complete anatomy\n- [ ] Counts are stated where anything is countable, and repeatable actions carry a ledger\n- [ ] A TECHNICAL BLOCK carries format, lens realism, exposure and the blanket negatives\n- [ ] `[Dialogue]` is a closed list with a FORBIDDEN blacklist\n- [ ] An ENDING LOCK says where the film stops\n- [ ] `videoReferenceSecondsEach` matches the clip's real duration\n- [ ] A HOLD block closes it\n\n## Related\n\n`slates-previs-blocking` (producing the clip) · `slates-camera-language` (the moves being described) · `slates-dialogue-blocking` (multi-character continuity) · `slates-restyle-from-blocking` (reusing this prompt across styles) · `slates-prompting-seedance-2-5` / `slates-prompting-minimax-h3` (model-specific rules)\n",
|
|
5
|
+
"slates-camera-language": "---\nname: slates-camera-language\ndescription: Turn director vocabulary into real Blender camera rigs — orbits, floor rises, robo-arm whips, handheld, speed ramps, over-the-shoulder cuts — as bpy code. Use when building or refining the camera on a previs blocking pass, when a move needs to accelerate/hold/snap, or when someone asks for a \"cinematic\" camera and you need to convert that into an actual shot list.\n---\n\n# Camera language — from a shot list to a rig\n\nCompanion to `slates-previs-blocking`. That skill owns the workflow; this one owns the camera.\n\n## The first rule\n\n🚨 **Never build \"a cinematic camera move.\" Brief the camera the way you would brief an operator:** rails, target, height, lens, and the frame each move starts and ends on. \"Cinematic\" is not a specification, and asking for one produces the drifting slop the whole blocking workflow exists to avoid.\n\nBad: *a dynamic cinematic orbit around the subject.*\nGood: *a 3/4 orbit starting rear-left at 1.6m, ending front-right at 0.9m, frames 1–96, 35mm, easing out of the start and holding hard on the last 8 frames.*\n\nIf the user gives you the first, convert it to the second and say what you assumed.\n\n## Look it up, don't recall it\n\nBefore any constraint or operator you are not certain of, call `slates_blender_docs` (e.g. `bpy.types.FollowPathConstraint`) or `slates_blender_search_docs`. Invented enum values are the most common failure here and they often fail *quietly* — the constraint gets added, the axis is wrong, and the camera points at nothing.\n\n## The two primitives everything is built from\n\n### Target-based aiming\n\nAlmost every move in this skill is *position on a path* plus *aim at a target*. Separating them is what lets framing vary while the subject stays in frame.\n\n```python\nimport bpy\n\ntarget = bpy.data.objects.new(\"CAM_TARGET\", None) # an Empty\ntarget.empty_display_type = 'PLAIN_AXES'\nbpy.context.collection.objects.link(target)\n\ncon = cam.constraints.new('TRACK_TO')\ncon.target = target\ncon.track_axis = 'TRACK_NEGATIVE_Z' # cameras look down -Z\ncon.up_axis = 'UP_Y'\n```\n\n**Aim at a separate target, not at the subject's head.** A camera locked to the head produces dead, centred framing. Offset the target beside or ahead of the subject and the shot breathes — that small offset is most of what reads as \"real operator.\"\n\nFor a subject that should notice the camera, keyframe the target's follow with a **few frames of lag** behind each camera move. Heads catch up; they don't teleport.\n\n### Path-based movement\n\n```python\ncurve = bpy.data.curves.new(\"CAM_PATH\", 'CURVE')\ncurve.dimensions = '3D'\nspline = curve.splines.new('BEZIER')\nspline.bezier_points.add(len(points) - 1)\nfor bp, co in zip(spline.bezier_points, points):\n bp.co = co\n bp.handle_left_type = bp.handle_right_type = 'AUTO'\n\npath = bpy.data.objects.new(\"CAM_PATH\", curve)\nbpy.context.collection.objects.link(path)\n\ncon = cam.constraints.new('FOLLOW_PATH')\ncon.target = path\ncon.use_curve_follow = False # aiming is the Track To constraint's job\n\n# Animate progress explicitly rather than relying on the default path animation.\ncurve.path_duration = 96\ncurve.eval_time = 0\ncurve.keyframe_insert(\"eval_time\", frame=1)\ncurve.eval_time = 96\ncurve.keyframe_insert(\"eval_time\", frame=96)\n```\n\n**Why a path and not raw location keys:** the user can drag a control point to retime or reshape the move without you regenerating anything. That is the difference between \"re-prompt and hope\" and \"nudge it.\"\n\n## Speed — the part that reads as production value\n\nMovement at one constant speed is the tell of a machine. Real moves accelerate, hold, and snap.\n\nSpeed lives in the **f-curve handles** of `eval_time` (or of location, if you keyed it directly):\n\n- **Long, near-horizontal handle** at a key → slow near that key.\n- **Short, steep handle** → fast.\n- `interpolation = 'CONSTANT'` → no movement at all until the next key. This is how you get an absolute dead stop.\n\n```python\nfc = curve.animation_data.action.fcurves.find(\"eval_time\")\nfor kp in fc.keyframe_points:\n kp.interpolation = 'BEZIER'\n kp.handle_left_type = kp.handle_right_type = 'FREE'\n\na, b, c = fc.keyframe_points # start, middle, end\n# Speed ramp: fast in, sag in the middle, accelerate out.\na.handle_right = (a.co.x + 2, a.co.y + 18) # steep = launches fast\nb.handle_left = (b.co.x - 14, b.co.y) # flat = holds\nb.handle_right = (b.co.x + 14, b.co.y)\nc.handle_left = (c.co.x - 2, c.co.y - 18) # steep = arrives fast\n```\n\n**Zero drift at a stop.** If a move is supposed to be locked off, it must be *actually* locked — a slow crawl at a \"stop\" reads as a mistake. Hold with `CONSTANT` interpolation, or duplicate the key so the segment is genuinely flat.\n\n## The moves\n\n### Orbit\n\nCircle the subject on a path, target at subject height. Vary radius and height across the move so it does not read as a turntable. Half-orbits and 3/4 orbits look more intentional than full ones.\n\nFor a multi-scene continuous orbit, keep one unbroken `eval_time` curve and move the *world* under it — the camera never cuts, the set changes.\n\n### Floor rise\n\nPure vertical translation, **no rotation**, smooth acceleration with a slow middle. Each \"floor\" is a different set stacked on Z at a fixed interval; the subject sits centre-frame at each pass.\n\n```python\nFLOOR_H = 4.0\nfor i in range(4):\n cam.location = (0, -6, i * FLOOR_H)\n cam.keyframe_insert(\"location\", frame=1 + i * 48)\n```\n\nRotation during a rise destroys the effect. Leave it out.\n\n### Robo-arm\n\nThe whip-and-lock commercial move: a fast flight along a curved arc, an **absolute** dead stop at a completely different angle, repeat. Each relocation is roughly a third of a second; each stop is a distinct, readable frame.\n\nBuild it as a path with a control point per stop, then make the stops real:\n\n```python\nHOLD_FRAMES = 10\nfor kp in fc.keyframe_points:\n kp.interpolation = 'CONSTANT' # hold dead still between flights\n```\n\nKeep the target separate and slightly offset per stop, so each lock-off is a different composition of the same subject rather than six centred portraits.\n\n### Handheld\n\nApplied **last**, on top of a finished move. Slow organic sway, not jitter: long waves plus a barely-perceptible tremor.\n\n```python\nfor path in (\"location\", \"rotation_euler\"):\n for i in range(3):\n fc = cam.animation_data.action.fcurves.find(path, index=i)\n if fc is None:\n continue\n n = fc.modifiers.new('NOISE')\n n.scale = 120 # large scale = long lazy waves (4-6s at 24fps)\n n.strength = 0.035 # small; raise for rotation, lower for location\n n.phase = i * 7.3 # decorrelate the axes or it reads as a slide\n```\n\n**Never fast jitter, wobble or snap corrections.** Wrong-flavour handheld is more damaging than none.\n\n### Over-the-shoulder cuts\n\nPer cut: a camera position below shoulder height, a near-foreground body mass, and a target on the far face. Move barely — a slow sideways crawl. See `slates-dialogue-blocking` for who may occupy the foreground and why it matters.\n\n### Lens\n\nAnimate focal length like any other channel; a slow lens breath under a move adds a lot for nothing.\n\n```python\ncam.data.lens = 35\ncam.data.keyframe_insert(\"lens\", frame=1)\ncam.data.lens = 50\ncam.data.keyframe_insert(\"lens\", frame=96)\n```\n\n**But the lens must not drift across a cut.** Within a cut it can animate; on the cut frame it changes instantly with everything else.\n\n## Multiple cameras and cuts\n\nTwo ways, and only one of them survives contact with a 19-shot edit:\n\n- **One camera, jump-cut it.** Keyframe location/rotation/lens with `CONSTANT` interpolation on the cut frames. Fine up to a handful of cuts.\n- **A camera per setup, bound to timeline markers.** Correct for anything bigger, because each setup stays independently editable.\n\n```python\nmarker = bpy.context.scene.timeline_markers.new(\"SHOT_04\", frame=188)\nmarker.camera = cam_shot_04\n```\n\nEither way the invariant is the same: **camera, target and lens all change on the cut frame, and no frame between two setups is interpolated.** One transition frame reads as a whip-pan, and the model will reproduce it faithfully.\n\n## Verify before you render\n\n```\nslates_blender_scene\n```\n\n`cutSeconds` is your actual cut list in seconds. Check it against the shot list you were given — mismatches here become mismatched prompt timings, and the prompt is what you write next.\n\n⚠️ **On a marker-bound rig, read `cutSeconds` or `markers`, never `camera.keyframeSeconds`.** The per-setup cameras are usually static (a Track To constraint does the aiming), so the active camera's action is empty and that field reads `[]` on a perfectly good three-cut edit. `cutSeconds` resolves to whichever the scene actually used.\n\n## Related\n\n`slates-previs-blocking` (the workflow) · `slates-blocking-to-prompt` (turning these moves into prompt text) · `slates-dialogue-blocking` (OTS and eyelines)\n",
|
|
4
6
|
"slates-character-identity": "---\nname: slates-character-identity\ndescription: Build a Slates character from a reference image — generate one identity sheet and bind it to the character so the card updates live. Use when the user wants to create a character, build a character from an image, or starts a storyboard flow that needs consistent character references.\n---\n\n# Character identity sheet — Slates workflow\n\nA character's identity sheet is attached to **every** downstream generation that mentions it, so a flaw in the sheet becomes a flaw in every shot made from it. Building it well is the highest-leverage thing you can do for a project.\n\n<!-- @inject:references-read-literally -->\n> **The general law: the model reads a reference literally.**\n> A reference image is not a suggestion. Whatever is baked into it — lighting, medium, texture, symmetry, competing identities — is read as a **property of the subject** and reproduced downstream. A baked rim light tints every shot made from that sheet. A sheet that looks like a 3D game render gets animated like game footage. Two competing renderings of one face get averaged into a third face.\n\nEvery reference rule below is a corollary of that one sentence, which is why \"prep the reference\" beats \"prompt around the reference\" every time:\n\n- **Flat, plain identity refs** — because scene lighting in the sheet becomes scene lighting in the output (Slates' own receipt: a studio-lit sheet produced a subject that looked green-screen-pasted in front of mountains).\n- **One authoritative rendering per subject** — because the model cannot tell which panel is the real one. ByteDance documents this failure directly: multi-view character assets \"confuse the model's character recognition, causing it to generate duplicate characters of the same appearance.\"\n- **No 3D-game-render look in a reference** — the model recognizes the render mood and inherits its motion character, so the *animation* comes out looking like game footage. This is not a taste rule; it is the same literal-reading mechanism applied to the temporal layer.\n- **Break perfect symmetry** — mirrored faces and dead-square framing read as synthetic, and the model preserves that reading rather than correcting it.\n\n**What this means in practice:** when output is wrong in a way that tracks the *subject* rather than the *scene* — the lighting is wrong the same way in every shot, the face drifts, the material looks synthetic everywhere — fix the reference, not the prompt. Prompting around a baked-in property is the expensive way to lose.\n<!-- @end:references-read-literally -->\n\n## The shape: ONE sheet, three panels\n\nSlates generates **one identity sheet per character**, bound as the character's canonical reference:\n\n| Panel | What it carries |\n|---|---|\n| **Chest-up portrait, three-quarter angle, largest panel (~25–30% of the sheet)** | The face. **This is the only place the model reads facial identity from** — every detail it will ever know comes from those pixels, so it gets the resolution. Off-frontal, never dead-on: an angled head reads its volume instantly. |\n| **Full-body front, relaxed A-pose — cropped at the collarbone, just the face cropped out** | Build, proportion, wardrobe. The face is cropped off on purpose: a front-facing body panel renders a ~40px face that can't match the portrait's, so the sheet would carry two competing identities and the model averages them. **Only the face** — neck, arms and hands render as skin. |\n| **Full-body back, head and hair visible** | Hair fall and the back of the outfit — the only panel where either reads. Keeps its head because there's no face to compete with. |\n\nThe rule is **kill every competing rendering of the FACE, not every head** — which is why exactly one body panel is headless.\n\nOn a deep neutral-grey plate (hex `3a3a3c`, emitted without the `#` — see the sigil warning in Don'ts), flat and shadowless, with catchlights in the eyes, irises never crushed to black, surface texture at the medium's own natural level of detail, broken symmetry, and no over-clean 3D-game-model look. Expression is **a slight natural smile with the teeth just visible** — a closed mouth carries no dental information, so every downstream smiling shot invents teeth, and teeth are person-specific.\n\n**Two carve-outs, scoped differently on purpose.** Non-human characters get a natural neutral expression instead of a smile — that one is scoped by *having a human mouth*, so a bipedal robot or humanoid alien is covered. Quadrupeds and non-bipedal characters get a natural standing stance with the head shown on both body panels — that one is *anatomical*. **Both are conditionals the image model evaluates against your reference; neither is a code branch, because the op has no character-kind input.**\n\n**The sheet inherits the source's medium** — photo, anime, illustration, painterly, 3D render — unless the user explicitly asks for a transform. None of the craft clauses above override that: they ask for *readable* eyes and *material-looking* surfaces within whatever medium the character is in, not for photorealism.\n\n**Why one sheet.** Every `@character` mention attaches that character's canonical identity image, so each character costs one reference slot. It also reduces competing facial renderings to **one** — with the front panel headless and the back panel turned away, the portrait is the only face on the sheet, so there is nothing left to average.\n\n## Workflow\n\n### Get the reference\nThe user has either:\n- Pasted/uploaded an image of the character (real person, drawing, AI render).\n- Described the character in text only.\n\nIf image: upload it as a reference<!-- slates-only --> (`slates_upload_reference_image`)<!-- /slates-only -->.\nIf text only: generate from prompt-only — less consistent, so warn the user.\n\n<!-- slates-only -->\n### Create the character record\n`slates_create_character` with:\n- `name` (ask if not given)\n- `description` — 1-2 sentences, *visual* only (\"tall, dark hair, scar over left eye\"), not personality.\n- `style` — leave as the source's own medium by default. Only name a transform if the user wants one (e.g. anime → realistic).\n<!-- /slates-only -->\n\n### Generate the sheet\n<!-- slates-only -->\n`slates_generate_character_identity` with `characterId`, `projectId`, and `baseAssetId` (the source portrait).\n\n**Do not hand-write the sheet prompt.** Slates builds it from the canonical template in `@slatesvideo/shared/prompts` (`buildCharacterIdentityPrompt`) — panels, plate, lighting and craft clauses included — and appends your `userNotes`. Use `userNotes` for what the template can't know: *\"use the woman on the left\"*, *\"keep the scar on the right cheek\"*. A hand-written prompt is a fork of the template and will drift from it.\n\n- Estimate cost first with `slates_estimate_generation_cost` and announce in **credits** — never quote a price from memory.\n<!-- /slates-only -->\n\n- Default to Nano Banana 2 at 2K. **Never 4K** — no identity gain at sheet scale, wasted spend.\n- When the result returns inline, **evaluate it before binding**:\n - Is the portrait clearly the largest panel, and is it off-frontal?\n - **Is the front body panel cleanly headless** — an empty collar above a normally rendered body, no partial face, no floating jaw, no smeared neck stump? A botched crop is worse than no crop.\n - **Is the body still there?** Neck, forearms and hands rendered as skin, not an empty outfit floating on nothing. A hollow garment means the invisible-mannequin genre ran unbounded.\n - Do the body panels read as the same build, wardrobe and hair as the portrait?\n - Catchlights present, irises readable rather than black holes?\n - Is it in the source's medium, and does it read as *that* medium done well — or has it drifted toward the over-clean game-model look?\n - Plate a flat deep grey, not white and not black?\n- If off: one focused refinement, then regenerate. The sheet is upstream of everything — it is worth a re-roll that a scene frame is not.\n<!-- slates-only -->\n- The op binds the result as the canonical identity automatically.\n\n### Hand back\n> \"Character {name} ready — identity sheet bound. Use `@{name}` in any prompt and Slates attaches it and names it inline, so the face stays consistent.\"\n<!-- /slates-only -->\n\n## How the reference gets used at scene time\n\nSlates cites the sheet inline under the character's name — `{name} (image N)` — in the exact order it sends references. That **name** is the anti-averaging lever, and it is each model's own official mechanism (NB2: \"assign a distinct name\"; Seedance: `Reference <Subject_N> in <Image_N>`; Kling: reuse a fixed label verbatim).\n\nCritically, the app injects **no** wardrobe, expression, or lighting directive. The user's scene prompt owns all of that — which is why `@{name}` dropped into a movie-still injection keeps the still's own clothing and lighting instead of dragging the sheet's.\n\n## Anti-patterns\n\n- **Don't** studio-light, white-background, or black-background the sheet. White bleeds into the video and washes out the location; black eats edge detail. Flat, even, shadowless light on a deep neutral grey.\n- **Don't** hand-write the sheet prompt when the op will build it — that is how the template and the shipped prompt fork.\n- **Don't** create a second character image. One canonical identity is what the storyboard pipeline reads.\n- **Don't** skip binding. An unbound asset doesn't help downstream.\n- **Don't** invent character details. Stick to what's in the reference image and the user's description.\n- **Don't** describe the front panel's crop as an absent head — in `userNotes` or any hand-written variant. The template asks for it as *framing*: **\"cropped at the collarbone, an invisible-mannequin presentation with just the face cropped out\"**, a standard e-commerce genre with deep training data. **\"the head not shown\" is a hard 422 on gpt-image-2** — fal returns `content_policy_violation` with `loc: [\"body\",\"prompt\"]`, so the text is rejected before any image is read, because an anatomical absence reads as gore to OpenAI's classifier. It passed NB2, which is why the original receipt looked safe: **it was model-scoped.** State an exclusion as a framing choice, never as a missing body part.\n- **Don't** invoke the invisible-mannequin genre without bounding it to the face. **\"an invisible-mannequin presentation where the clothing holds its own shape\" removed all the skin** — no neck, no hands, no forearms, a garment floating on nothing — because that *is* the e-commerce genre in full: an empty outfit. **\"with just the face cropped out\"** keeps the anchor and bounds it. Generalises: a genre anchor imports the whole genre, so name what STAYS, not only what goes.\n- **Don't** put `#` or `@` anywhere in prompt text. Both are reference-token sigils in the desktop prompt composer and an unresolved one is **silently deleted** — no error, no log, just missing words. `#3a3a3c` reached fal as `background ()` on a real 2026-07-30 request, meaning the plate value had never been delivered to any model since the composer shipped. Write hex values bare.\n- **Don't** use 4K — wastes credits, no quality gain at sheet scale.\n- **Don't** feed a multi-view sheet into a Seedance shot that has **several characters in frame** without binding each character to its image and appending the anti-twin constraint — ByteDance documents multi-view assets as a cause of duplicate characters. See `slates-prompting-seedance`.\n",
|
|
5
7
|
"slates-content-policy": "---\nname: slates-content-policy\ndescription: Content-policy-safe construction — build any scene safe from the first word so it hits full cinematic impact without depicting prohibited content (and without getting silently rejected or degraded by the model's filter). Read this before writing any prompt that involves conflict, creatures, crowds, destruction, weapons, or young characters. Mirror of @slatesvideo/shared/prompts content-policy fragment — SSOT: second-brain business/projects/slates/product/prompting-ssot.md.\n---\n\n# Content-policy-safe construction — read before any risk-surface prompt\n\nDon't depict the harm — depict the energy, the aftermath, the threat, or the scale. Build the scene safe from the first word.\n\nWrite scenes that hit full cinematic impact without ever *needing* to depict prohibited content. This is a craft move, not a compromise — the substitutions below usually read as more cinematic, not less, and they keep your generation from getting silently rejected or degraded by the model's filter. A standoff is more tense than a massacre; an evacuated city is eerier than a crowd in panic; a roar lands harder than a kill. Load this whenever a prompt involves conflict, creatures, crowds, destruction, weapons, or young characters.\n\n## Substitution table\n\n| Avoid | Use instead |\n|---|---|\n| Civilians in panic, crowds fleeing under debris | An evacuated / empty city; abandoned streets; a lone figure for scale |\n| Weapons firing into buildings or at people | Energy-discharge standoffs, searchlights sweeping, charged auras, shockwaves with no muzzle fire |\n| Creatures tearing into each other, gore | A grapple / standoff — roars, near-misses, circling, an energy clash; combat that stays contained (in/on the water, never lifting into the air) |\n| Destruction with people in harm's way | Destruction in uninhabited terrain — glaciers, deserts, ruins, open sea, evacuated zones |\n| Realistic guns as the focus | Stylized / fantasy implements, weapons slung-not-fired, the weapon as silhouette or prop only |\n| Blood, wounds, death | Impact light, dust, debris, buckling and collapse, a silhouette dropping out of frame |\n| Real, named public figures | Original / anonymous characters |\n| Real brand logos | Original or generalized branding — except the user's own product, which is the whole point of a brand film |\n\n## The safe benchmark\n\nWhen a scene starts drifting risky, pull it back toward this shape: **one original creature, in a generalized monument or amphitheatre, in daylight, no weapons present, performing expressive action** (rising, roaring, spreading wings). Original design, generalized location, daylight, expressive rather than violent. That's the confirmed-safe envelope — most epic ideas re-stage into it without losing the punch.\n\n## Containment rule — it doubles as a physics win\n\nGive any creature or combat scene a **containment rule** that grounds the physics at the same time:\n- \"the fight STAYS at the sea surface — they breach, dive, grapple, submerge, but never fly or get carried into the air\"\n- \"boss scale locked ~2.5 human-heights, NOT kaiju-giant\"\n- \"destruction stays in the evacuated valley\"\n\nThis improves coherence (the model isn't inventing absurd escalation) AND keeps the scene inside policy — same clause buys both.\n\n## Scale and stakes without harm\n\nEpic stakes come from environmental danger and reaction, not depicted victims: tiny figures diving clear of *collapsing* terrain (not being crushed), a war-horn over an *empty* field, an army *scrambling* across a frozen valley as a titan tears free of a glacier. The danger is the environment; the figures are reacting, not dying. Snow plumes, glowing runes, splintering ice, shockwaves, and dust carry the chaos.\n\n## Minors — hard rule\n\nNever write romantic, sexual, or suggestive content involving or directed at minors, and never anything that sexualizes a young-presenting character. Any scene with children stays wholesome and age-appropriate. Non-negotiable — it overrides every stylistic goal.\n\n## Pre-flight (run before delivering any risk-surface prompt)\n\n- [ ] No civilians depicted in panic/harm; crowds are evacuated or absent.\n- [ ] No weapons firing at people/buildings; threat is energy / searchlight / silhouette.\n- [ ] No creature-on-creature or creature-on-person gore; combat is grapple / standoff / roar, contained.\n- [ ] Destruction is in uninhabited / evacuated terrain.\n- [ ] Creatures are original (\"not based on any franchise\"); no real public figures; no real brand logos except the user's own product.\n- [ ] Anything with children is wholesome and age-appropriate.\n\nIf a box fails, apply the substitution table before writing the prompt.\n\n## Editing real footage (Kling O3 edit / Omni Flash edit) — real people in the SOURCE\n\nVideo edit takes the user's own footage, which often contains real people. Rules:\n\n- The user must hold rights/consent for any real person's likeness in footage they edit — ask once when it's clearly someone other than the user, then proceed.\n- Kling's video-to-video filter behavior on real faces is **not yet verified** (unlike Seedance, where the consent-gated real-face route is confirmed). If an edit of real-person footage is rejected by the provider, do NOT retry-spam variations — tell the user the filter blocked it and offer a no-face crop/segment or an AI-character swap instead.\n- **Omni Flash: own-footage editing of the uploader's own face PASSED live 2026-07-09** (real talking-head clip, edited on our fal route) despite Google's documented \"recognizable people\" restriction — treat that restriction as aimed at third-party/public figures, but expect probabilistic refusals and never promise passage.\n- Never use edit to put a real, named public figure into a scene, or to make someone appear to say/do something they didn't. Faceless b-roll (hands, products, landscapes, crowds-from-behind) edits freely.\n\n## Gemini / Omni Flash filter regime (video gen + edit) — receipts 2026-07-09\n\nGoogle's filter is its own regime (stricter than fal-hosted Kling about harm-to-a-person, looser than BytePlus about faces). Live receipts:\n\n| Blocked (`content_policy_violation`) | Passed |\n|---|---|\n| \"his fingertips **ignite** with a small real flame\" (fire ON a body part = harm) | \"small **magical** flames appear on his fingertips … vanish when he blows on them\" |\n\n- **Harm-to-person framing is the tripwire**, not the effect itself. Reframe body-contact effects as magical / supernatural / harmless VFX: \"magical flames\", \"a glowing aura\", \"sparks of light dance on\". Avoid ignite / burn / on fire / catch fire applied to a person.\n- **Never use a real object as a metaphor** — \"candle-like flame\" rendered a literal candle in the subject's hand. Describe the effect, not an object that resembles it.\n- The block is a 422 refund (no credits lost) and arrives mid-generation — one reframe per the substitution mindset above, don't retry-spam.\n",
|
|
6
8
|
"slates-cost-discipline": "---\nname: slates-cost-discipline\ndescription: Mandatory pre-flight discipline before ANY generation call (image or video) — estimate cost, announce in credits, get confirmation, aggregate batches. Read this every time before calling slates_generate_image or any future slates_generate_* op. Skipping this risks burning the user's credits on guesses.\n---\n\n# Slates cost discipline — read before every generation\n\nGeneration costs real money. Every call is on the user's credits. The user can't see what you're about to spend until you tell them. **Tell them first, generate second.**\n\n## The 4 rules\n\n### 1. Pre-flight estimate — never call generate without one\n\nBefore ANY `slates_generate_*` call, run `slates_estimate_generation_cost` first. Inputs you must lock before estimating:\n\n- **Model** — derived from the op (`slates_generate_image` → `nano-banana-2-{resolution}`)\n- **Resolution** — never let the op default. Pick deliberately. Drafts → 1k. Hero → 2k. Print → 4k.\n- **Aspect ratio** — never let the op default to 1:1. Pick from the use case (cinematic → 16:9, mobile vertical → 9:16, square feed → 1:1).\n- **Count** — explicit. Don't generate 4 when 1 will tell you if the prompt works.\n\nIf aspect ratio or resolution isn't obvious from the user's request, **ask before estimating**. Don't guess.\n\n### 2. Announce in credits, plainly, before spending\n\nSlates bills abstract **credits** (they never expire). Announce the credit total the estimate returns — never dollars.\n\nFormat: `About to spend N credits on M image(s) at [resolution] [aspect ratio]. Proceed?`\n\nExamples:\n- `About to spend 4 credits on 1 image at 1k 16:9. Proceed?`\n- `About to spend 24 credits on 4 images at 2k 9:16 (variants). Proceed?`\n\nBelow ~7 credits you can proceed silently after announcing once. Above ~7 credits wait for explicit confirmation. Above ~17 credits the server itself will gate with `requires_confirm` — pass `confirm: true` only after the user explicitly OKs.\n\n### 3. Aggregate batches into ONE upfront announcement\n\nIf you're planning a multi-call workflow (5 storyboard frames, 3 character variants, a grid of options), **announce the total before the first call**, not five small announcements after the fact.\n\nFormat: `Plan: N generations totaling C credits. [Brief description of the sequence.] Proceed with the batch?`\n\nExample: `Plan: 6 frame generations at 1k 16:9 totaling 24 credits — establishing wide, push-in, two-shot, reverse, OTS, insert. Proceed?`\n\n### 3b. Batch authorization — one approval covers the enumerated batch\n\nWhen the user approves a batch plan with one aggregated cost total up front (\"8 scenes, ~$X total — go\"), that single approval authorizes `confirm=true` on **each enumerated call in that batch** — and nothing beyond it. You do not need to re-ask per call; that's the point of the upfront announcement. Hands-off multi-scene runs depend on this.\n\nBoundaries that re-trigger confirmation:\n\n- Any call's actual estimate exceeds what the announced plan implied for it by **>25%** → stop, surface the delta, get a fresh OK.\n- New calls are added that weren't in the enumerated plan (extra variants, retries beyond the plan, a new scene) → those are NOT covered. Announce and confirm separately.\n- The batch scope changes (different model, resolution, or duration than announced) → re-announce, re-confirm.\n\nOne approval = that plan, as enumerated, at those prices. Nothing else.\n\n### 4. Track the running total\n\nAfter each generation completes, the response includes `cost_credits` (when available). Keep a running tally in your context. Surface it every 3 generations or whenever the user asks \"how much have we spent?\"\n\n## Resolution decision rules\n\n| Use case | Resolution |\n|---|---|\n| First draft of a new prompt | 1k |\n| Storyboard frame (will likely regenerate) | 1k |\n| Hero shot, locked composition | 2k |\n| Print, marketing asset, final delivery | 4k |\n| Iterating to refine | match the previous resolution |\n\nResolution is a price lever, not a free choice: on Nano Banana 2 and FLUX.2 Max, 4k costs roughly 2x 1k (Seedream 5 Lite is flat-priced regardless of resolution). Prices change — call `slates_estimate_generation_cost` or `slates_list_available_models` for current numbers instead of assuming. Pick the cheapest resolution that serves the use case.\n\n**4K VIDEO is Pro-only (2026-07-07).** The ladder above is for IMAGES (open at every tier). For VIDEO — Kling, Seedance, Veo — 4K requires a Slates Pro account; a base-tier 4K video gen is rejected server-side with `PRO_REQUIRED`. Default video to 1080p or lower and only reach for 4K when the user is on Pro and explicitly asks. 4K *images* are never gated.\n\n## Aspect ratio decision rules\n\nAsk the user when ambiguous. Otherwise:\n\n| Context cue | Aspect ratio |\n|---|---|\n| \"cinematic\", \"film\", \"movie\", \"wide\" | 16:9 |\n| \"TikTok\", \"Reels\", \"Story\", \"mobile vertical\", \"phone\" | 9:16 |\n| \"square\", \"Instagram feed\", \"thumbnail\" | 1:1 |\n| \"ultra-wide\", \"anamorphic\", \"cinemascope\" | 21:9 |\n| \"portrait\", \"magazine cover\", \"vertical\" | 4:5 or 2:3 |\n| \"landscape photo\", \"horizontal\" | 3:2 or 4:3 |\n\nIf the user prompt mixes signals (e.g. \"cinematic Instagram post\"), ask. Don't guess.\n\n## When the gate fires\n\nThe server returns `requires_clarification` when aspect ratio or resolution is missing. The server returns `requires_confirm` when total spend exceeds ~17 credits. In both cases:\n\n1. Surface the gate response to the user\n2. Get a clean answer\n3. Re-call with the explicit values + `confirm: true` if applicable\n\nDon't bypass the gate by silently filling in defaults. The gates exist because defaults waste money.\n\n## Video is slow + async — a timeout is NOT a failure\n\nVideo gens take minutes (Seedance 4K can run far longer). A client/CLI timeout or a slow, empty-looking response is **not** a failed generation — the job is still running on the provider.\n\n- **Never re-submit a video gen because it \"timed out.\"** That double-charges the user for one video. Re-rolling a slow gen is the single most expensive mistake here.\n- **Poll, don't re-roll.** Use `background: true` on `slates_generate_video`, then poll `slates_get_generation_status` (free, read-only) until it reports `completed` or `failed`. In-flight jobs survive app restarts and are recovered.\n- A gen has only failed when the status comes back `failed` — and a provider *rejection* **refunds** the credits, so failed isolation tests are ~free. Until you see a terminal status, the job is in flight. Wait.\n\n## 🔴 The still-gate — the most expensive mistake in the pipeline\n\n<!-- @inject:still-gate -->\n**A visible defect in the still is already a STOP.** Do not animate it. Fix the frame first, then move to motion — and go to motion only when the crop passes the still scan and you genuinely need movement to confirm an uncertain edge, reflection, or object.\n\nThis is a **cost** rule as much as a craft rule: a 1080p/10s premium video generation costs many multiples of an image re-roll, and video is where a defect stops being fixable. Anything wrong in the still gets worse in motion — soft geometry mushes, broken-but-plausible objects fall apart, oily textures start crawling. **Animating a known-bad frame is the single most expensive mistake in the pipeline.** Re-rolling the image is the cheap move; re-rolling the video is not.\n<!-- @end:still-gate -->\n\nThe check itself lives in `slates-vision-feedback-loop` (the four slop tells and the per-model accents). The **stop** is a cost rule and belongs here: before every image→video call, confirm the source frame passed the still scan. If it didn't, spending video credits on it is not iteration — it is buying a more expensive copy of a defect you already found.\n\n## The 3-strike rule\n\nStop after 3 iterations on the same prompt. Hand back to the user with what you tried and what's not working. The slot machine doesn't converge — if it's not landing, the prompt structure is wrong, not the seed.\n",
|
|
9
|
+
"slates-dialogue-blocking": "---\nname: slates-dialogue-blocking\ndescription: Keep multiple characters spatially consistent across cuts — seating, screen direction, eyelines, the 180-degree rule — by blocking the scene in 3D first. Use for any multi-character dialogue scene, conversations around a table or in a car, or when generated characters swap seats, change sides, or look the wrong way between shots.\n---\n\n# Dialogue blocking — six people who stay where you put them\n\nThe hardest thing to generate, and the case where previs beats raw prompting by the widest margin.\n\n## Why this is hard\n\nEvery cut is an independent guess unless something forces agreement. Prompt a six-person conversation four times and you get four different seating charts: characters swap places, the 180-degree line breaks, and nothing cuts together. The failure is not aesthetic — the shots are simply unusable as an edit, and you find out only after paying for all four.\n\n**The blocking fixes it structurally.** Positions exist in 3D, so every camera sees the same arrangement, and consistency stops being something the model has to remember.\n\n## Build\n\nFollow `slates-previs-blocking` and add these.\n\n### Seated proxies, colour-coded\n\nSimple seated shapes. **Do not animate the heads** — a proxy head turning the wrong way is worse than one that never turns.\n\nGive each character a distinct viewport colour and write the mapping down. This is the identity channel:\n\n> red = the boss · green = the kid · blue = the driver · yellow = the fixer · purple = the cousin · cyan = the nephew\n\nThat mapping goes verbatim into the generation prompt. It is what lets the model bind a grey body to a character sheet across four cuts.\n\nGive every proxy a material and set `mat.diffuse_color` to its identity colour — the blocking render pins Workbench to `MATERIAL` shading, so **the material's `diffuse_color` is what reaches the clip**. Set `object.color` to the same value too, so the user's viewport matches what renders. See `slates-previs-blocking` for the snippet.\n\n### Fix the geography, then never move it\n\nPlace people once. Write down who sits where relative to the camera's opening position, in words, because that sentence is going into the prompt:\n\n> Across the table, facing camera: yellow dead centre, purple far left, blue and green to the right.\n\n### The camera plan\n\nPer `slates-camera-language`, with two things specific to dialogue:\n\n- **Below shoulder height, slow rail glides.** Eye-level-and-above reads as surveillance.\n- **Decide who owns the near foreground in each cut and honour it.** A shoulder in frame is a spatial anchor; a different shoulder in the next cut relocates the whole room.\n\nThe move that earns the most: **a gaze handoff without a cut** — the camera keeps gliding while the target hands off across the table, face to face, slowing on each but never stopping. Build it by keyframing the Track To target's position between subjects.\n\n### Crossing behind someone\n\nA head wiping frame during a move is a strong depth cue. It is also a spatial claim, so pick who gets crossed and say so — *the camera crosses directly behind cyan's back mid-shot and his head wipes the frame once.*\n\n## The prompt\n\nEverything in `slates-blocking-to-prompt`, plus these blocks.\n\n### Geography — restate it as a rule\n\n> TABLE GEOGRAPHY — do not deviate: the camera is never parked behind red. Only in the opening seconds does his dark shoulder hang at the near frame RIGHT edge, and it slides out as the camera travels LEFT. The true near-foreground of this shot is cyan: the camera crosses directly behind him mid-shot. After the opening seconds red is gone from the foreground, and the camera never travels behind anyone except cyan.\n\n### Screen direction, and the mirror that is not a swap\n\nThe 180-degree rule survives on its own in the blocking. What breaks is the model **\"correcting\" a legitimate mirror** — when the camera faces back through a scene, sides invert, and that inversion is correct. Say so explicitly or it gets flipped:\n\n> The driver's seat is on the LEFT for the entire timeline; this layout never mirrors or flips. When a camera faces BACKWARD into the car, screen sides mirror naturally: the driver reads on the RIGHT of frame, the passenger on the LEFT — that is correct left-hand drive, not a swap. They never swap seats or roles anywhere in the timeline.\n\nThen compress it into the HOLD block: *(backward camera mirrors them: he right of frame, she left)*.\n\n### Presence\n\n> A seated person stays drawn even when partially occluded — in every interior frame some part of each seat's owner is visible: a hand, an arm, a shoulder, a head above the bolster. Every occupied seat visibly holds its person.\n\n### Keep everyone alive\n\nThree orthogonal layers. Without them, whoever is not speaking freezes:\n\n- **ONGOING BUSINESS** — a small continuous physical action per character, running whether or not they are speaking. *turns his glass a quarter every few seconds · thumbs a lighter without lighting it.*\n- **BACKGROUND LIFE** — soft-focus, low contrast, never pulls attention, never crosses in front of a speaking face.\n- **SCENE EVENT** — the unnamed thing everyone is playing but nobody says. One line, repeated verbatim in every character's direction: *keep tomorrow sounding like a fishing trip.*\n\n### Acting, per character\n\nSame six slots each. Terse:\n\n```\nACTING TASK — <character>\n SCENE DIRECTION (shared, unspoken): <the same line for everyone>\n MOTIVE (his fuel): <what he wants underneath>\n GOAL: <what he wants in this scene>\n OBSTACLE: <what is in the way>\n TACTIC: <how he goes about it>\n Moment to moment: <2-3 beats keyed to timestamps>\n (Safety: gaze always engaged in the task — never a frozen, glassy,\n unfocused stare; natural blink cadence.)\n```\n\nThat safety line is not filler. Dead eyes are the characteristic failure of generated faces in dialogue, and naming it is what prevents it.\n\n### Split any strong emotion into phases\n\nThe other characteristic failure is a face that strikes one extreme expression and holds it for the whole shot — a mouth stuck open for three seconds. Give the beat two phases with a hinge, and name the failure you are excluding:\n\n> PHASE 1 (17.3-18.6s) — she SCREAMS at him, mouth wide, eyes huge, hand clamped on the grab handle. PHASE 2 (18.6-19.9s) — the scream breaks off: she shuts her eyes tight and CLOSES her mouth, both hands now on the handle, head ducked, braced. Scream, then brace — never one frozen open mouth held through the whole shot.\n\nThe hinge timestamp is what makes it a performance instead of a pose.\n\n### Dialogue must not restructure the edit\n\nBoth of these, verbatim, every time:\n\n> DIALOGUE NEVER CREATES SHOTS: spoken lines happen inside the reference's takes exactly as blocked — no cutaways to a speaker, no reverse shots, no added close-ups. If a line plays while the camera is elsewhere, the line stays off-screen audio.\n\n> OFF-SCREEN VOICES RULE: a line marked off-screen must STAY off-screen — never show the speaker, never move him into frame, never route the camera behind him because he spoke.\n\nA sentence may cross a cut. Say so where it does: *the sentence does not pause for the edit.*\n\n## Model routing\n\nDialogue directed as separate layers (voices, scene sound, score) is **minimax-h3**'s seat; it also takes declared reference relationships, which suits a colour-coded cast. Native synced audio is **Veo**'s niche. seedance-2.5 carries the reference-video capacity. Route per `slates-model-selection` and read the chosen model's prompting skill before writing the audio block.\n\n## Checklist\n\n- [ ] Colour→character mapping written down and pasted into the prompt\n- [ ] Heads not animated in the blocking\n- [ ] Seating stated as a geography rule\n- [ ] Foreground owner named per cut\n- [ ] Mirror-is-not-a-swap clause present if any camera faces back through the scene\n- [ ] Presence rule present\n- [ ] Ongoing business, background life and scene event all specified\n- [ ] Acting task per character, safety line included\n- [ ] Any strong emotion split into phases with a hinge timestamp\n- [ ] Dialogue-never-creates-shots and off-screen-voices rules present\n\n## Related\n\n`slates-previs-blocking` · `slates-camera-language` · `slates-blocking-to-prompt` · `slates-character-identity` (the sheets) · `slates-prompting-minimax-h3`\n",
|
|
7
10
|
"slates-direct-response-ad": "---\nname: slates-direct-response-ad\ndescription: Build a 30-second hyper-motion direct-response ad in Slates from a product image and brief. Composes upload → storyboard → frame gen → motion gen → timeline → export. Use when the user drops a product image and asks for \"an ad\", \"a promo video\", \"a TikTok ad\", \"an Instagram ad\", a launch video, or any short-form direct-response video built around a product.\n---\n\n# Direct-response ad — Slates workflow\n\n🚨 **Wrong skill if a PERSON talks to camera.** This file builds a product-led hyper-motion spot — product hero frames, punchy cuts, no presenter. **A creator-style ad where a synthetic person speaks to the lens is a different discipline with an inverted rulebook (ugly on purpose, one shot per generation, plate-before-video): read `slates-ugc-influencer-ad`.** Route on the presence of a talking person, not on the platform.\n\nYou are building a 30-second hyper-motion direct-response ad. The user has handed you a product image (or product URL) and a short brief. Slates desktop is open on the second monitor; the user watches it populate as you work.\n\n**Hard rules**\n\n- Always estimate cost before generating. Use `slates_estimate_generation_cost` and surface the total.\n- All Slates generation routes through Slates Credits, period (BYOK is retired) — don't suggest \"use your own keys\" workarounds.\n- Default model: `nano-banana-2-2k`. For close-up product hero frames step up to `4k` only if the user asks.\n- Hyper-motion = punchy cuts, 4 frames in 30 seconds, ~7s each. Don't over-storyboard.\n\n## Workflow\n\n### 1. Set up the project\n- Create a project named for the product (`slates_create_project`).\n- If the user gave a product image as a file path, upload it (`slates_upload_reference_image`).\n- If they pasted base64 / a data URL, use the same op with `dataUrl`.\n\n### 2. Generate the storyboard frames\nBuild exactly 4 frames in this order:\n\n| # | Beat | Visual goal |\n|---|------|-------------|\n| 1 | Hook | Hyper-close-up of the product, dramatic light, motion blur edge |\n| 2 | Lifestyle | Real person using/wearing/holding the product, eye contact |\n| 3 | Problem→solution | The before/after moment that justifies the buy |\n| 4 | CTA | Clean product hero with mental room for an overlaid CTA in editing |\n\nFor each frame:\n1. Draft a tight 1-2 sentence prompt (visual only — no copy text in the image).\n2. Reference the product upload's URL or asset ID for visual fidelity.\n3. Call `slates_generate_image` with that prompt + reference. **You see the result inline — evaluate it.**\n4. If it's wrong: refine prompt, regenerate. If it's right: bind it as a frame in the storyboard (`slates_add_frame`).\n\n### 3. Build the storyboard\n- `slates_create_storyboard` named \"30s ad — v1\".\n- Default scene already exists. Add 3 more scenes (\"Hook\", \"Lifestyle\", \"Problem-Solution\", \"CTA\") via `slates_add_scene`, or just add all 4 frames to the default scene.\n- For each generated image, add a frame referencing the asset id (`slates_add_frame`).\n\n### 4. Hand back to the user\n- Surface estimated total credits spent.\n- Tell the user the storyboard is ready and they can either:\n - **In Slates desktop:** click each frame to generate motion (the existing UI handles motion generation).\n - **Continue here:** ask you to keep going.\n\n### 5. If they say keep going — motion, assembly, export\n- Generate motion per frame with `slates_generate_video` (`firstFrameAssetId` = the frame's asset, `background: true`), routed per `slates-model-selection` (Kling 3.0 std 8s by default; Seedance 2 for any physics-heavy beat like the hook). Submit all four, then poll `slates_get_generation_status` until each completes (1-5 min).\n- Assemble: `slates_add_clip_to_timeline` for each completed clip in beat order (Hook → Lifestyle → Problem-Solution → CTA). Verify with `slates_get_timeline`; fix order with `slates_reorder_clips`.\n- Export: `slates_export_video` to an absolute `.mp4` path (default `<slates_get_project_directory>/exports/<product>-ad.mp4`), then `slates_reveal_file` so the user sees the file.\n- Full pipeline doctrine (batch cost authorization, model mixing, multi-take selection): `slates-one-prompt-film`.\n\n## Anti-patterns\n\n- **Don't** generate text overlays in the image. Slates renders captions/CTAs at the editor stage.\n- **Don't** burn credits on slot-machine prompting. If the first generation is off, refine the prompt; don't just regenerate.\n- **Don't** skip the cost estimate. Confirm with the user above ~17 credits.\n- **Don't** invent visual specifics about the product (colors, textures, angles) that aren't in the reference image. Reference-anchored prompts only.\n\n## Voice\n\nThe ad lives or dies on the hook frame. Tight, sensory, no fluff. Match the user's brand. Default tone is \"scroll-stopping\" not \"informative.\"\n",
|
|
8
11
|
"slates-edit-and-iterate": "---\nname: slates-edit-and-iterate\ndescription: Iterate on an existing Slates asset — re-evaluate, refine prompt, regenerate or edit. Use when the user has an existing generated image in Slates and wants to \"tweak it\", \"change one thing\", \"make it warmer\", \"remove the second person\", or any other surgical refinement instead of full regeneration.\n---\n\n# Edit and iterate — Slates workflow\n\nThe user already has a generated image in Slates and wants to refine it. The vision-feedback-loop skill defines the general pattern; this skill is the specific recipe for \"I have asset X, here's what's wrong with it.\"\n\n## 🔴 The master rule — an edit is a LEAF, not a node\n\n**Never re-edit an edit. Always go back and re-edit the master.**\n\nEvery edit model silently re-renders the **whole frame**, not just the region you named. So the parts you didn't ask to change come back slightly different every pass — softer texture, drifted colour, mushier fine detail. It is barely visible after one edit and obvious by the second. Chaining edits compounds the damage and there is no way to undo it, because each generation *is* the new source.\n\nThe fix is structural, not a matter of care:\n\n- **Want two changes?** Make them in ONE edit off the master, or make them as two separate edits **both taken from the master**, then keep whichever you prefer.\n- **An edit came back wrong?** Do NOT edit the result to fix it. Discard it and re-edit the master with a better instruction.\n- **Only the changed region is worth keeping?** That is a compositing job — the edit supplies the new region, the untouched master supplies everything else.\n\nSlates records this: an edit result carries `sourceAssetIds` pointing at the asset it was made from, so **you can tell whether the thing you are about to edit is itself an edit.** Check before you edit — `[Edit]`-prefixed prompts and a populated source lineage both say \"this is a leaf; go back to its parent.\"\n\n## Workflow\n\n### 1. Pull the current asset back into context\n- The user references an asset by id, frame number, or \"the latest one.\"\n- Resolve to an asset id (`slates_list_assets` if needed).\n- `slates_get_asset_image` with that id to load it inline. **You see the image.**\n\n### 2. Identify the delta\nThe user's request is one of:\n- **Surgical** — \"remove the second figure\", \"make the sword red\", \"swap the background to a bamboo forest\".\n- **Aesthetic** — \"warmer light\", \"more dramatic\", \"softer focus\".\n- **Compositional** — \"wider shot\", \"lower angle\", \"centered subject\".\n- **Wholesale** — \"actually let's try a totally different look.\"\n\n### 3. Pick the right tool\n| Delta type | Approach |\n|---|---|\n| Surgical | `slates_edit_image` — `sourceAssetId` = the original, `prompt` = the change only (\"remove the second figure\"), not a re-description of the whole image. |\n| Aesthetic / compositional | `slates_generate_image` with the original in `referenceAssetIds` + a refined prompt. Don't re-roll from scratch. |\n| Wholesale | New prompt, no reference, fresh generation. Treat as a new brief. |\n\n**`slates_edit_image` shape:** `projectId` + `sourceAssetId` + `prompt` (the edit instruction). Default model `nano-banana-2` — the only edit model that also takes extra `referenceAssetIds`; `flux-2-max` / `seedream-5-lite` use their own edit endpoints and ignore references. The result lands as a NEW asset (prompt prefixed `[Edit]`); the source is untouched. Cost above ~17 credits gates on `confirm=true`.\n\n### 4. Generate, evaluate, decide\n- Estimate cost first.\n- After generation, the result is inline. Compare side-by-side with the original (`slates_get_asset_image` again).\n- If the delta is correct: bind to the same role (frame, character identity, etc.) the original was bound to.\n- If the delta missed: one focused refinement, then regenerate. Cap at 3 tries.\n\n### 5. Hand back\n- \"Asset updated. Frame 3 now uses {new_asset_id}.\"\n- Always note what changed and what didn't, so the user can see the surgery worked: \"Lighting shifted to warmer, composition unchanged.\"\n\n## Anti-patterns\n\n- **Don't** delete the original asset until the user confirms the new one. Slates keeps both; the user picks.\n- **Don't** mix surgical and wholesale changes in one regeneration. The user said \"make it warmer\" — don't also reframe the shot.\n- **Don't** re-generate when `slates_edit_image` would work. Edits preserve composition and identity; full regen rolls the dice.\n- **Don't** edit an edit — ever. Not once, not \"just a small one.\" Go back to the master (see the master rule above). Every attempt re-renders the full frame and the degradation is cumulative and permanent.\n- **Don't** keep re-rolling the same failed edit. If three tries off the master didn't land, the brief is wrong, not the model — check in with the user.\n",
|
|
9
12
|
"slates-model-selection": "---\nname: slates-model-selection\ndescription: Which model to pick for a given job — the routing doctrine. Read BEFORE choosing any video or image model, before quoting a plan, and before defaulting anywhere. Kling 3.0 is the general-purpose video default; Seedance 2.0 is the premium tier for anything where physics, effects, or scale remotely matter; Seedance 2.5 is a SECOND SEAT beside 2.0 (30s takes, 30 references and timestamp control, but no 4K and dearer at every shared resolution — never an upgrade); MiniMax H3 is the AUTHORED-AUDIO seat (three directable sound layers in one pass, declared reference relationships, 480p-4K) with MiniMax H3 Max beside it as a faster 768p-capped, reference-free premium; Veo 3.1 is a narrow niche (native synced audio in one gen, 16:9 or 9:16, 4/6/8s) and never the default.\n---\n\n# Model selection — the routing doctrine\n\nPick the model FIRST, deliberately, before writing a prompt or quoting a plan. Model routing is a core part of the intelligence users are paying for: the agent knows what each model is good at and which ones underperform for a job — defaulting to the wrong model burns the user's credits on a weaker result.\n\n## 🔑 The meta-rule — above the table\n\nThe tables below are a snapshot. This roster churns constantly (NB2 Lite, Omni Flash, Seedream 5 Lite, GPT Image 2 all landed recently) — **a table rots; a rule doesn't.** When the tables and this rule disagree, or when a model appears that the tables don't cover, run the rule:\n\n> **Name ONE must-preserve requirement for the shot.** Not a vibe — the single thing that, if it breaks, makes the shot unusable: this face stays this face · the fluid behaves like fluid · the text stays legible · the take stays one unbroken move.\n>\n> **Inspect the output at its intended crop.** A frame that holds up as a thumbnail can fall apart at the size it will actually be watched. For a location, look at atmosphere, material texture, and anchor objects; for a character, identity, skin, pose, and gradients.\n>\n> **Choose the model that PROVES that requirement** and leaves only failures you can afford to rerun or mask.\n>\n> **When the roster changes, repeat the evidence test.** Do not carry today's ranking forward on reputation.\n\n## Video routing\n\n| Job | Model | Why |\n|---|---|---|\n| **General-purpose — the default for most shots** | **Kling 3.0 std** | Cost-effective workhorse. Strong image-to-video: preserves identity, layout, and text from the start frame. 16:9 / 9:16 / 1:1, 3–15s. |\n| Higher visual polish, no physics demands | Kling 3.0 pro | Mid-price fidelity bump on the same strengths. |\n| Multi-character dialogue / audio co-generation | Kling 3.0 omni | Dialogue syntax, voice direction, language codes, `@element` refs. |\n| **Anything with remotely important physics** — effects, destruction, water/fire/smoke/cloth, creature motion, scale, complex simultaneous action | **Seedance 2.0** | The premium tier. Physics and effects are its whole edge; up to 9 ingredient refs, first+last frame, native 4K (4K video is Pro-only). |\n| The premium hero shot a piece hangs on | Seedance 2.0 | Spend where it shows. |\n| **One take longer than 15 seconds**, or a shot needing more than 9 image references, or an AUDIO-ONLY reference, or **beats that have to land at a named second** | **Seedance 2.5** | A SECOND SEAT beside 2.0, never an upgrade: 4–30s in one take, 30 image + 10 video + 10 audio references, audio-only refs, and the only Seedance seat that **acts on timestamps** (rules in `slates-prompting-seedance-2-5` § Timestamps) — 480p / 720p / 1080p, **no 4K**, and **dearer than 2.0 at every shared resolution** (720p $0.231/s vs $0.15/s, +54%). If you want 4K, or the same resolution cheaper, stay on 2.0. 🚨 Two live hazards: (a) with references attached, the words *add / remove / replace / change / extend / continue* make it reclassify the request as a video EDIT and fail AFTER the job queues — describe the finished frame, or use `seedance-2.5-edit`; (b) LENGTH is the price dial, not resolution — a 30s 720p face gen is 489 credits and a 30s 1080p faceless gen is 614, against a 1,000-credit welcome grant. Quote before any take over ~10s. |\n| **The SOUND has to be directed, not just present** — a specific line delivered a specific way, scene sound that has to sit under it, and score that must stay out of the characters' world | **MiniMax H3** | The only seat where audio is authored in three separate layers in ONE pass (synchronised events in the body, ambience in a soundscape section, audience-only score in its own) rather than toggled on. 5–15s, 480p / 768p / 2K / 4K, 24fps, 32kHz stereo, 11 languages. Rules in `slates-prompting-minimax-h3`. |\n| **A reference has to keep a DECLARED amount of itself** — especially moving one subject's characteristic onto a *different* subject | **MiniMax H3** | The only seat that understands a stated retention relationship (kept whole / kept in part / transferred onto another subject / loose echo). 9 images + 3 video + 3 audio, 12 files total. 🚨 The first 5 reference images are free and every one after that costs 4 credits — pass `referenceImages` to `slates_estimate_generation_cost` before a reference-heavy job. |\n| **Turnaround is the requirement** on a text-to-video or start-frame shot at 480p/768p | **MiniMax H3 Max** | fal's self-hosted post-train of H3. **Measured 2026-08-27: a 5s 768p clip finished in 4.8s against 57s on base H3 — about 12x faster**, same prompt, queue to file. When turnaround is the requirement this is not a marginal win. 🚨 It is the PREMIUM seat, not a cheap H3 — $0.080/s at 768p against base H3's $0.060/s, 33% more, and it tops out at 768p. It still animates a start frame and an end frame — image-to-video is one of the two things it is for — but it has no reference-to-video endpoint, so the omni-reference set (9 images + video + audio) is base-H3 only. Never the default; never reach for it to save money. |\n| Native synchronized audio (dialogue + SFX generated WITH the video in one gen), 16:9, ≤8s | Veo 3.1 | Narrow, and now narrower: if the sound needs DIRECTING rather than merely existing, MiniMax H3 is the better seat. |\n\n### Named Seedance escalation triggers\n\n\"Physics matter\" is an abstract category and it under-fires. These are the beats Seedance is **observably** good at — if the shot contains one, escalate without deliberating:\n\n- **Real-time → slow-motion contrast.** The signature beat; nearly every strong clip rides it.\n- **The camera moving while debris, meteors, sparks or particles crash around the subject.** Distinctly a feature of this model, not just a thing it survives.\n- **Massive scale that has to read as genuinely huge** — not \"a big thing\", a thing whose size is the point of the shot.\n- **One continuous unbroken take.**\n\nConcrete beats route better than an abstract category. Cost stays a tiebreaker, never the router (see below).\n\n## Video EDIT routing (changing an existing clip)\n\n| Job | Tool | Why |\n|---|---|---|\n| **Footage-synced VFX on real footage** — add/remove an effect, prop, or lighting change while the take stays the take (incl. talking heads) | **Omni Flash Edit** (`slates_edit_video`, `omni-flash-edit`) | **The edit-fidelity winner** (head-to-head receipt 2026-07-09, WITH a short prompt): lip movement held perfectly, audio near-identical, effect landed and released on cue — where Kling missed an action beat and drifted lips. Prompt-only, 3–10s clips, 720p out, ~6.4 cr/s (cheapest). Quirk: occasional tail jitter / doubled final speech beat — trim the tail on the timeline. Fidelity is EARNED by prompt discipline: one short line + \"Keep everything else the same\"; long prompts destroy it (see below). |\n| **Identity swap needing reference images** — put @marcus into the clip, lock a style from refs | **Kling O3 Edit** (`slates_edit_video`) | The only edit engine that takes element/style reference images (frontal + angles lock identity). ~19¢/s. |\n| **Spoken words must be bit-exact** (VO, legal copy, music) | **Kling O3 Edit** with `keepAudio` (default true) — or segment-splice | Kling keeps the ORIGINAL audio track verbatim — but re-synthesizes the video, so lips can drift slightly against it (7/09 receipt). Omni Flash regenerates audio (voice editing unsupported): on the 7/09 receipt it came back near-identical with perfect lips, but \"near-identical\" is not a guarantee. Zero-risk path for critical audio: segment-splice — edit only the non-talking seconds and keep the original track under the cut. |\n| Style-transfer-heavy re-imagining, full relocate of the scene, or edit quality worth a premium at 1080p+ | Seedance edit/relocate (`videoReferenceAssetId` on `slates_generate_video`) | Seedance's strength is transfer intensity; it re-generates rather than surgically edits. Head-to-head receipt 2026-07-09 (photoreal-insert job, same clip): at 720p it LOST to Omni Flash edit on result while costing ~3× (vref bills input+output seconds; face-lane rates when people are in frame). Route here for its strengths or at 1080p/4K where its ceiling is higher — never as the cheap default. (2.5's relocate lane reaches 1080p too as of 2026-08-24, at $0.2457/s of combined input+output.) Takes long descriptive prompts fine (no Omni-style hard-fail on timing phrasing). |\n| **A clip LONGER THAN 15 SECONDS** | **Seedance 2.5 Edit** (`slates_edit_video`, `seedance-2.5-edit`) | The only edit engine that takes a 4–30s clip — length is the whole reason to route here. 480p/720p/1080p out, native audio, prompt + clip only (no reference images). Output length AND aspect ratio follow the source, so the billed key is the ceiled source length; an edit bills roughly DOUBLE a plain 2.5 generation of the same length because every provider charges an edit on input + output seconds. Set `seedanceFace: true` when a face is visible — the faceless provider blocks faces outright. No consented-real-face route for editing. Inside 15s, choose on fidelity instead. |\n| AI-edit the user's OWN footage | Omni Flash Edit (3–10s), Kling O3 Edit (3–15s, 720–3840px) or Seedance 2.5 Edit (4–30s) | Both take any MP4/MOV — not just Slates gens. Phone footage MUST be rotation-normalized first (players honor the rotation flag; models don't — raw portrait phone clips come back SIDEWAYS). |\n\n- **Edit before re-roll.** A re-roll gambles away the parts the user already likes; an edit changes only what the prompt names. Quote the edit first when a clip is mostly right.\n- **Ship via segment-splice.** Every edit model re-synthesizes the whole clip, so fidelity risk scales with clip length. For real deliverables: trim out ONLY the seconds where the change happens, edit that segment, splice it back over the original on the timeline with the ORIGINAL audio underneath. Most of the final video stays the untouched original — that's how the polished split-screen demos going around actually work, plus gesture-only beats with voiceover laid over in post.\n- **One change per pass, short prompts.** On Omni Flash this is documented law (\"overly descriptive prompts can lead to unintended changes\" — long identity-lock preambles make drift WORSE, receipt 7/09); on Kling multi-beat instructions get dropped. Chain passes instead.\n- Edited clips are themselves editable clips — chain passes; lineage links each output to its parent.\n\n## Motion Transfer & Lip Sync routing (Kling-only tools)\n\nBoth tools are **Kling-only**. Every entry in them is a real Kling endpoint that bolts motion or lip movement onto a finished source as a dedicated post-process.\n\n| Job | Tool | Why |\n|---|---|---|\n| Motion retarget onto a still character | Kling MC std/pro (`slates_generate_motion_transfer`) | Structured skeleton/depth retarget, ~32–42 credits / 5s, takes up to 30s driving clips. |\n| Re-voice a clip, or animate a still portrait | Kling lip-sync / avatar (`slates_generate_lip_sync`) | ~4–29 credits / 5s blocks. |\n\n**Want the Seedance version of either?** It is not a switch on these tools — it is a normal `slates_generate_video` on `seedance-2` with the clip attached as a **video reference** and the motion or dialogue written into the prompt (\"the character from image 1 performs the exact motion from video 1\"). That routes to the same endpoint the tool would have called, with the prompt visible and editable instead of ghost-written. Single-pass conditioning genuinely beats post-hoc retargeting on fast choreography, contact, cloth and hair — and it carries native audio — so escalate there whenever fidelity matters.\n\n- Seedance video-reference gens bill COMBINED input+output seconds (`seedance-2*-vref-*` keys) — pass the clip duration and quote before confirming. Driving clips must be 2–15s on Seedance 2.0 and up to 30s on 2.5; past that it is Kling MC's lane.\n- Faces on that route go through the normal cascade: `seedanceFace` for a character, `[REAL_FACE_DETECTED]` → `seedanceRealFace` + `realFaceConsent` for a real person (premium realface pricing).\n\n**Rules:**\n\n- **Default video = Kling 3.0 std.** Escalate to Seedance the moment the shot has physics/effects weight or is the hero moment — and say why in the plan (\"physics-heavy, routing to Seedance\").\n- **Veo is never the default.** 16:9 or 9:16 only, 4/6/8s only (and 8s only at 1080p/4K, or with reference images), and it is not the quality pick — treat it as a single-purpose tool for native-synced-audio shots. If audio can be added after (Kling lip-sync, edit stage), prefer Kling or Seedance + audio in post.\n- **9:16 vertical → Kling or Seedance by preference**, not by necessity: Veo does take 9:16 on the route Slates uses. Route away from it because it is the niche seat, not because it can't.\n- **Ratios and durations are enforced before submit.** `slates_generate_video` validates the aspect ratio, resolution and duration against the model you picked and refuses out-of-set values with the legal list — it will not silently ignore or downgrade them. The authoritative per-model sets are in the op's own param descriptions, which are generated from the capability SSOT; prefer those over any list written in prose here.\n- **Image-to-video from an NB2 start frame** (the standard pipeline) → Kling by default, Seedance when the motion is physics-heavy. Not Veo.\n- **User names a model explicitly → use it.** But if it's a mismatch for the job (crazy physics on Kling std, a 30s take on anything but Seedance 2.5, 4K on Seedance 2.5 which has none), say so in one line and offer the right route before generating.\n\n## Image routing\n\n**Video models (Kling, Seedance, Veo) cannot generate standalone images — ever.** A \"premium hero reference image\" is still an image job: it routes to an image model below, never to Seedance.\n\n- **Default: Nano Banana 2** — best reference handling (14 refs), best legible text, the standard start-frame generator.\n- **NB2 Lite** — the fast/draft seat: ~half NB2's price, ~2.7× faster, 1K only. Route iteration volume and drafts here; finals go back to NB2 full (2K/4K).\n- **Nano Banana Pro** — the hero-frame/typography ceiling (~2× NB2). NB2 ≈ 95% of Pro; escalate only when spatial composition, cinematic lighting/skin, fine typography-in-scene, or deep multi-element frames must be perfect. Up to 14 refs — feed it a full subject library.\n- **GPT Image 2** — readable text / panels / UI king: character sheets, shot grids, diagrams, text-bearing panels. **Also the photoreal front-runner (Eric, 2026-08-24)** — at `quality: high` it beat both Nano Banana rails head-to-head on skin realism, which is why the AI-influencer ad lane generates every plate here. Medium is the value seat (half NB2's price at 1080p); **high is the seat for photoreal skin and for text precision**. 4K at both tiers is API-only — even paid ChatGPT can't render it.\n- **FLUX.2 Max** — photoreal texture, hex-color binding, typography, less censored.\n- **Seedream 5 Lite** — uncensored + any-resolution flat price; volume exploration when the Gemini filter is in the way.\n\n**Split rule of thumb:** readable text / panels / UI **and photoreal people** → GPT Image 2 (`high` for photoreal); edit-heavy work, or anything needing the 14-reference ceiling → the Banana line; drafts → NB2 Lite; uncensored or odd resolutions → Seedream/FLUX.\n\n⚠️ **This line said the opposite until 2026-08-24** — it sent photoreal *away* from GPT Image 2 on reputation, which is the exact failure § The meta-rule above warns about. Re-run the evidence test when the roster moves.\n\n## Audio routing\n\n**Image and video models cannot generate standalone audio, and neither audio model can generate images or video.** A shot that needs synced audio generated WITH the picture is still a video job (Kling omni / Veo / Omni Flash / Seedance all carry native audio); the models below produce audio *as its own asset*, to lay on the timeline.\n\n| Job | Model | Why |\n|---|---|---|\n| **Default — a whole audio scene in one pass**: room tone, ambience beds, crowds, nature, layered dialogue + effects, spoken lines | **Seed Audio 1.0** (`seed-audio`) | One plain sentence in, a complete scene out. 1–120s. The continuity-bed workhorse and the only speech surface. |\n| **One effect that lands on a known frame**, or a seamless loop | **Sound Effects v2** (`eleven-sfx`) | The only surface with an exact duration control (0.5–22s) and a real loop mode. |\n\n**There is no music model and no cast-voiceover model.** A song is imported (Slates reads audio files and puts them on the timeline), not generated. A line that has to be spoken is generated on Seed Audio and lip-synced against.\n\n### Named audio escalation triggers\n\n- **\"It needs to sound like a place\"** → Seed Audio. Three separate SFX generations layered on the timeline is the wrong shape and costs more.\n- **\"Read this line\"** → Seed Audio, with the line in quotes inside the scene sentence. Re-roll until the take is right, then lip-sync against it.\n- **\"That needs a thump right there\"** → Sound Effects, with the duration set to roughly the length of the event.\n- **\"Give it a track\"** → there is no music generation. Say so and offer to lay an imported track on an audio track.\n\n**Rules:**\n\n- **🚨 Seed Audio has NO duration parameter.** Length comes from the prompt text, so Slates writes the requested duration into the prompt and **bills what you asked for**. Choose the duration deliberately and never write a second, different length into the sentence. Full doctrine: `slates-prompting-seed-audio`.\n- **Kling's audio syntax does not transfer.** `SFX:` / `Ambient noise:` / `Background music:` prefixes are Kling 3.0 *video* prompt syntax. Seed Audio reads them as literal words and the result degrades.\n- **Beds outlast the cut.** Always ask for more seconds than the clip needs so the edit has fade handles — and remember those extra seconds are billed on both surfaces.\n- **Audio inside the video vs audio as an asset.** If the sound must be locked to what happens on screen, generate it with the video (Kling omni / Seedance / Omni Flash / Veo). If it needs to be moved, trimmed, re-used, or layered, generate it here and drop it on an audio track.\n- Per-model prompting: `slates-prompting-seed-audio`, `slates-prompting-elevenlabs`.\n\n## Cost is a tiebreaker, not the router\n\nRoute by capability first, then pick the cheapest tier that serves the job (per `slates-cost-discipline`). Never pick a model because its per-second price looked lowest — a cheap clip that has to be regenerated on the right model costs more than routing correctly once.\n",
|
|
10
13
|
"slates-one-prompt-film": "---\nname: slates-one-prompt-film\ndescription: The full one-prompt-to-finished-film pipeline in Slates — script, project, characters, storyboard, frame images, video generation, timeline assembly, MP4 export. Use when the user gives one idea and wants a finished video out the other end - \"make me a video about X\", \"turn this idea into an ad\", \"make a short film from this\", \"one prompt, finished film\". This is the master recipe; other Slates skills are its sub-steps.\n---\n\n# One prompt → finished film — Slates master pipeline\n\nThe user gives an idea. You hand back an MP4 on disk. Everything in between is yours, with exactly TWO mandatory user checkpoints: the creative plan, and ONE aggregated cost approval.\n\n## The pipeline\n\n### 1. Script the beats\nTurn the idea into a beat-level script: 4-10 shots, each with subject, action, setting, camera, and duration (4-8s per shot). Surface it as a tight table. Get the user's nod on the plan, format (aspect ratio — 16:9 vs 9:16 decides everything downstream), and rough budget appetite before touching any op.\n\n**Surface a decision log with the plan.**\n\n<!-- @inject:decision-log -->\nWhen you surface the plan, include a short **decision log** — one line per decision *you* made that the user did not specify:\n\n```\nsource phrase or declared default → what you wrote → what it resolves\n\"in a diner\" → chrome-and-vinyl booth, 3/4 on the counter → fixes the anchor so blocking is repeatable\n(no time of day) → late afternoon, low warm key → default; say the word and it changes\n(no camera) → slow push-in, single move → one move per shot; stacking increases instability\n```\n\n**Hard rule: never silently add weather, props, style, or camera movement.** If it wasn't in the brief and you added it, it goes in the log. This is the \"why did you add that?\" affordance — for an agent that writes prompts on the user's behalf and spends their credits, it is what keeps the model in assembly and the user in the director's chair.\n\n> ❌ **Do NOT turn this into a question gate.** Clarifying questions before optimizing directly fight the locked fast-path rule: *if intent is clear, generate immediately with sane defaults, don't ask questions; only ask for production intent, and batch every question into one message.* Log the decisions, then go. The log is an **output**, not an interrogation — surfaced alongside the plan, never as a separate ceremony, and never as a reason to wait.\n<!-- @end:decision-log -->\n\nA 4-10 shot script is where you invent the most on the user's behalf — time of day, wardrobe, weather, lens feel, camera moves the brief never mentioned. The log is what makes those visible while they are still free to change.\n\n### 2. Set up the project\n- `slates_create_project` named for the piece.\n- Recurring character? Build it properly — `slates_create_character` + the `slates-character-identity` recipe — so every frame references the same identity.\n- Recurring location? `slates_create_environment`.\n- One-off shots don't need character/environment records; skip the ceremony.\n\n### 3. Storyboard skeleton (no generation yet)\n- `slates_create_storyboard`, `slates_add_scene` per script scene.\n- Structure first, spend second — the user catches script problems on the free skeleton, not on burned credits.\n\n### 4. ONE aggregated cost approval — then hands-off\nPrice the whole batch before the first generation: frame images (count × model — `slates_estimate_generation_cost`) + video gens (count × model × duration). Present a single total:\n\n> Plan: 6 frames at 1k 16:9 + 5 × 8s Kling 3.0 std + 1 × 8s Seedance 2 hero shot ≈ $X.XX total. Proceed with the batch?\n\nPer `slates-cost-discipline` 3b: that single OK authorizes `confirm=true` for **every enumerated call in the batch** — no per-call re-asking. Re-confirm only if a call's price overruns the plan >25% or new calls get added (extra retakes, new shots).\n\n### 5. Generate frame images\nPer shot: `slates_generate_image` with `referenceAssetIds` pointing at the character identity / environment / prior frames for consistency (Slates names each reference inline as \"image N\" — you don't hand-write role labels; reuse the same subject name across shots). Evaluate every result inline against the beat. Bind keepers via `slates_add_frame`.\n\n**Multi-take where it matters:** for the hook shot and any shot the whole film hangs on, generate 2-4 variants (cheap model or 1k), pull them back with `slates_get_assets_batch`, pick the strongest on composition + identity, discard the rest. Don't multi-take filler shots.\n\n### 6. Generate video per frame — background mode\n`slates_generate_video` with `firstFrameAssetId` = the bound frame, `background: true`. Submit ALL shots, collect the generationIds, then poll `slates_get_generation_status` every 10-15s (1-5 min per gen; they survive app restarts). This parallelizes a 6-shot film into one wait instead of six.\n\n**Model mixing — route per `slates-model-selection`** (details in the per-model guides):\n- **Kling V3** (`slates-prompting-kling-v3`): the DEFAULT for most shots — 16:9 / 9:16 / 1:1, 3-15s, strong start-frame adherence; std is the workhorse, Omni for multi-character dialogue.\n- **Seedance 2** (`slates-prompting-seedance`): the PREMIUM tier — any shot where physics/effects/scale remotely matter, plus the hero shot; audio included, first+last frame guidance, native 4K (4K video is Pro-only).\n- **MiniMax H3** (`slates-prompting-minimax-h3`): route here when a shot's SOUND is part of the writing — a line delivered a particular way, scene sound under it, score that must stay outside the characters' world. It authors all three in one pass, which **collapses a shot's audio pass into its video pass** and removes the separate `slates_generate_audio` step for that shot. 5-15s, 480p/768p/2K/4K. Its sibling `minimax-h3-max` is faster but capped at 768p, takes no references, and costs MORE at 768p — a deliberate speed pick, never a saving.\n- **Veo 3.1** (`slates-prompting-veo-3`): niche, never the default — only when native synced audio must generate WITH the video in one gen; 16:9 or 9:16, 4/6/8s (8s only at 1080p/4K or with reference images).\n\nFailed gen? Check the error via `slates_get_generation_status`, fix the prompt, resubmit that one shot (a retry beyond the plan = announce the delta cost).\n\n### 7. Assemble the timeline\n- `slates_get_timeline` once to get the lay of the land.\n- `slates_add_clip_to_timeline` for each completed video asset **in story order** — defaults append back-to-back on the first video track, which is exactly an assembly cut.\n- Order wrong? `slates_reorder_clips` with the full clip-id list. Dropped a shot? `slates_remove_clip`, then reorder to close the gap.\n\n### 8. Export + deliver\n- Output path: ask the user, or default to `<slates_get_project_directory>/exports/<name>.mp4`.\n- `slates_export_video` (absolute path, `.mp4`; blocks while ffmpeg renders — minutes for long timelines).\n- `slates_reveal_file` so the file is literally in front of them.\n- Offer the finishing path: `slates_export_timeline_xml` → DaVinci Resolve (File → Import → Timeline) for grading, sound, and titles.\n\n### 9. Report\nShots delivered, total spent vs. approved plan, the export path, and the single best next lever (\"re-take shot 3 with a tighter prompt\" / \"add a CTA end-card\").\n\n## Hard rules\n\n- **Two checkpoints only.** Creative plan (step 1) and total cost (step 4). Everything else runs without asking — that's the product promise.\n- **Skeleton before spend.** Project + storyboard structure are free; generation isn't.\n- **Look at everything.** Every image inline, every video via `slates_get_asset_video_frames` if a clip seems off. Never assemble a timeline from clips you haven't evaluated.\n- **3-strike rule per shot.** Three failed takes on one shot = stop, show the user what you tried, ask.\n- **Consistency comes from references, not luck.** Same identity asset on every character frame; same environment refs across a location's shots.\n",
|
|
14
|
+
"slates-previs-blocking": "---\nname: slates-previs-blocking\ndescription: Build a 3D blocking pass in Blender, render it grey-box, and use it as a reference video so the generated shot follows a camera path you designed instead of one the model invented. Use when the user wants precise camera control, a multi-cut sequence, a one-take move, spatial consistency across shots, or says the camera keeps drifting / they keep burning credits re-rolling.\n---\n\n# Previs blocking — design the shot, then generate it\n\nThe spine of the whole workflow. Read this first; the other four previs skills are branches off it.\n\n## The mechanism (why this works at all)\n\nA text prompt asks the model to *invent* camera motion, so it invents differently every roll. You cannot iterate on a variable you do not control, so you re-roll and pay again.\n\nA **reference video** removes the invention. You build the shot in Blender as untextured proxies — a neutral grey set with colour-coded figures, free, instant, deterministic — render the camera's path to mp4, and hand the model that clip alongside the prompt. **Blender locks the motion; the model builds the world.** Iteration moves to the free half, and the paid half usually lands first try.\n\nTwo halves, and keeping them separate is the whole discipline:\n\n| Half | Lives in | Changes when |\n|---|---|---|\n| **Structure** — cuts, camera, timing, who is where | the blocking clip | you re-block |\n| **Style** — what any of it looks like | references + prompt text | you restyle (see `slates-restyle-from-blocking`) |\n\n## Before you start\n\n1. `slates_blender_status` — confirms the bridge is up and returns fps, frame range, existing camera. If it reports `connected: false`, relay its hint and stop; nothing else here works.\n2. Settle **format first**, because the blocking render *is* the film's format: fps, aspect, duration. 24fps is the default and makes cut times land on clean frames. Duration ≤ 30s (seedance-2.5's reference-video ceiling; 15s on the others).\n3. Know the shot count. \"One take\" and \"19 cuts\" are different builds.\n\n## Build order\n\nDo these in order. Each stage is verifiable on its own, and a camera built before the geometry has nothing to frame.\n\n### 1. Set the format\n\n```python\nscene = bpy.context.scene\nscene.render.fps = 24\nscene.render.fps_base = 1.0\nscene.render.resolution_x, scene.render.resolution_y = 1920, 1080\nscene.frame_start, scene.frame_end = 1, 720 # 30s at 24fps\nresult = {\"seconds\": 720 / 24}\n```\n\nFrame maths, stated once so you never redo it in your head: **frame = seconds × fps + 1**. A cut at 7.79s is frame 188.\n\n### 2. Geometry and light — grey set, coded figures, named\n\nProxies only. A person is a box or a capsule with a sphere head. A car is a stretched cube. A can is a cylinder. **The SET is neutral grey — one light, a floor and enough wall that the space reads.** Colour is reserved for the figures, where it carries meaning (below); a grey set is what makes those few colours legible as notation rather than décor. Anything you spend on materials here you pay for twice, because the model repaints every surface anyway.\n\n**Name every object for what it *is* in the story**, not `Cube.003`. The name is how you refer to it later, and it is how you keep your own timeline honest.\n\nTwo conventions that cost nothing now and save a re-roll later:\n\n- **Colour is identity.** Give each character a distinct viewport colour and *write the mapping down* — `red = the boss, green = the kid, blue = the driver`. The generation prompt will restate that mapping so the model knows which grey body is which person across cuts. Without it, characters swap.\n- **Encode facing on featureless proxies.** A box has no front. Mark one face red, the back black, the sides green, and say so in the prompt: `RED face = the direction he faces`. Otherwise the model guesses which way people are looking.\n- **Checker a surface when SCALE or SPEED has to read.** Flat grey gives a model no parallax cue, so a fast move over a featureless floor reads as slow, and a big room reads as a small one. A black-and-white checker on the ground (or the wall a camera races past) gives it something to measure against. ⚠️ **Build it as GEOMETRY, never as a Checker Texture node.** The blocking render is Workbench, which draws one flat colour per material and never evaluates a shader node tree — a `TEX_CHECKER` comes out flat grey and you lose the cue without being told. Subdivide the plane and alternate `material_index` per face. Like every other colour here it is notation, so it goes in the translation list and gets dressed over.\n\n```python\n# Two materials, alternated per face. `TILE` is the square size in metres.\ndark = bpy.data.materials.new(\"Checker_Dark\")\ndark.diffuse_color = (0.05, 0.05, 0.05, 1.0)\nlight = bpy.data.materials.new(\"Checker_Light\")\nlight.diffuse_color = (0.80, 0.80, 0.80, 1.0)\nfloor.data.materials.append(dark) # material_index 0\nfloor.data.materials.append(light) # material_index 1\n# Subdivide first (edit mode or a Subdivide modifier applied) so there ARE\n# faces to alternate — a 2-triangle plane can only ever be one colour.\nfor face in floor.data.polygons:\n cx, cy = face.center.x, face.center.y\n face.material_index = (int(cx // TILE) + int(cy // TILE)) % 2\n```\n\nAnd the identity colour on each proxy:\n\n```python\nmat = bpy.data.materials.new(\"ID_Red\")\nmat.diffuse_color = (0.8, 0.1, 0.1, 1.0) # what the blocking render draws\nobj.data.materials.append(mat)\nobj.color = (0.8, 0.1, 0.1, 1.0) # same value, for viewport parity\n```\n\nThe blocking render pins Workbench to `MATERIAL` shading, so **`mat.diffuse_color` is the value that reaches the clip** — and an object with no material at all falls back to a neutral grey, which is why an unpainted set still reads correctly. Set `obj.color` to the same value anyway: it costs one line, it makes the user's viewport match what renders, and keeping the two equal means you never have to remember which one is authoritative.\n\n### 3. Camera\n\nThe whole of `slates-camera-language`. Build the rig, then keyframe it. Then **read back what you built** with `slates_blender_scene` — its `cutSeconds` is your cut list, and it is the number you will write timings against. That field is the authoritative one on EITHER rig — marker frames when cameras are bound to markers, the active camera's own keyframes when they are not. `camera.keyframeSeconds` is empty on a marker-bound edit, which is the rig `slates-camera-language` recommends for anything past a handful of cuts.\n\n### 4. Handheld, last\n\nAdd it after the moves are right, never before — noise on top of a wrong path just hides the wrong path.\n\n### 5. Verify the cuts\n\nThe one check that catches the most damage: on a multi-cut blocking, camera position, target and focal length must all change **exactly on the cut frame, with no transition frame between**. One interpolated frame reads as a whip-pan the model will faithfully reproduce.\n\n```python\n# Every camera f-curve keyframe on a cut frame must be CONSTANT out of the\n# previous key, or the cut smears.\nfor fc in cam.animation_data.action.fcurves:\n for kp in fc.keyframe_points:\n if int(kp.co[0]) in CUT_FRAMES:\n kp.interpolation = 'CONSTANT'\n```\n\nAlso check nothing interpenetrates — proxies through floors, clones through the hero object, letters through each other. The model renders intersections as faithfully as it renders everything else.\n\n### 6. Save a backup after every stage\n\nCheap, and blocking is iterative by nature.\n\n```python\nbpy.ops.wm.save_as_mainfile(filepath=path, copy=True)\n```\n\n## Render and generate\n\n```\nslates_blender_render_blocking { projectId, fps: 24 }\n```\n\nRenders the **scene camera** through scene settings — never the user's viewport, so the result does not depend on where they left their mouse — imports the mp4 into the project, and returns `assetId` + `durationSeconds`.\n\nThen:\n\n```\nslates_generate_video {\n model: \"seedance-2.5\",\n videoReferenceAssetIds: [<the blocking asset>],\n videoReferenceSecondsEach: [<durationSeconds>],\n characterAssetIds: [...], environmentAssetIds: [...], styleAssetIds: [...],\n prompt: <written per slates-blocking-to-prompt>\n}\n```\n\n**Four inputs, and that is the entire stack:** a character sheet each, one location/style reference, the blocking clip, and a prompt written against the blocking. Resist adding a fifth.\n\nModel note: seedance-2.5 is the seat for this — 10 reference videos at up to 30s each. seedance-2 and minimax-h3 take 3 at 15s. Route per `slates-model-selection`.\n\n## Leaving holes on purpose\n\nWhere the model outperforms any blockout you could build — liquid, smoke, fire, cloth — **block a black gap instead** and say so in the prompt: `CUT 7 (14.5-17.0, black gap in the reference)`. You are reserving a slot, not forgetting one.\n\n## What not to do\n\n- **Don't texture, light or material the blocking.** Grey is the specification. The reference supplies motion; the references supply look.\n- **Don't animate what you don't need.** Heads especially — a proxy head turning wrong is worse than one that never turns.\n- **Don't build the camera before the geometry.** It has nothing to aim at, and every value you set gets redone.\n- **Don't skip reading the scene back.** Write timings from `slates_blender_scene`'s `cutSeconds`, never from what you intended to build.\n- **Don't exceed the model's reference-video ceiling.** A 40s blocking against a 30s cap silently truncates.\n\n## Related\n\n`slates-camera-language` (rigs and moves) · `slates-blocking-to-prompt` (writing the prompt against the clip) · `slates-dialogue-blocking` (multi-character continuity) · `slates-restyle-from-blocking` (one blocking, many worlds) · `slates-model-selection` (routing)\n",
|
|
11
15
|
"slates-project-organization": "---\nname: slates-project-organization\ndescription: How a Slates project's assets are organized AND named — the asset short-code system (IMG-A12 / VID-V3 / AUD-S1 badges on every gallery card), folders for film STRUCTURE, the typed tabs for reusable references. Read when the user refers to an asset by code, asks what a code like IMG-A36 means, or when organizing/navigating a project.\n---\n\n# Organizing a Slates project\n\nSlates already gives each REUSABLE reference type its own home — the **Characters**, **Environments**, and **Styles** tabs, each with its own generation + `@mention`/`#ref` behavior. Do NOT recreate those as folders. Folders are for **structure**, never type.\n\n**Folders = where an asset sits in the FILM**, and they mirror to real subfolders on disk (`projects/<id>/…`), so a human can open the project in Resolve/Finder and navigate it like an edit. Use them for work product, not references.\n\nCreate with `slates_create_folder`; file assets with `slates_move_assets_to_folder`. Generations land in the project's active folder, so set it before a batch.\n\nConventions by project type:\n- **Short film / narrative:** `Shots` (scene stills) · `Clips` (generated video) · `Final` (the export). Use one folder per scene (`Scene 1`, `Scene 2`, …) instead when the piece has distinct locations/beats.\n- **Ad / UGC:** `Hooks` · `B-roll` · `Talking-head` · `Final`.\n\nRules of thumb:\n- Reusable cast / sets / look → leave in the Characters/Environments/Styles tabs. Don't fold them.\n- Scene stills, clips, and the final cut → file into the structural folder they belong to, as you make them.\n- One folder per asset (folders are structure). Cross-cutting status (hero take, reject, variant) is a tag concern, not a folder.\n- Keep the gallery legible: work product lives in folders; the reference scaffolding (sheets, plates, style images) stays in its tabs.\n\n## Asset codes — the shared vocabulary (IMG-A12 / VID-V3 / AUD-S1)\n\nEvery asset gets a short, stable code the moment it lands in a project, and the user sees it as the badge in the **top-left corner of every image and video card** in the gallery. This is the shared vocabulary between you and the user — it exists so neither of you ever has to quote a UUID.\n\n**The scheme:**\n- `IMG-A{n}` = images · `VID-V{n}` = videos · `AUD-S{n}` = audio.\n- Numbering is **per project, per type**, counts up from 1, and **numbers are never reused** — deleting IMG-A12 doesn't renumber anything, so a code always means the same asset forever.\n- Each asset also carries a **label**: the first ~4 meaningful words of its prompt, title-cased. Chat format is code + label: `IMG-A12 — Beach Sunset`.\n\n**How to use it:**\n- **User names a code** (\"use IMG-A36 as the reference\", \"animate VID-V3's last frame\") → resolve it via `slates_list_assets` (match the `code` field) to get the assetId, confirm back in the same vocabulary: \"Got it — IMG-A36 — Marcus Rooftop Close-Up as the first frame.\"\n- **You name assets** → ALWAYS code + label, never UUID, never \"the beach one\" (which of three?). The user matches your words to the badge by eye.\n- **User seems confused** about what a code is or how to point you at an image → explain it in one line: \"Every image and video in your gallery has a code badge in its top-left corner — like IMG-A36. Just say that code and I'll know exactly which one you mean.\"\n- **Ambiguity** (\"the sunset image\" when several exist) → pull candidates with `slates_get_assets_batch` and offer the codes: \"I see IMG-A12, IMG-A19, and IMG-A24 with sunsets — which one?\"\n",
|
|
12
16
|
"slates-prompting-elevenlabs": "---\nname: slates-prompting-elevenlabs\ndescription: How to prompt ElevenLabs Sound Effects v2 in Slates. Read before calling slates_generate_audio with model eleven-sfx — ONE short effect with an EXACT duration (0.5-22s), or a seamless loop, billed per second. Covers describing an effect by its physical cause, the one-sound-per-generation rule, picking a duration, loops, prompt_influence, and when to use Seed Audio instead.\n---\n\n# ElevenLabs Sound Effects v2 — prompting\n\nOne short sound with an exact length, carried on fal (`fal-ai/elevenlabs/sound-effects/v2`). This is the only Slates audio surface with a real duration control and a real loop mode.\n\n## Where it routes\n\n- **A single hit that has to land on a known frame** — door slam, whoosh, impact, UI blip, riser.\n- **A seamless loop** you can lay under a whole scene — rain, engine hum, crowd murmur, machine noise.\n- **NOT** layered scenes. A room with dialogue *and* clatter *and* ambience is one `seed-audio` pass, not three SFX generations.\n- **NOT** speech. Dialogue, narration and scratch VO are `seed-audio` — it casts and performs the line inside the scene.\n- **AUDIO-ONLY.** It cannot produce images or video.\n\n## THE RULES\n\n### 1. Describe the physical CAUSE, not the label\n\n```\n✗ door sound\n✓ heavy oak door slams shut in a stone hallway\n\n✗ whoosh\n✓ a thick rope swung fast past a microphone, low air displacement\n\n✗ footsteps\n✓ boots on wet gravel, slow, one person\n```\n\nMaterial + weight + surface + room. Naming all four is the difference between a usable effect and a stock-library shrug. Cap is 450 characters — you will not need them.\n\n### 2. One sound per generation\n\nThis surface makes a single event. A door, then footsteps, then a siren is three generations layered on the timeline — or one `seed-audio` scene, which is usually cheaper and always more coherent.\n\n### 3. Duration is always explicit, and it is the price\n\n`durationSeconds` is 0.5–22 and Slates **always sends it**. (Left null the model picks, which makes the charge non-deterministic — so it is never left null.)\n\n| Kind of sound | Ask for |\n|---|---|\n| impact, hit, click | 0.5–1s |\n| whoosh, riser, transition | 2–4s |\n| loopable bed | 8–22s + `loop: true` |\n\nOver-asking pads the tail with room tone you then trim. Under-asking clips the decay.\n\n### 4. Loops\n\n`loop: true` tiles without a seam — rain, engine hum, crowd murmur, machine noise. Combine with a longer duration so the loop point is not obvious.\n\nFor a bed longer than 22s, this is the wrong surface: `seed-audio` runs to 120s in one pass.\n\n### 5. Prompt influence\n\n`promptInfluence` 0–1, default 0.3. Higher hugs your wording with less variation between takes; lower explores. Raise it when a re-roll keeps wandering off the brief; lower it when every take sounds like the same take.\n\n## Iterating\n\n- Re-rolls that keep missing = the prompt named a **label** instead of a **cause**. Rewrite it as a physical event.\n- A hit that lands but sounds wrong in the scene is usually a *room* problem — name the space (\"in a stone hallway\", \"in a padded studio\", \"outdoors, no reflections\").\n- Three failed takes means the prompt is wrong, not the seed.\n\n## Content notes\n\nElevenLabs applies its own moderation. See slates-content-policy.\n",
|
|
13
17
|
"slates-prompting-flux-2-max": "---\nname: slates-prompting-flux-2-max\ndescription: How to prompt FLUX.2 Max (Black Forest Labs image model). Read before calling slates_generate_image with model flux-2-max, or slates_edit_image with editModel flux-2-max. FLUX.2 wants front-loaded structure, real camera vocabulary, and positive-only phrasing — no negative prompts, no tag soup.\n---\n\n# FLUX.2 Max — prompting\n\nBlack Forest Labs' top image model, routed via fal.ai. In Slates: `slates_generate_image` with `model: flux-2-max` (REQUIRES projectId — no headless path), priced per resolution (1k/2k/4k — call `slates_estimate_generation_cost` for current numbers, never quote from memory). Strengths vs Nano Banana 2: photoreal texture, less censored, precise hex-color control, strong typography. Reference images route through FLUX's edit endpoint and carry a lower per-model cap than NB2's 14.\n\n## Core structure — front-load what matters\n\n```\nSubject + Action + Style + Context\n```\n\nWord order is weight. FLUX.2 attends hardest to the start of the prompt: main subject → key action → critical style → essential context → secondary details.\n\n**Length:** 10-30 words for concept tests, 30-80 words for most work, 80+ only for genuinely complex scenes.\n\n## Photorealism: name real gear, not \"professional photo\"\n\nThe single biggest realism lever is concrete camera vocabulary:\n\n```\nShot on Hasselblad X2D, 80mm lens, f/2.8, natural lighting\nShot on Sony A7IV, 35mm, golden hour, shallow depth of field\nKodak Portra 400, natural grain, organic colors\n```\n\nEra cues work the same way: \"early digital camera, slight noise, flash photography, candid\" reads 2000s digicam; \"film grain, warm color cast, soft focus\" reads 80s.\n\nFor portraits add: natural skin texture, realistic pores, subtle imperfections, soft diffused lighting.\n\n## No negative prompts — reframe positively\n\nFLUX.2 has no negative prompt support. Describe the presence you want, not the absence:\n\n- ❌ \"no blur\" → ✅ \"sharp focus throughout\"\n- ❌ \"no people\" → ✅ \"empty scene\"\n- ❌ \"no harsh shadows\" → ✅ \"soft, diffused lighting\"\n\n## Hex colors — bind them to objects\n\nFLUX.2 matches hex codes, but only when each code is attached to a specific object:\n\n```\nwalls in hex #C4725A, sofa in #1B6B6F, accent pillows #E8A847\ngradient starting with color #02eb3c and finishing with color #edfa3c\n```\n\n❌ \"use #FF0000 somewhere\" — unbound colors land inconsistently.\n\n## Text rendering\n\nQuote the exact text, then place and style it:\n\n```\nThe text 'OPEN' appears in red neon letters above the door\nLogo text 'ACME' in color #FF5733, ultra-bold decorative serif, centered\n```\n\nSpecify placement relative to other elements, font family feel (serif / sans / script), and relative size (\"large headline,\" \"small body copy\").\n\n## JSON prompting for production work\n\nFor multi-element scenes that must come out exactly right (product shots, infographics, brand work), FLUX.2 parses structured JSON prompts:\n\n```json\n{\n \"scene\": \"Professional studio product photography on polished concrete\",\n \"subjects\": [{ \"description\": \"matte black ceramic mug with steam\", \"position\": \"center foreground\" }],\n \"style\": \"commercial product photography\",\n \"color_palette\": [\"#1B1B1B\", \"#E8A847\"],\n \"lighting\": \"three-point softbox, soft diffused highlights\",\n \"camera\": { \"lens-mm\": 85, \"f-number\": \"f/5.6\" }\n}\n```\n\nUse natural language for exploration, JSON when the layout is locked and you're matching a spec.\n\n## Reference images (edit path)\n\nIn Slates, pass `referenceAssetIds` on `slates_generate_image` — FLUX routes them through its edit endpoint. Slates names each reference inline in the prompt (\"the subject (image 1), the style (image 2)\") in the order it sends them, so you don't hand-write role labels; the name carries the role and unnamed-by-position blending is avoided. For surgical changes to one existing image use `slates_edit_image` with `editModel: flux-2-max` (note: FLUX edits ignore extra referenceAssetIds — that's NB2-only).\n\n### Reference rules (the verified ones)\n\n<!-- @inject:references-read-literally -->\n> **The general law: the model reads a reference literally.**\n> A reference image is not a suggestion. Whatever is baked into it — lighting, medium, texture, symmetry, competing identities — is read as a **property of the subject** and reproduced downstream. A baked rim light tints every shot made from that sheet. A sheet that looks like a 3D game render gets animated like game footage. Two competing renderings of one face get averaged into a third face.\n\nEvery reference rule below is a corollary of that one sentence, which is why \"prep the reference\" beats \"prompt around the reference\" every time:\n\n- **Flat, plain identity refs** — because scene lighting in the sheet becomes scene lighting in the output (Slates' own receipt: a studio-lit sheet produced a subject that looked green-screen-pasted in front of mountains).\n- **One authoritative rendering per subject** — because the model cannot tell which panel is the real one. ByteDance documents this failure directly: multi-view character assets \"confuse the model's character recognition, causing it to generate duplicate characters of the same appearance.\"\n- **No 3D-game-render look in a reference** — the model recognizes the render mood and inherits its motion character, so the *animation* comes out looking like game footage. This is not a taste rule; it is the same literal-reading mechanism applied to the temporal layer.\n- **Break perfect symmetry** — mirrored faces and dead-square framing read as synthetic, and the model preserves that reading rather than correcting it.\n\n**What this means in practice:** when output is wrong in a way that tracks the *subject* rather than the *scene* — the lighting is wrong the same way in every shot, the face drifts, the material looks synthetic everywhere — fix the reference, not the prompt. Prompting around a baked-in property is the expensive way to lose.\n<!-- @end:references-read-literally -->\n\n<!-- @inject:reference-rules-core -->\nIdentity = a few flat-lit neutral angles; one reference per role, named inline; 2-4 refs not 12; describe environments instead of feeding a grid.\n\n1. **2-4 strong references beat both extremes.** Not 1 (warps toward itself), not 12 (averages worse). Start with 2-3 focused refs — each one adds context AND another variable to balance.\n2. **One reference per ROLE, named in the prompt** — identity / style-grade / environment. The model does **not** infer a reference's role from its position in the list; the inline name carries it. Same-role competitors drift (two \"identity\" refs of different people blend into a third face). Slates composes the naming for you from your `@mentions` / `#tags` — you never hand-write role labels.\n3. **One identity sheet per character, named inline.** A character's identity is a single asset (dominant portrait + body panels), so attach that one asset rather than a pile of views: **fewer competing renderings of a face is better, because the model cannot tell which one is authoritative and averages them.** Slates cites it as `Marcus (image 1)`. **Do NOT hand-write a \"Reference Image Instructions\" block or role essays** (\"use for identity, ignore the outfit, render a neutral expression\") — that drags the sheet's studio lighting and wardrobe into a scene that asked for neither. The prompt leads; the user's words own wardrobe, expression, lighting, and action.\n4. **Flat-light identity refs.** Prep identity references with flat, even, shadowless lighting on a plain neutral background. A studio-lit or scene-lit character sheet bleeds its lighting into every generation — the failure looks like the subject was green-screen-pasted in front of the location. Reference prep beats prompting here.\n5. **Environment: describe it, don't feed a grid.** Default to describing the location in words and let the model build a space that fits the shot. Reserve an environment reference for a mandatory exact-match, and then use ONE clean establishing image with natural ambient light that reads as the location's real light — never a multi-panel grid fed whole.\n6. **Grids: explore, don't input.** Use grids to explore compositions cheaply, then pick a cell. Never feed a grid back in as a reference — the cells share a split detail budget and were generated jointly, so their flaws propagate.\n7. **Reuse the same refs across every shot** in a sequence. Lock a set and keep it; swapping references mid-sequence causes drift, because the model adapts each reference to the current prompt rather than copying it.\n8. **Legible in-shot text → bake it into a still start frame, never trust text-to-video.** Have an image model render the text, then animate from that locked frame. Video models smear type.\n9. **Working from existing media — describe ONLY what changes.** The source already carries its composition, motion, timing, and performance; re-describing them fights the model. Narrate the delta. (Video lane: restyle your own clip while keeping the performance; delayed-VFX on \"video one\"; marker-object insertion; video-as-reference for a series.)\n10. **Style transforms happen in natural language.** By default the source's artistic medium and visual style are inherited. To change it, add a plain-text instruction (\"anime → real person\"). There are no preset pickers, and there is no style slider.\n<!-- @end:reference-rules-core -->\n\n### For FLUX.2 Max specifically\n\n- **FLUX caps references well below NB2's 14, so rule 1's \"2-4\" is a ceiling here, not a starting point.** Be deliberate about which roles earn a slot.\n- **Rule 9 has a hard edge on this model:** `slates_edit_image` with `editModel: flux-2-max` ignores extra `referenceAssetIds` — that is NB2-only. A FLUX edit sees the source image and the prompt, nothing else.\n- **FLUX has no memory between generations, so rule 7 is enforced by repetition.** Define the character exhaustively once and repeat those exact descriptors verbatim in every subsequent prompt — see Character consistency across a series below.\n\n## Character consistency across a series\n\nDefine the character exhaustively once, then repeat those exact descriptors verbatim in every subsequent prompt. FLUX has no memory between generations — the repeated description IS the consistency mechanism.\n\n## Common failure modes + fixes\n\n| Failure | Fix |\n|---|---|\n| Generic \"AI look\" on photoreal | Name a camera body + lens + f-stop instead of \"professional photo\" |\n| Colors drift from brand spec | Bind each hex code to a named object |\n| Text garbled | Quote the exact string, specify font feel + placement + size |\n| Multi-reference blend chaos | Name each reference inline (Slates does this from your @mentions/referenceAssetIds) — the same name for one entity, distinct names per role |\n| Wanted element missing | Move it earlier in the prompt — order is weight |\n\n## Pre-flight: references arrive inline, refer by code\n\nWhen you pass `referenceAssetIds`, the first call returns the references **inline as image content blocks** with a cost estimate and `requires_confirm: true`. Look at them — revise the prompt if they suggest a different composition or style — then re-call with `confirm=true`. Refer to each asset by its short code (`IMG-A12 — Beach Sunset`) when talking to the user; it matches the badge on their gallery thumbnail.\n\n## Sources\n\n- [Black Forest Labs — FLUX.2 Prompting Guide](https://docs.bfl.ml/guides/prompting_guide_flux2)\n- [fal.ai — FLUX.2 [max] Prompt Guide](https://fal.ai/learn/devs/flux-2-max-prompt-guide)\n",
|
|
@@ -23,6 +27,7 @@ export const SKILLS = {
|
|
|
23
27
|
"slates-prompting-seedance": "---\nname: slates-prompting-seedance\ndescription: How to prompt Seedance 2.0 (ByteDance video model). Read before calling slates_generate_video with model seedance-2. Seedance 2.0 structures multi-beat prompts as a \"Shot 1 / Shot 2 / Shot 3\" storyboard against an 8-slot advanced formula — never per-second time stamps, which 2.0 does not respond to (Seedance 2.5 does; see slates-prompting-seedance-2-5). Its syntax differs from Kling, Veo and the image models; don't cross-pollinate (in particular, no lens / aperture / film-stock vocabulary).\n---\n\n# Seedance 2.0 — prompting\n\nByteDance's video model — first-party via **BytePlus ModelArk** (credits only, no BYOK). Audio always generated alongside the video. Single model `seedance-2` across the full resolution ladder (480p / 720p / 1080p / native 4K — 4K video is Pro-only, default 1080p), 4–15s, first+last frame, and up to 9 reference images / 3 videos / 3 audio clips.\n\n> **How to read this file.**\n> **[official :NNNN]** — ByteDance's own BytePlus ModelArk prompting guide, line `NNNN` of the archived doc dump (`research/seedance-2-modelark-docs.md`). Receipt-grade; treat as law.\n> **[community]** — third-party guides and our own field notes. Useful, but an `[official]` block always wins.\n> **[slates]** — how the Slates app composes or bills this; not ByteDance doctrine.\n>\n> The split is load-bearing. A community-sourced \"narrative timing beats\" doctrine shipped in this file for months teaching the **exact inverse** of ByteDance's published guidance. Never merge the two registers again.\n\n---\n\n# Part 1 — Official ByteDance doctrine\n\n## What Seedance actually is `[official :1450-1452]`\n\nSeedance 2.0 is a multimodal AI director. It reads text, images, video and audio **simultaneously** and internally decomposes them into two dimensions:\n\n- the **spatial layer** — what is in the frame\n- the **temporal layer** — how things change over time\n\nSo a good prompt is **not \"copywriting-style description\" but an \"engineering-style instruction\"**: who, in what scene, doing what action, how the camera moves, and in what chronological order events occur — delivered respectively to the spatial layer and the temporal layer.\n\n## The advanced formula — 8 slots `[official :1455]`\n\n```text\nprecise subject + action details + scene/environment + lighting & color tone\n+ camera movement + visual style + image quality + constraints\n```\n\n⚠️ There is **no official \"6-step formula.\"** `Subject + Action + Environment + Camera + Style + Constraints` is community branding with no ByteDance source, and it silently drops the **lighting & color tone** and **image quality** slots. Use the 8 slots above.\n\n## Task-type sentence patterns `[official :1389-1425]`\n\nSeedance classifies your request from the phrasing. Use the pattern that matches the task:\n\n| Task | Pattern |\n|---|---|\n| **Image reference** | ``Reference `<Subject_N>` in `<Image_N>` to generate…`` |\n| **Video reference** | ``Reference `<Action / Camera_movement / Style / Sound_effect>` in `<Video_N>` to generate…`` |\n| **Audio reference** | ``Reference the timbre in `<Audio_N>` to generate…`` |\n| **Video edit — modify** | ``Strictly edit `<Video_N>`, and modify `<Original_Characteristic>` in it to `<New_Characteristic>``` |\n| **Video edit — add** | ``<Element_Features>` + `<Timing>` + `<Location>`` |\n| **Video edit — delete** | Name what to delete; for anything that must stay, say so explicitly |\n| **Video extend** | ``Extend `<Video_N>` forward/backward to generate…`` |\n| **Combined** | ``Reference `[Dimension]` of `<Image/Video_N>`, strictly edit `<Video_X>`, `[Specific_Edits]``` |\n\n### ⚠️ Edit / extend phrasing landmine `[official :1431]`\n\n> *\"For edit / extend video tasks, directly use `<Video_N>` to refer to the video. **Do not use \"reference `<Video_N>`\"**, to avoid being incorrectly identified as a reference task.\"*\n\nThis is easy to trip: Slates has an edit lane<!-- slates-only --> (`slates_generate_video` with `videoReferenceAssetId`, plus the Seedance edit/relocate routes)<!-- /slates-only -->. Writing *\"reference video 1 and change the jacket to red\"* gets classified as a **reference** task — the model generates a brand-new clip inspired by the source instead of editing it. Write *\"Strictly edit video 1, and modify the blue jacket to red.\"*\n\n## Shot structure — \"Shot 1 / Shot 2 / Shot 3\" `[official :1563-1598]`\n\n> *\"Use shot order, write a simple 'Shot 1 / Shot 2 / Shot 3' storyboard for each segment of the video, and then merge them into a complete prompt.\"*\n\n**❌ Never second-stamp.** No `0:00–0:03`, no \"At 4 seconds\", no per-segment durations.\n\n> *\"Do not impose strict limits on the duration of each segment; prioritize allowing the model to naturally generate the pacing based on the plot.\"* `[:1580]`\n>\n> *\"The model's support for precise timing (such as 0–3 seconds) is **unstable**, and forcibly limiting duration may lead to **abnormal generation results**.\"* `[:1586]`\n\nOrder shots by when events occur — primary first, secondary later. Let the plot set the pacing.\n\n**Per-shot internal order** `[official :1590-1598]` — organize each shot in exactly this sequence:\n\n1. **Camera movement or shot transition** — \"slowly push in from a wide shot\", \"fixed camera position\", \"cut to…\"\n2. **Subject actions and expressions** — the key actions and expression changes of the core character/object\n3. **Position or spatial change** — where the subject is, and how that relationship shifts\n4. **Audio** — sound effects, voices, background music for that shot\n\n**One primary camera move per shot** — see Camera below. `[official :1648]`\n\n## Subject binding — names + image indexes `[official :1488-1556]`\n\nEvery time a subject appears, it must be **explicitly referred to**. Two supported forms:\n\n- **Undefined subjects** — bind inline every mention: `<Subject_N>@<Image_N>`. Official example: **`Zhang San@Image 1`**. `[:1540]`\n- **Pre-declared subjects** — define once, then reuse the same label verbatim: *\"Define the tall man in **Video 1** as **police officer**, and define the other short man as **thief**\"*, then say \"police officer\" every time after. `[:1514]`\n\n**One subject spread across several assets** — bind them together: *\"Define `[…]` in **Image 1** and `[…]` in **Image 2** as `<Subject N>`.\"* `[:1514]`\n\n⚠️ **An Asset ID must never substitute for `<Image/Video_N>`.** `[:1546]` *\"the model cannot directly associate the Asset ID with the reference content.\"* Always cite by index.\n\nAlso official: keep descriptions concise, avoid redundancy, avoid semantic conflicts (contradictory traits for one subject), and prefer expressing spatial relationships through reference images rather than dense text. `[:1550-1556]`\n\n**`[slates]`** — the app composes this for you. `composeReferences()` cites each canonical character or environment reference inline as `Name (image N)` in the exact order it sends them, which is ByteDance's own duplicate-character format (*\"Zhang San (corresponding to image 1)\"* `[:1976]`). You never hand-write role labels or index numbers.\n\n## Action description `[official :1602-1621]`\n\n- **Body-part specificity + quantified degree.** Name hands, legs, head, shoulders, back — and supplement **range, speed, and force**. *\"slowly raise a hand\", \"quickly turn the head\", \"push hard off the ground\", \"slightly lower the head.\"*\n- **Prioritize slow, gentle, continuous small movements.** Avoid high-burst, large-dynamic actions — sprinting, big jumps, violent rolls. *\"walk slowly\", \"gently raise a hand\", \"sit down naturally with the motion.\"* **This is the official basis for the folk rule that \"fast\" degrades quality** — it is not a banned token, it is a class of motion the model handles badly.\n- **Supplement transitions between actions.** Specify inertia and continuity between consecutive beats so movement reads coherent: *\"use the inertia of turning around to naturally raise a hand\", \"naturally transition from a pause into raising a hand.\"*\n\n## Externalize emotion `[official :1623-1636]`\n\nReplace abstract emotion words (\"very sad\", \"extremely angry\") with **specific physical detail**. This is the highest-leverage single habit in the official guide:\n\n| Abstract | Externalized as actions and details |\n|---|---|\n| **Sadness** | head lowering, shoulders trembling slightly, eyes reddening, fingers unconsciously clutching the corner of clothing, tears welling but not falling |\n| **Joy** | corners of the mouth rising uncontrollably, brows and eyes relaxing, steps becoming light, unconsciously humming a tune |\n| **Nervousness / anxiety** | frequently checking the watch, fingers constantly tapping the tabletop, rapid breathing, eyes darting away |\n| **Anger** | both fists clenched, jawline tense, chest heaving, eyes sharp, squeezing words out through gritted teeth |\n| **Relief** | letting out a long breath, tense shoulders completely relaxing, a faint smile appearing, looking up toward the distance |\n\n## Camera `[official :1643-1648]`\n\n> *\"The model has a **strong understanding of camera movement terms**, so you can **directly use standard camera movement terminology**, such as 'medium shot, close-up, wide shot, slow push-in, smooth lateral tracking, fixed shot.'\"*\n\nThis is an **open vocabulary, not a fixed list** — and it explicitly includes **shot size** (close-up / medium / wide / long shot), which is as much a camera instruction as the move itself.\n\n> ⚠️ *\"Try to specify only 1 type of camera movement in a single shot. Do not require push, pull, pan, and move at the same time, as this will increase image instability.\"* `[:1648]`\n\n## Image quality, style, and constraints `[official :1656-1679]`\n\nThese three slots \"define creative boundaries for the model, unify image quality and artistic tone, and avoid visual flaws and random deviations.\"\n\n**1. Image quality** — define clarity, texture detail, and lighting quality. Official vocabulary: `HD` · `rich details` · `cinematic texture` · `natural colors` · `soft lighting`.\n\n> ⚠️ This is a **real slot with real vocabulary** — do not confuse it with Stable-Diffusion-era quality incantations. `8K` / `masterpiece` / `trending on artstation` remain banned slop tokens (see Part 3); *\"cinematic texture, rich details, natural colors\"* is the officially sanctioned way to ask for the same thing.\n\n**2. Style** — the overall art style and visual tone: `cyberpunk cool blue-purple tone` · `retro film` · `fresh Japanese style`.\n\n**3. Constraint words** — *\"Constraint words are very important. They can effectively avoid visual flaws, deformities, breakdowns, and unreasonable elements.\"* Official templates, verbatim:\n\n- **No subtitles** — \"keep it subtitle-free\" / \"avoid generating any text or subtitles\"\n- **No logo** — \"do not generate a logo\"\n- **No watermark** — \"do not generate a watermark\"\n\nSeedance has **no `negativePrompt` field** — constraints go inline in this slot. See Part 3 for the wider inline-negative kit.\n\n## 🔴 Duplicated characters — the twin problem `[official :1948-1994]`\n\n**Symptom:** in frames with **many characters**, where **three-view / multi-view character images** are supplied as references, two identical characters appear in the same generated frame.\n\n**Root causes** `[:1954-1959]`:\n1. Character subjects are not clearly defined in the prompt, so the model cannot distinguish roles.\n2. *\"When character **three-view / multi-view images** are used as reference assets, it is easy to confuse the model's character recognition, causing it to generate duplicate characters of the same appearance.\"*\n\n**Official fixes, in their order** `[:1971-1994]` — ByteDance is explicit that these *reduce probability*, not eliminate it:\n\n1. **Bind each character to its image explicitly**, in a consistent format. Official example: *\"Zhang San (corresponding to image 1) throws the green passbook toward Li Si (corresponding to image 2), who is standing.\"*\n2. **Append the global constraint verbatim** at the end of the prompt `[:1982]`:\n > *\"Throughout the video, characters with completely identical appearance, clothing, and accessories are prohibited. Do not generate duplicate avatars or a twin effect. Keep only a single corresponding character in the same frame, and do not reproduce repeated copies of characters.\"*\n3. **Optimize reference assets** `[:1988]` — *\"For character reference images, prioritize independent single-person photos. Three-view or multi-view assets are not recommended.\"*\n4. **Simplify the prompt** — do not paste a whole script; redundant copy confuses the model.\n\n**Scope this honestly.** This is troubleshooting for the twin problem in **multi-character frames**, not a blanket verdict on identity sheets. Practical rule for Slates:\n\n- **Multi-character Seedance shot** → bind every character to its image, append the anti-twin constraint, and prefer single-person / dominant-portrait references over multi-view sheets.\n- **Single-character shot** → the standard character-sheet flow is fine.\n\n**Too many reference people** `[official :2048-2052]` — past **4 reference people**, output stability drops (wrong headcount, duplicates). Official workaround: group the cast into images of ≤4 people each, generate those stills first, then drive the video from them.\n\n## Worked examples `[official :1689-1745]`\n\nThese are ByteDance's own end-to-end cases. Note the shape: an asset-binding preamble, then `Shot N` blocks in event order, then a trailing style + stability paragraph. No time stamps anywhere — 2.0 does not respond to them at all, which is version-scoped and reverses on 2.5.\n\n**Example 1 — dormitory emotional short drama (dialogue-focused).** Assets: `@Image 1` half-body photo of the female lead · `@Image 2` dormitory scene reference · `@Video 1` camera-movement reference · `@Audio 1` indoor ambience.\n\n> Use the girl in @Image 1 as the main character, use @Image 2 as the dormitory scene style reference, and refer to the camera movement in @Video 1.\n>\n> **Shot 1**: At dusk, **girl @Image 1** walks briskly to the **dormitory entrance @Image 2**. The camera follows steadily in a medium shot. Warm yellow sunlight spills into the hallway from the window. She pauses at the doorway, takes a deep breath, and looks slightly nervous.\n>\n> **Shot 2**: **Girl @Image 1** pushes the door open and enters the dormitory. The camera cuts to an indoor medium shot. Her roommates look up at her while organizing their books. One of them smiles and asks {How did the exam go? Did you pass?}. The camera slowly cuts between half-body close-ups of several people.\n>\n> **Shot 3**: **Girl @Image 1** first lowers her head with a dejected expression. The camera gives her a close-up. Then she raises her head, unable to hold back a smile, laughs out loud, and says {I was kidding}. Her roommates start chasing and play-fighting with her. The camera slowly pulls back and freezes on a wide shot of the dormitory filled with laughter.\n>\n> The entire video should have a high-definition cinematic documentary style, with warm tones and soft lighting. The character's face remains stable without deformation; movements are natural and smooth, with no stutter or flicker. The ambient sound blends naturally with @Audio 1.\n\n**Example 2 — ancient-style cliff confrontation (action/atmosphere-focused).** Assets: `@Image 1` female lead in red · `@Image 2` assassin in black · `@Image 3` cliff and bamboo forest · `@Video 1` martial-arts camera reference · `@Audio 1` drum beats.\n\n> Use the woman in red from @Image 1 as the female lead, use the woman in black from @Image 2 as the opponent, use the cliff and bamboo forest environment in @Image 3 as the scene reference, refer to the overall camera movement and action rhythm in @Video 1, and synchronize the background sound effects with @Audio 1.\n>\n> **Shot 1**: At dusk, the camera slowly pushes in from a side medium shot of **woman in red @Image 1**. She stands at the edge of the cliff and lifts a wine flask to drink. Her sleeves and robe hem sway gently in the mountain wind. The camera circles halfway around her, moving from the front to her back. In the distance, a figure in black is faintly visible in the bamboo forest.\n>\n> **Shot 2**: The camera zooms and fades into a long shot. From a drone perspective, it overlooks the entire cliff and bamboo forest. The two characters stand at opposite ends of the cliff. The mountain wind lifts their robe hems and dust, and the rhythm slightly accelerates with the drum beats.\n>\n> **Shot 3**: The camera cuts back to a ground-level close shot. The two slowly draw their swords and face off. **Woman in red @Image 1** shifts from a careless expression to a cold gaze. **Woman in black @Image 2** looks determined, and the sword tip trembles slightly. The camera steadily follows the two as they circle each other, finally freezing on a close-up of the instant before the two swords meet.\n>\n> The overall visual style should feel like a cinematic wuxia world in misty rain, with cool tones, low saturation, a film-grain texture, and rich light-and-shadow layers. The characters' faces and body proportions remain stable without deformation. Movements are continuous and natural, not stiff, with no clipping or stutter.\n\n## Other official notes\n\n- **On-screen text** `[official :1758]` — Seedance can render common text (ad slogans, subtitles, speech bubbles) and will auto-match style/colour from context, or take an explicit colour / style / timing / position. Prefer **common characters**; avoid rare glyphs and special symbols. (For *guaranteed* legible text, the start-frame route in Part 3 is still safer.)\n- **Extension degrades quality** `[official :2004-2024]` — using a generated video as the input for extension compounds degradation, with mottled colour blocks in face regions. Limit repeated continuations; prefer HD assets as input.\n- **Special effects that miss** `[official :2031-2044]` — when a described effect comes out wrong (a countdown that scrolls randomly), define it with a **reference video** instead of words: *\"the way the number '2999' appears should reference video 1.\"*\n\n---\n\n# Part 2 — Slates-specific `[slates]`\n\n## Reference media — caps and transport\n\nReference-to-video accepts up to **9 reference images, 3 reference videos, 3 audio clips** `[official :275-281]`. Text+audio-only and audio-only inputs are not supported.\n\n**Mutually exclusive:** first-frame/last-frame mode CANNOT be combined with reference images. The error reads `\"first/last frame content cannot be mixed with reference media content.\"` Pick one or the other. *(Official note `[:284]`: you can approximate first/last frames via prompt wording inside a multimodal call, but if the frames must be exact, use the dedicated first/last-frame route.)* The same rule covers reference VIDEO and AUDIO: they ride the reference endpoint, which has no frame parameters at all.\n\n### All three modalities go in ONE call\n\nThe caps are a shared budget, not three separate features: **12 files total on 2.0** (9 image + 3 video + 3 audio), **15 seconds of reference video combined**, **15 seconds of audio combined**. On 2.0 an audio reference needs at least one image or video alongside it; 2.5 accepts audio on its own.\n\nCite each by type and index, in the order they were attached — `image 1`, `video 1`, `audio 1`. The index is positional: reorder the attachments and the numbers move with them.\n\n```\nMarcus (image 1) performs the motion from video 1, in the workshop from image 2,\nspeaking the line in audio 1. Preserve his identity, appearance and outfit.\n```\n<!-- slates-only -->\n**Attaching a clip is NOT the same as editing it.** \"Add as reference\" puts it in the composer alongside everything else and wipes nothing; \"Edit with AI\" makes the clip the canvas and clears the tray for a fresh instruction. Two different jobs, two different menu entries — never infer one from the other.\n\n**Over the cap is REFUSED, never trimmed.** A reference video is priced into the quote before it is sent, so a clip silently dropped after the quote would be a clip you paid for and the model never saw. Remove one and retry.\n<!-- /slates-only -->\n\n### Motion transfer & lip-sync recipes (reference video / audio)\n\nThese aren't separate Seedance features — they're prompting strategies over reference media.<!-- slates-only --> The Slates tools (`slates_generate_motion_transfer` / `slates_generate_lip_sync` with the seedance engine) compose them for you. When driving them by hand through `slates_generate_video`:<!-- /slates-only -->\n\n- **Motion transfer:** subject image as a reference + the driving clip<!-- slates-only --> via `videoReferenceAssetId`<!-- /slates-only --> (2–15s) + `The character from image 1 performs the exact motion, choreography, and camera movement from video 1. Preserve the character's identity, appearance, and outfit.`\n- **Lip-sync / dialogue:** write the line in the prompt — `The person in video 1 says: \"…\"` — with audio generation on (always on in Slates). A **video** source's own voice is cloned natively; an **audio** reference (≤15s) drives speech from an existing recording: `…speaks the dialogue from audio 1 with accurate lip sync.`\n- **Voice + face from one clip (the talking-head recipe):** ONE unedited 2–15s clip of the person speaking (clear voice, no music, no cuts) as the video reference + prompt with the new script → their likeness AND voice deliver the new line.\n<!-- slates-only -->\n- **Billing:** a reference VIDEO switches the cost key to `seedance-2*-vref-{res}-{T}s` where T = clip seconds + output seconds — quote before confirming. Audio references are free (audio is included on every route).\n<!-- /slates-only -->\n\n<!-- slates-only -->\n## Faces — set `seedanceFace` for AI-character faces\n\nSeedance routes through **three tiers** depending on the face in the reference, exposed as the \"Face in Reference\" toggle plus the real-face params on `slates_generate_video`:\n\n- **Faceless / object / environment refs → default route (cheapest).** Leave `seedanceFace` off.\n- **An AI-character's FACE in a reference → `seedanceFace: true`.** The default route's baseline moderation rejects or degrades faces, so this reroutes to the face-capable provider. It costs **~45% more** — the cost key becomes `seedance-2-face-{res}-{N}s`, so the pre-flight quote already reflects it. Announce the face-route price, not the faceless one.\n- **A REAL person's photo (the user themselves, an actor) → the consent-gated premium route.** If a `seedanceFace` gen fails with `[REAL_FACE_DETECTED]`, the provider classified the reference as a real person: confirm with the user that (a) they hold the rights/consent to the likeness and (b) they accept the higher price (cost key `seedance-2-realface-{res}-{N}s`, roughly 2× the AI-face rate — quote via `slates_estimate_generation_cost`), then retry with `seedanceRealFace: true` + `realFaceConsent: true`. Never set `realFaceConsent` without the user's explicit confirmation.\n\nRules:\n- **The real-vs-AI call is the PROVIDER'S, not yours.** ByteDance's classifier is probabilistic — some real photos pass the standard face route (billed at the cheap rate; fine), others get rejected with `[REAL_FACE_DETECTED]` (auto-refunded). Don't preemptively route to the real-face tier just because a photo looks real; try `seedanceFace: true` first and escalate only on the marked rejection. Public figures / celebrities fail on every route.\n- It's about the **reference, not the output.** If your character identity or generated portrait shows a face, turn it on. A product shot with no person stays off.\n- Don't toggle it on \"just in case\" — a faceless gen on the face route burns ~45% extra for nothing.\n<!-- /slates-only -->\n\n## Reference rules (the verified ones)\n\n<!-- @inject:references-read-literally -->\n> **The general law: the model reads a reference literally.**\n> A reference image is not a suggestion. Whatever is baked into it — lighting, medium, texture, symmetry, competing identities — is read as a **property of the subject** and reproduced downstream. A baked rim light tints every shot made from that sheet. A sheet that looks like a 3D game render gets animated like game footage. Two competing renderings of one face get averaged into a third face.\n\nEvery reference rule below is a corollary of that one sentence, which is why \"prep the reference\" beats \"prompt around the reference\" every time:\n\n- **Flat, plain identity refs** — because scene lighting in the sheet becomes scene lighting in the output (Slates' own receipt: a studio-lit sheet produced a subject that looked green-screen-pasted in front of mountains).\n- **One authoritative rendering per subject** — because the model cannot tell which panel is the real one. ByteDance documents this failure directly: multi-view character assets \"confuse the model's character recognition, causing it to generate duplicate characters of the same appearance.\"\n- **No 3D-game-render look in a reference** — the model recognizes the render mood and inherits its motion character, so the *animation* comes out looking like game footage. This is not a taste rule; it is the same literal-reading mechanism applied to the temporal layer.\n- **Break perfect symmetry** — mirrored faces and dead-square framing read as synthetic, and the model preserves that reading rather than correcting it.\n\n**What this means in practice:** when output is wrong in a way that tracks the *subject* rather than the *scene* — the lighting is wrong the same way in every shot, the face drifts, the material looks synthetic everywhere — fix the reference, not the prompt. Prompting around a baked-in property is the expensive way to lose.\n<!-- @end:references-read-literally -->\n\n<!-- @inject:reference-rules-core -->\nIdentity = a few flat-lit neutral angles; one reference per role, named inline; 2-4 refs not 12; describe environments instead of feeding a grid.\n\n1. **2-4 strong references beat both extremes.** Not 1 (warps toward itself), not 12 (averages worse). Start with 2-3 focused refs — each one adds context AND another variable to balance.\n2. **One reference per ROLE, named in the prompt** — identity / style-grade / environment. The model does **not** infer a reference's role from its position in the list; the inline name carries it. Same-role competitors drift (two \"identity\" refs of different people blend into a third face). Slates composes the naming for you from your `@mentions` / `#tags` — you never hand-write role labels.\n3. **One identity sheet per character, named inline.** A character's identity is a single asset (dominant portrait + body panels), so attach that one asset rather than a pile of views: **fewer competing renderings of a face is better, because the model cannot tell which one is authoritative and averages them.** Slates cites it as `Marcus (image 1)`. **Do NOT hand-write a \"Reference Image Instructions\" block or role essays** (\"use for identity, ignore the outfit, render a neutral expression\") — that drags the sheet's studio lighting and wardrobe into a scene that asked for neither. The prompt leads; the user's words own wardrobe, expression, lighting, and action.\n4. **Flat-light identity refs.** Prep identity references with flat, even, shadowless lighting on a plain neutral background. A studio-lit or scene-lit character sheet bleeds its lighting into every generation — the failure looks like the subject was green-screen-pasted in front of the location. Reference prep beats prompting here.\n5. **Environment: describe it, don't feed a grid.** Default to describing the location in words and let the model build a space that fits the shot. Reserve an environment reference for a mandatory exact-match, and then use ONE clean establishing image with natural ambient light that reads as the location's real light — never a multi-panel grid fed whole.\n6. **Grids: explore, don't input.** Use grids to explore compositions cheaply, then pick a cell. Never feed a grid back in as a reference — the cells share a split detail budget and were generated jointly, so their flaws propagate.\n7. **Reuse the same refs across every shot** in a sequence. Lock a set and keep it; swapping references mid-sequence causes drift, because the model adapts each reference to the current prompt rather than copying it.\n8. **Legible in-shot text → bake it into a still start frame, never trust text-to-video.** Have an image model render the text, then animate from that locked frame. Video models smear type.\n9. **Working from existing media — describe ONLY what changes.** The source already carries its composition, motion, timing, and performance; re-describing them fights the model. Narrate the delta. (Video lane: restyle your own clip while keeping the performance; delayed-VFX on \"video one\"; marker-object insertion; video-as-reference for a series.)\n10. **Style transforms happen in natural language.** By default the source's artistic medium and visual style are inherited. To change it, add a plain-text instruction (\"anime → real person\"). There are no preset pickers, and there is no style slider.\n<!-- @end:reference-rules-core -->\n\n### For Seedance specifically\n\n- **Describe the ACTION, never the reference's content.** With refs attached, prompt only what is *happening* — motion, change, camera. Never re-describe what's in the reference, and never say \"still / scene / from a movie / from the image.\" The model already sees the refs; narrating them wastes tokens and induces drift. Injection is stochastic — if a roll misses, **re-roll, don't re-engineer** (and a slow gen is not a failed one<!-- slates-only --> — see slates-cost-discipline<!-- /slates-only -->).\n- **Seedance's own idiom for rule 2 is `Reference <Subject_N> in <Image_N>`** `[official :1389]` — `Image_N` indexes the order the refs are attached, so the name plus the index carries the role. The full binding grammar is in Part 1 (Subject binding).\n- **Rule 3 has an official ceiling here.** The trend is MORE references (video and audio into Seedance), all addressed by name — but for **multi-character frames** see the twin-problem section above: bind every character to its image, append the anti-twin constraint, and prefer single-person references. Past 4 reference people, stability drops `[official :2048-2052]`.\n- **Rule 8 holds even though Seedance can render common text natively** `[official :1758]`. A baked NB2 start frame is still the reliable route for text that must be legible.\n- **Rule 5 pairs with the first/last-frame exclusion** — frames and reference images are mutually exclusive on this model (see Reference media above), so an environment you must match exactly costs you the frame lane.\n\n<!-- slates-only -->\n## Pre-flight: references arrive inline, refer by code\n\nWhen you call `slates_generate_video` with reference asset IDs (firstFrameAssetId, lastFrameAssetId, ingredientAssetIds), the first call returns those references **inline as image content blocks** alongside a cost estimate and `requires_confirm: true`. **Look at the references** — if they suggest a different framing, lighting, or motion than your current prompt captures, revise the prompt before re-calling with `confirm=true`.\n\nWhen talking to the user about the gen, refer to each reference by its short code: `IMG-A12 — Beach Sunset`. The user sees that code as a badge on the gallery thumbnail, so they can match what you're saying to what they're looking at.\n\n- ✅ \"I'm using **IMG-A12** as the first frame and **IMG-A15** as the last frame — the camera move is going to be a slow dolly forward through the gap.\"\n- ❌ \"I'm using the first beach image and the last one...\" (which? They have four.)\n<!-- /slates-only -->\n\n---\n\n# Part 3 — Community field notes `[community]`\n\nThird-party guides and Slates field experience. Useful heuristics — but if one of these ever appears to contradict Part 1, **Part 1 wins**.\n\n## Length\n\n**Sweet spot 60-150 words** for a single shot (not 150-300 — that's the upper bound). Multi-shot storyboards run longer; official Example 1 above is ~230 words across three shots.\n\n## Pin the subject in the first 20-30 words\n\nThe opening sentence is the **identity anchor**. If the subject isn't locked early, the model hallucinates new subjects mid-clip. (Compatible with Part 1: the binding preamble comes before `Shot 1`.)\n\n```\nA matte black earbud case sits on a polished obsidian surface...\n```\n\n## Lighting is a top quality lever\n\nLighting has an outsized impact on output quality — which is why it has its own slot in the official 8-slot formula. Describe it before or alongside the subject.\n\n```\nA cool-white diagonal beam from upper left, dust particles drifting through.\nSoft golden hour lighting from low west angle.\nDramatic rim light against dark background.\n```\n\n## Camera and subject motion — separate sentences\n\nMixing them is a common cause of glitchy / shaky output.\n\n❌ \"The camera speed ramps as the earbud rises.\"\n✅ \"The earbud rises smoothly. The camera tracks upward.\"\n\n## Slow-motion works; \"fast\" is a known bad token\n\nSpeed ramps and slow-motion are supported in natural language, and `fast` is widely reported as a quality-degrading keyword. **The official version of this rule is stronger and better founded** — prioritize slow, gentle, continuous small movements and avoid high-burst action (Part 1, Action description `[:1611-1615]`). Prompt the motion class, not the adjective.\n\n```\nthe lid opens in slow-motion · the blade whips through the air\n```\n\n**Slop tokens to avoid:** `epic`, `amazing`, `beautiful`, `lots of movement`, `8K`, `masterpiece`, `trending on artstation`. These are quality *incantations* — the officially sanctioned way to ask for quality is the image-quality slot vocabulary in Part 1 (`HD`, `rich details`, `cinematic texture`, `natural colors`, `soft lighting`).\n\n## Style block at the end\n\nOne primary anchor + 2-3 supporting details, as the trailing paragraph (both official examples do exactly this). End with `Single continuous take` if you want one shot with no cuts. **Never** write `no cut` or `seamless transition` — not in the training vocabulary.\n\n## ⚠️ Don't cross-pollinate image-model syntax\n\nNamed **lenses, apertures, film stocks, and camera bodies** — `85mm f/1.4`, `Kodak Portra 400`, `ARRI Alexa 65`, `shot on Sony A7S3` — are an **image-model lever** (correct and encouraged in `slates-prompting-nano-banana-2`) and a **Seedance anti-pattern**. ByteDance's guide uses shot sizes, camera moves, pacing words, and the image-quality/style vocabulary throughout, and never once mentions fps, shutter angle, f-stop, or lens millimetres.\n\nIf you are carrying a look over from an NB2 start frame, translate it: `85mm f/1.4, Portra 400` → `close-up, shallow depth of field, warm natural colors, cinematic texture, film-grain texture`.\n\n## Negative prompting — inline only\n\nSeedance has **no `negativePrompt` field**. Put negatives in the constraints slot, led by the three official templates (Part 1):\n\n```\nkeep it subtitle-free · do not generate a logo · do not generate a watermark\navoid jitter and bent limbs\navoid temporal flicker\navoid identity drift\nno distortion, no stretching\n```\n\nAlso fine: positive reframing (\"empty street\" not \"no cars\").\n\n## Image-to-video / first-frame guidance\n\n**Describe motion, not image.** The model already sees the visual; tokens spent re-describing appearance are wasted.\n\nStability phrases that help:\n- `preserve composition and colors`\n- `maintain exact appearance from reference image`\n- `consistent character throughout, no deformation or drift`\n\n**Cap I2V prompts under 60 words** when possible. Over 100 words frequently triggers silent generation failure.\n\n## Common failure modes + fixes\n\n| Failure | Fix |\n|---|---|\n| Hallucinated subject mid-clip | First 20-30 words = identity anchor |\n| Bent limbs / extra fingers | `avoid jitter and bent limbs` in Constraints |\n| Identity drift across multi-shot | Re-name the bound subject in **every** `Shot N` block `[official :1537]` |\n| Two identical characters in one frame | The twin fix in Part 1 — bind each character to its image + append the global anti-twin constraint |\n| Silent generation failure on I2V | Cut prompt under 100 words, single primary camera move |\n| Speech / motion conflict | Limit dialogue to one line per action shot |\n| Erratic/random pacing | You second-stamped. Remove all time markers and use `Shot N` `[official :1586]` |\n\n## Sources\n\n**Official (authoritative):**\n- BytePlus ModelArk — Seedance 2.0 prompting guide, archived at `research/seedance-2-modelark-docs.md` (all `:NNNN` refs above)\n\n**Community (secondary):**\n- [fal.ai — How to Use Seedance 2.0](https://fal.ai/learn/tools/how-to-use-seedance-2-0)\n- [apiyi.com — Seedance 2.0 Prompt Guide](https://help.apiyi.com/en/seedance-2-0-prompt-guide-video-generation-camera-style-tips-en.html)\n- [atlabs.ai — Ultimate Seedance 2.0 Prompting Guide](https://www.atlabs.ai/blog/the-ultimate-seedance-2.0-prompting-guide-47-prompts-2026)\n",
|
|
24
28
|
"slates-prompting-seedream-5-lite": "---\nname: slates-prompting-seedream-5-lite\ndescription: How to prompt Seedream 5 Lite (ByteDance image model — the cheap volume option in Slates). Read before calling slates_generate_image with model seedream-5-lite, or slates_edit_image with editModel seedream-5-lite. Seedream front-loads attention, likes 30-100 focused words, and takes quoted strings for in-image text.\n---\n\n# Seedream 5 Lite — prompting\n\nByteDance's Seedream image model, Lite tier, routed via fal.ai. In Slates: `slates_generate_image` with `model: seedream-5-lite` (REQUIRES projectId — no headless path). **Flat-priced regardless of resolution** — the cheapest image model in Slates, which makes it the right default for high-volume drafting, storyboard exploration, and variant grids. Call `slates_estimate_generation_cost` for the current number; never quote prices from memory. Less censored than Nano Banana 2.\n\n**When to pick it:** lots of frames cheap (storyboard passes, 3-4 variant exploration), posters/layouts with text, quick look-dev. Step up to NB2 or FLUX.2 Max for the locked hero shot.\n\n## Core structure — five components, most important first\n\n```\nSubject + Style + Composition + Lighting/Atmosphere + Technical parameters\n```\n\nSeedream weights concepts mentioned **earlier in the prompt** more heavily. Lead with the subject; close with camera/technical details.\n\n**Length sweet spot: 30-100 words.** Unlike models that reward verbosity, Seedream gets confused by very long prompts. Focused beats exhaustive.\n\n## Style, composition, lighting vocabulary it responds to\n\n- **Style:** portrait photography, macro photography, cinematic, photorealistic, minimalist, oil painting, watercolor, digital art\n- **Composition:** symmetrical composition, rule of thirds, foreground detail with blurred background, wide-angle view, overhead perspective, medium shot, close-up\n- **Lighting:** golden hour lighting, dramatic side lighting, soft diffused light, moody low-key lighting, bright high-key lighting\n- **Technical:** shot on 85mm lens, shallow depth of field, high resolution\n\n## Worked examples\n\n**Portrait:**\n> \"Professional headshot of a female CEO with short blonde hair, confident expression, wearing a navy blue suit, neutral office background, studio lighting, shallow depth of field, high-end corporate photography style\"\n\n**Product:**\n> \"Modern smartphone floating in space, dark background with subtle blue gradient, product photography, studio lighting highlighting the glossy screen, ultra-detailed, commercial quality, photorealistic rendering\"\n\n## In-image text: double-quote it\n\nPut the exact string in double quotation marks — Seedream treats quoted text as render-this-verbatim:\n\n```\nA minimalist poster with the headline \"SUMMER SALE\" in bold sans-serif, centered\n```\n\nSeedream is one of the stronger models for layout-heavy work (posters, mockups, diagrams): call out the layout explicitly — \"centered headline, subtitle beneath, clean margins.\"\n\n## Edits: change one thing, lock the rest\n\nVia `slates_edit_image` with `editModel: seedream-5-lite`. Seedream edits respond well to instructions that name the change AND the preserved elements:\n\n```\nChange the bag to brown leather. Keep the person's face, pose, and the room unchanged.\n```\n\nNote: Seedream edits in Slates ignore extra `referenceAssetIds` — that path is Nano Banana 2 only.\n\n## Common failure modes + fixes\n\n| Failure | Fix |\n|---|---|\n| Subject inconsistent / mutates | Put the subject description first; break complex subjects into clear components |\n| Style drift | Reinforce the aesthetic with 2-3 related terms (\"cinematic, photorealistic, shallow depth of field\") |\n| Compositional confusion | Use photography terms (\"medium shot,\" \"overhead view\"); simplify the scene |\n| Garbled text | Double-quote the exact string; keep it short; state placement |\n| Mushy long-prompt output | Cut to under 100 words — Seedream rewards focus, not volume |\n\n## Iterate cheap, lock expensive\n\nFlat pricing makes Seedream the iterate-fast model: run the 3-strike loop here (draft → evaluate inline → one specific delta → regenerate), and only re-render the winning composition on a pricier model if the project's hero shot demands it. Cost rules live in `slates-cost-discipline` — the batch-authorization pattern applies when generating variant grids.\n\n## Sources\n\n- [fal.ai — Seedream Prompt Guide](https://fal.ai/learn/devs/seedream-v4-5-prompt-guide)\n- [BytePlus ModelArk — Seedream Prompt Guide](https://docs.byteplus.com/en/docs/ModelArk/1829186)\n",
|
|
25
29
|
"slates-prompting-veo-3": "---\nname: slates-prompting-veo-3\ndescription: How to prompt Veo 3.1 (Google). Read before calling slates_generate_video with veo-3.1-fast or veo-3.1-standard. Veo is a NICHE pick, never the default (route per slates-model-selection — Kling is the general default, Seedance the premium tier) — reach for it only when native synchronized audio must generate WITH the video in one gen. 16:9 or 9:16, 4/6/8s. Different cinematography formula than Seedance/Kling. (no subtitles) is mandatory after every dialogue line.\n---\n\n# Veo 3.1 — prompting\n\nGoogle DeepMind's video model. Two tiers: `veo-3.1-fast` (cheaper, quick) and `veo-3.1-standard` (higher quality). 4k variants exist for both (4K video requires Slates Pro).\n\n**Native single-shot duration: 4, 6, or 8 seconds** — and **8s only** at 1080p or 4K, or whenever you attach reference images (that endpoint is 8s-fixed). 4s and 6s exist at 720p, text-to-video or single-start-frame only. Longer durations require chaining clips via Extend / last-frame reuse — quality degrades if naively requested past 8s in a single generation. Aspect ratio: **16:9 or 9:16** on the route Slates uses. `slates_generate_video` REFUSES anything outside these before submit and names the legal set — nothing is silently ignored or downgraded.\n\nNative synchronized audio at 48kHz: dialogue, SFX, ambient — generated WITH video, not added after.\n\n## Official Google formula\n\n```\n[Cinematography] + [Subject] + [Action] + [Context] + [Style & Ambiance]\n```\n\nSweet spot length: 50-150 words. Cloud's official benchmark is ~50 words.\n\nVerbatim official benchmark:\n> \"Medium shot, a tired corporate worker, rubbing his temples in exhaustion, in front of a bulky 1980s computer in a cluttered office late at night. The scene is lit by the harsh fluorescent overhead lights and the green glow of the monochrome monitor. Retro aesthetic, shot as if on 1980s color film, slightly grainy.\"\n\n## Cinematography vocabulary (Vertex AI docs)\n\n**Lenses:** wide-angle, telephoto, fisheye, anamorphic, 35mm, 85mm, shallow/deep depth of field\n\n**Lighting:** Rembrandt lighting, volumetric lighting, backlighting, golden hour glow, lens flare, rack focus, **vertigo effect** (dolly zoom)\n\n**Camera moves:** dolly (in/out), truck (left/right), pan, tilt, crane, aerial/drone, handheld, whip pan, arc shot, zoom\n\n## Texture-realism phrases (counter the AI-plastic look)\n\n```\nfine skin pores · visible fabric weave · subtle contrast, no gloss or sharpening\n```\n\nSpecify materials concretely: `charcoal cotton hoodie`, `matte concrete`, `silk lapel`. Generic \"smooth, beautiful\" rendering is the failure mode you're avoiding.\n\n## Dialogue — `(no subtitles)` is mandatory\n\nEvery dialogue line you don't want burned in as text overlay needs `(no subtitles)`. Verbatim from the founder talking-head benchmark:\n\n```\nThe founder says, \"This update cuts setup time in half, helping teams get started faster.\" (no subtitles).\n```\n\nWithout this, Veo will overlay subtitle text on top of your generation.\n\n## Voice direction — keep it terse\n\nVeo is less responsive to long voice-direction blocks than Kling. Use brief modifiers:\n\n```\nsays in a weary voice\nwhispers\nshouts\nmutters\n```\n\nMulti-character: handles 2-3 speakers natively. Past 3, sync degrades — use first-frame/last-frame chaining for 4+.\n\n## SFX with cause\n\n```\n✅ SFX: thunder cracks in the distance\n❌ SFX: thunder\n```\n\nAlways specify direction or distance.\n\n## Ambient is mandatory\n\nAlways include an ambience line per scene. Without it, the audio mix feels dead.\n\n```\nSoft office ambience.\nWind on the open ridge.\nDistant city hum.\n```\n\n## First-frame + last-frame workflow (Veo's strength)\n\n1. Generate start frame (Gemini 2.5 Flash Image is the recommended pair — Slates' Nano Banana 2 works)\n2. Generate end frame\n3. Animate with both frames as anchors\n\n**Motion-Lock hack:** Keep ~60% of the same background pixels between start and end frames. Prevents latent drift across the clip.\n\nVerbatim arc-shot example:\n> \"The camera performs a smooth 180-degree arc shot, starting with the front-facing view of the singer and circling around her to seamlessly end on the POV shot from behind her on stage. The singer sings 'when you look me in the eyes, I can see a million stars.'\"\n\n## Ingredients-to-Video (multiple references)\n\nVerbatim example:\n> \"Using the provided images for the detective, the woman, and the office setting, create a medium shot of the detective behind his desk. He looks up at the woman and says in a weary voice, 'Of all the offices in this town, you had to walk into mine.'\"\n\n## Reference discipline (character / environment refs)\n\n<!-- @inject:references-read-literally -->\n> **The general law: the model reads a reference literally.**\n> A reference image is not a suggestion. Whatever is baked into it — lighting, medium, texture, symmetry, competing identities — is read as a **property of the subject** and reproduced downstream. A baked rim light tints every shot made from that sheet. A sheet that looks like a 3D game render gets animated like game footage. Two competing renderings of one face get averaged into a third face.\n\nEvery reference rule below is a corollary of that one sentence, which is why \"prep the reference\" beats \"prompt around the reference\" every time:\n\n- **Flat, plain identity refs** — because scene lighting in the sheet becomes scene lighting in the output (Slates' own receipt: a studio-lit sheet produced a subject that looked green-screen-pasted in front of mountains).\n- **One authoritative rendering per subject** — because the model cannot tell which panel is the real one. ByteDance documents this failure directly: multi-view character assets \"confuse the model's character recognition, causing it to generate duplicate characters of the same appearance.\"\n- **No 3D-game-render look in a reference** — the model recognizes the render mood and inherits its motion character, so the *animation* comes out looking like game footage. This is not a taste rule; it is the same literal-reading mechanism applied to the temporal layer.\n- **Break perfect symmetry** — mirrored faces and dead-square framing read as synthetic, and the model preserves that reading rather than correcting it.\n\n**What this means in practice:** when output is wrong in a way that tracks the *subject* rather than the *scene* — the lighting is wrong the same way in every shot, the face drifts, the material looks synthetic everywhere — fix the reference, not the prompt. Prompting around a baked-in property is the expensive way to lose.\n<!-- @end:references-read-literally -->\n\n<!-- @inject:reference-rules-core -->\nIdentity = a few flat-lit neutral angles; one reference per role, named inline; 2-4 refs not 12; describe environments instead of feeding a grid.\n\n1. **2-4 strong references beat both extremes.** Not 1 (warps toward itself), not 12 (averages worse). Start with 2-3 focused refs — each one adds context AND another variable to balance.\n2. **One reference per ROLE, named in the prompt** — identity / style-grade / environment. The model does **not** infer a reference's role from its position in the list; the inline name carries it. Same-role competitors drift (two \"identity\" refs of different people blend into a third face). Slates composes the naming for you from your `@mentions` / `#tags` — you never hand-write role labels.\n3. **One identity sheet per character, named inline.** A character's identity is a single asset (dominant portrait + body panels), so attach that one asset rather than a pile of views: **fewer competing renderings of a face is better, because the model cannot tell which one is authoritative and averages them.** Slates cites it as `Marcus (image 1)`. **Do NOT hand-write a \"Reference Image Instructions\" block or role essays** (\"use for identity, ignore the outfit, render a neutral expression\") — that drags the sheet's studio lighting and wardrobe into a scene that asked for neither. The prompt leads; the user's words own wardrobe, expression, lighting, and action.\n4. **Flat-light identity refs.** Prep identity references with flat, even, shadowless lighting on a plain neutral background. A studio-lit or scene-lit character sheet bleeds its lighting into every generation — the failure looks like the subject was green-screen-pasted in front of the location. Reference prep beats prompting here.\n5. **Environment: describe it, don't feed a grid.** Default to describing the location in words and let the model build a space that fits the shot. Reserve an environment reference for a mandatory exact-match, and then use ONE clean establishing image with natural ambient light that reads as the location's real light — never a multi-panel grid fed whole.\n6. **Grids: explore, don't input.** Use grids to explore compositions cheaply, then pick a cell. Never feed a grid back in as a reference — the cells share a split detail budget and were generated jointly, so their flaws propagate.\n7. **Reuse the same refs across every shot** in a sequence. Lock a set and keep it; swapping references mid-sequence causes drift, because the model adapts each reference to the current prompt rather than copying it.\n8. **Legible in-shot text → bake it into a still start frame, never trust text-to-video.** Have an image model render the text, then animate from that locked frame. Video models smear type.\n9. **Working from existing media — describe ONLY what changes.** The source already carries its composition, motion, timing, and performance; re-describing them fights the model. Narrate the delta. (Video lane: restyle your own clip while keeping the performance; delayed-VFX on \"video one\"; marker-object insertion; video-as-reference for a series.)\n10. **Style transforms happen in natural language.** By default the source's artistic medium and visual style are inherited. To change it, add a plain-text instruction (\"anime → real person\"). There are no preset pickers, and there is no style slider.\n<!-- @end:reference-rules-core -->\n\n### For Veo specifically\n\n- **Veo's idiom for rule 2 is plain-English role naming in the sentence itself** — *\"Using the provided images for the detective, the woman, and the office setting, create a medium shot of…\"* (see Ingredients-to-Video above). The role rides in the noun phrase, not in a separate label block.\n- **Rule 8 has a second reason to matter here:** Veo bakes subtitle text into the frame unless every dialogue line carries `(no subtitles)`. Text you did not ask for is the failure mode, not just text you did.\n\n## Negative prompting — nouns, not instructions\n\nVeo has a `negativePrompt` field. **Verbatim Vertex AI rule:**\n> \"Describe unwanted elements as nouns rather than instructions. Use 'wall, frame' instead of 'no walls' or 'don't show walls.'\"\n\nInline: positive reframing in the body too.\n- ✅ `\"a desolate landscape with no buildings or roads\"`\n- ❌ `\"no man-made structures\"`\n\n## Common failure modes + fixes\n\n| Failure | Fix |\n|---|---|\n| Subject identity shifts mid-clip | Front-load identity at prompt start; use material cues (`charcoal canvas`, `cotton`, `silk`) to stabilize |\n| Floaty / weightless motion | Weight verbs (`trudges`, `drops heavily`), ground contact (`boots crunch on gravel`) |\n| AI-plastic look | `fine skin pores`, `visible fabric weave`, `subtle contrast` |\n| Subtitles baked into video | `(no subtitles)` after every dialogue line |\n| Rushed dialogue | Lines fit one natural breath in 8s |\n| Mismatched ambience | Always include an ambience line |\n| Warped geometry | `photorealistic stability` |\n\n## Timestamp shot syntax (for chained / multi-beat scenes)\n\nVeo accepts `[00:00-00:02]` brackets for timed sequences within an 8s clip. **Do NOT cross syntaxes** — Veo timestamps in a Seedance prompt cause subject drift; Seedance \"single continuous take\" in a Veo prompt suppresses cuts.\n\nVerbatim multi-beat:\n> \"[00:00-00:02] Medium shot from behind a young female explorer with a leather satchel and messy brown hair in a ponytail, as she pushes aside a large jungle vine to reveal a hidden path.\n> [00:02-00:04] Reverse shot of the explorer's freckled face, her expression filled with awe as she gazes upon ancient, moss-covered ruins. SFX: The rustle of dense leaves, distant exotic bird calls.\n> [00:04-00:06] Tracking shot following the explorer as she steps into the clearing and runs her hand over the intricate carvings on a crumbling stone wall.\n> [00:06-00:08] Wide, high-angle crane shot, revealing the lone explorer standing small in the center of the vast, forgotten temple complex, half-swallowed by the jungle. SFX: A swelling, gentle orchestral score begins to play.\"\n\n## Benchmark prompt — founder talking head (full)\n\n> \"Camera locked at eye level, medium close-up on a 35mm lens: a startup founder in his late 30s with short black hair and light stubble, wearing a charcoal cotton hoodie, speaking directly to camera, leaning slightly forward as he speaks, lifting one hand to emphasize a point, then relaxing back to neutral, in a quiet office during late afternoon, with blurred monitors glowing faintly in the background, lit by soft daylight from a side window with gentle fill on the opposite side and natural falloff across his face. Style: fine skin pores, visible fabric weave, subtle contrast, no gloss or sharpening. Audio: The founder says, 'This update cuts setup time in half, helping teams get started faster.' (no subtitles). Soft office ambience.\"\n\n## Pre-flight: references arrive inline, refer by code\n\nWhen you call `slates_generate_video` with `firstFrameAssetId` / `lastFrameAssetId` / `ingredientAssetIds`, the first call returns those references **inline as image content blocks** alongside a cost estimate and `requires_confirm: true`. Veo's strongest move is first-frame + last-frame; the pre-flight is where you confirm the two frames actually anchor the motion you wrote. Revise the prompt before `confirm=true` if needed.\n\nWhen talking to the user about the gen, refer to each reference by its short code: `IMG-A12 — Founder Headshot`. The user sees that code as a badge on the gallery thumbnail, so they can match what you're saying to what they're looking at.\n\n- ✅ \"I'm anchoring on **IMG-A12** as the open shot and **IMG-A18** as the close — the 180° arc lands on her looking offscreen left.\"\n- ❌ \"I'm using two of the founder shots...\" (which two? They have six.)\n\n## Sources\n\n- [Google Cloud — Ultimate Prompting Guide for Veo 3.1](https://cloud.google.com/blog/products/ai-machine-learning/ultimate-prompting-guide-for-veo-3-1)\n- [Google DeepMind — Veo Prompt Guide](https://deepmind.google/models/veo/prompt-guide/)\n- [Google Cloud Docs — Vertex AI Video Generation Prompt Guide](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/video/video-gen-prompt-guide)\n- [Atlas Cloud — Veo 3.1 Master Guide](https://www.atlascloud.ai/blog/guides/google-veo-3-1-guide-master-image-to-video-ai-with-native-sound-and-4k-realism)\n- [Invideo — Veo 3.1 Prompt Guide](https://invideo.io/blog/google-veo-prompt-guide/)\n",
|
|
30
|
+
"slates-restyle-from-blocking": "---\nname: slates-restyle-from-blocking\ndescription: Render one blocking pass as several different visual worlds — live action, 2.5D painted, 2D ink, toybox — matching cut for cut. Use when a client needs style options, when someone wants to see the same edit in another look, or when an approved edit needs a new treatment without re-blocking.\n---\n\n# Restyle — one edit, many worlds\n\nThe commercial payoff of the whole previs workflow, and the reason a blocking file is an asset rather than a step.\n\n## The idea\n\nEvery prompt has two halves:\n\n- **Structure** — cuts, camera, timing, who is where. Lives in the blocking clip. **Never changes.**\n- **Style** — what any of it looks like. Lives in the references and the prompt text. **Changes freely.**\n\nHold the structure, swap the style, and the same edit comes back as live action, painted 2.5D, ink on paper or a toybox — **matching frame for frame across all of them.** Cuts land on the same frames, the car drifts at the same moment, the same head turns at the same beat.\n\nFor anyone pitching work: three visual worlds in a day, off one edit the client has already approved. The foundation is not up for renegotiation, so the conversation is only about look.\n\n## Before you restyle\n\nYou need a blocking clip whose structure you are happy with, and a finished prompt for at least one style (per `slates-blocking-to-prompt`). The first style is the expensive one; every later style is an edit of its text.\n\n## What stays fixed\n\nCopy these across every style **verbatim**. Changing them is what desynchronises the outputs:\n\n- The blocking reference's own contract — that it is the master for all movement, the placement-only clause, the tie-break clause, the disambiguation clause\n- The shot count and every timestamp\n- Every shot's camera position, angle, framing and cut point\n- Screen direction and seating\n- The `HOLD FOR THE FULL TIMELINE` block\n- `videoReferenceAssetIds` and `videoReferenceSecondsEach`\n\nLead each style's prompt with a lock so the style layer cannot leak into the structure:\n\n> VIDEO LOCK — the dominant rule of this prompt: the reference defines 100% of the motion, editing and object choreography. The text below defines only look, materials, locations and effects layered onto that motion. Wherever the text and the video could be read differently about motion, the video decides.\n\n## What changes\n\n| Layer | What you swap |\n|---|---|\n| Rendering style | photoreal · painted 2.5D · 2D ink · miniature/toybox |\n| Characters | different sheets entirely — a couple, grandparents, a robot and a cat |\n| Locations | the same four beats set in a different world |\n| Time of day / weather | night after rain · golden hour · hard noon |\n| Lighting and colour | per style |\n| Audio | SFX-only, or scored, or lip-synced dialogue |\n\nCharacters can change species and still land, because the blocking only supplies where a body is and how it moves.\n\n## Dummy mapping — the mechanism that makes it work\n\nEach style needs its own explicit mapping from grey proxy to real object. The proxy is a slot; the style fills it:\n\n> DUMMY MAPPING: the front-LEFT sphere-head dummy (with its grey arm at the shifter and grey leg at the pedals) is THE GRANDPA; the front-RIGHT sphere-head dummy is THE GRANDMA; a front-seat dummy together with its loose blocks is that ONE whole person. Blocks on the rear bench are the luggage. The low-poly flying model in SHOT 18 is THE HELICOPTER. The two vehicles behind the hero car in SHOT 19 are THE POLICE CARS.\n\nSame clause per style, different right-hand side. And restate the placement-only rule in style terms:\n\n> The source defines only placement and motion, never appearance: every placeholder becomes the real object its position implies — spheres are always people, cabin blocks are always cases and bags, fully drawn.\n\n## Location continuity\n\nIf the piece travels, name the places and pin each shot to one. Reusing labels across styles keeps the four prompts diffable:\n\n```\nLOCATION CONTINUITY — one journey through four fixed places; each looks\nidentical in every shot where it appears:\n LOC-A <opening> LOC-B <middle> LOC-C <turn> LOC-D <finale>\n```\n\nThen tag every beat: `SHOT 9 — 7.79-9.33s — LOCKED, LOC-B: <description>`.\n\n**On a piece that visits many places, make the map absolute and countable** — otherwise the model reuses a room it liked and you get the same interior three times:\n\n> The location map is absolute — SEVEN locations, each appearing EXACTLY ONCE, in this exact order: 1) yard 00:00-00:03.3 … 7) rooftop 00:20-00:30. No location ever appears twice, and the three interiors are three COMPLETELY DIFFERENT rooms — different walls, furniture, people and light — never the same room repeated.\n\n## Style references\n\nA style reference is **not a keyframe**, and saying so prevents the model reproducing its composition as a shot:\n\n> STYLE MASTER — defines the painting and rendering style only: hand-painted look with visible brushstrokes, sculpted painterly volumes, textured matte surfaces, dramatic coloured rim light, deep moody shadows. NOT a keyframe, NOT a location to reproduce, NOT a frame that ever appears in the film. Its own subject, framing and composition are never seen in any shot.\n\nA style can also be **text-only** — no reference image at all. Ink and toybox looks usually specify better in words than they match from a still.\n\n## Keep performance inside the existing shots\n\nStyle changes tempt the model to earn new coverage. Refuse it:\n\n> ACTING — inside the existing shots only: performance is visible only at the size and distance the reference already gives it, only where the source already shows a face; everywhere else it reads through posture and hands alone. The performance NEVER earns a new shot, a new angle or a closer framing.\n\n## Text-free worlds\n\nStylised worlds are where invented signage and garbled lettering appear. One clause kills it:\n\n> TEXT-FREE WORLD: every sign is a blank painted shape, every gauge face carries tick marks only, every licence plate is a blank plate.\n\n## Running it\n\nGenerate each style as its own `slates_generate_video` call against the **same** `videoReferenceAssetIds`. Keep them in one project so they sit side by side; name assets by style so the comparison reads at a glance.\n\nQuote the whole set before firing — `slates_estimate_generation_cost` per style — and confirm. Four styles is four generations, not one.\n\n🚨 Never fire a batch of style variants without showing the user the prompts and the total cost first.\n\n## Checklist per style\n\n- [ ] Same blocking asset, same `videoReferenceSecondsEach`\n- [ ] VIDEO LOCK leads the prompt\n- [ ] Every timestamp and shot count identical to style 1\n- [ ] Dummy mapping written for this style's cast\n- [ ] Style reference declared as style-only, or none used\n- [ ] Location labels reused; on a travelling piece the map is absolute and countable\n- [ ] Acting-inside-existing-shots clause present\n- [ ] HOLD block copied verbatim\n- [ ] Cost quoted and confirmed\n\n## Related\n\n`slates-previs-blocking` · `slates-blocking-to-prompt` · `slates-style-prompting` (style vocabulary per model) · `slates-cost-discipline` (batch quoting)\n",
|
|
26
31
|
"slates-storyboard-from-script": "---\nname: slates-storyboard-from-script\ndescription: Turn a script or treatment into a Slates storyboard with scenes and frames. Use when the user has a script, treatment, shot list, or scene-by-scene description and wants to materialize it as a Slates storyboard, optionally generating frame images per shot.\n---\n\n# Storyboard from script — Slates workflow\n\nThe user has a script, treatment, or shot list. You're turning it into a Slates storyboard with scene → frame structure, optionally generating images for each frame.\n\n## Workflow\n\n### 1. Parse the script\nRead the user's script. Decide:\n\n- **Scene count** — usually 1 scene per location/setting change. Don't fragment into one-frame scenes.\n- **Frames per scene** — match the shot list. Default is 3-6 frames per scene unless the script specifies more.\n- **Shot labels** — pull them from the script (e.g., \"Wide\", \"Close-up\", \"Over-the-shoulder\").\n\nIf the user hasn't named the storyboard, suggest one based on the project tone.\n\n### 2. Materialize the structure first (no generation yet)\n- `slates_create_storyboard` with the chosen name.\n- For each scene: `slates_add_scene` with a descriptive name and order.\n- For each frame: write a *visual-only* prompt (image, not action), the shot label, and any director notes. **Don't generate yet.**\n\nSurface the planned structure back to the user as a tight summary:\n> Storyboard \"X\" • 4 scenes • 12 frames total\n> Scene 1: Forest opening (3 frames)\n> Scene 2: Confrontation (4 frames)\n> ...\n\n**Surface a decision log alongside that summary.**\n\n<!-- @inject:decision-log -->\nWhen you surface the plan, include a short **decision log** — one line per decision *you* made that the user did not specify:\n\n```\nsource phrase or declared default → what you wrote → what it resolves\n\"in a diner\" → chrome-and-vinyl booth, 3/4 on the counter → fixes the anchor so blocking is repeatable\n(no time of day) → late afternoon, low warm key → default; say the word and it changes\n(no camera) → slow push-in, single move → one move per shot; stacking increases instability\n```\n\n**Hard rule: never silently add weather, props, style, or camera movement.** If it wasn't in the brief and you added it, it goes in the log. This is the \"why did you add that?\" affordance — for an agent that writes prompts on the user's behalf and spends their credits, it is what keeps the model in assembly and the user in the director's chair.\n\n> ❌ **Do NOT turn this into a question gate.** Clarifying questions before optimizing directly fight the locked fast-path rule: *if intent is clear, generate immediately with sane defaults, don't ask questions; only ask for production intent, and batch every question into one message.* Log the decisions, then go. The log is an **output**, not an interrogation — surfaced alongside the plan, never as a separate ceremony, and never as a reason to wait.\n<!-- @end:decision-log -->\n\nTurning a script into *visual* frame prompts means resolving things the script left open — what the room looks like, where the light comes from, how the shot is framed. Those are your decisions, not the writer's; name them.\n\nAsk: **\"Generate frame images now? (y/N)\"**\n\n### 3. Generate frames if requested\nFor each frame:\n- Estimate cost (`slates_estimate_generation_cost`, `count = total frames`). Confirm with user if total > ~17 credits.\n- Generate sequentially, with character/environment/style references attached when present in the project (`slates_list_characters`, `slates_list_environments`).\n- Each result returns inline. Evaluate. If wrong, refine prompt + regenerate (charge once, not multiple).\n- Bind to the frame via `slates_add_frame`.\n\n### 4. Hand back\n- Total frames generated, total credits spent, storyboard id.\n- Suggest next steps: review via `slates_get_storyboard_with_frames`, or take the frames to motion — `slates_generate_video` per frame (`firstFrameAssetId`, `background: true`, poll `slates_get_generation_status`), then `slates_add_clip_to_timeline` in story order and `slates_export_video`. The full frames-to-film pipeline (batch cost authorization, model mixing) is `slates-one-prompt-film`.\n\n## Anti-patterns\n\n- **Don't** auto-generate without asking. Generation is the expensive step. Always confirm first.\n- **Don't** invent shot details the script doesn't mention. If the script says \"they argue,\" ask what the shot looks like, don't fabricate \"she clenches her fists in a wide shot.\"\n- **Don't** mix scene structure and frame generation in one pass — building the skeleton first lets the user catch errors before spending credits.\n",
|
|
27
32
|
"slates-style-prompting": "---\nname: slates-style-prompting\ndescription: Per-style prompting depth — how photoreal, anime, painterly, and 3d-render are prompted DIFFERENTLY on Seedance 2.0 vs Kling V3 vs Nano Banana 2, and the style-routing recipe (reference-first, styled start-frame → i2v). Load when the user asks for any visual style (\"make it anime\", \"painterly look\", \"like a Pixar film\") or when style consistency across shots matters.\n---\n\n# Per-style prompting (photoreal · anime · painterly · 3d-render)\n\nThe style library (`slates_create_style` / the app's style ids) defines what each style IS. This guide is how to PROMPT each style per model. Derived from `research/style-prompting-research.md` (second-brain) — claims marked *(hypothesis)* are untested; don't present them to users as fact.\n\n## The four ground rules (all styles)\n\n1. **Reference beats adjectives.** A style reference image outperforms prose style instructions. If the user has an on-style image — or you can cheaply generate one — attach it and let the default `inherit` behavior match it. Prose styling is the fallback.\n2. **Style lives in ONE slot per model:**\n - **Nano Banana 2** — narrative prose; the style is the opening framing of the sentence (\"A hand-drawn 2D anime cel illustration of…\"), never a comma tag.\n - **Seedance 2.0** — the 8-part formula reserves \"visual style\" (slot 6) and \"image quality\" (slot 7). One clause each. Don't scatter style words through the action text.\n - **Kling V3** — prose scene direction; style rides the lighting/style tail of Scene → Subject → Action → Camera → Lighting/Style. Tag soup underperforms badly.\n3. **Multi-shot consistency = the SAME style clause, byte-identical, in every shot's prompt** (plus shared references). Paraphrasing the style clause between shots invites drift.\n4. **The styled start-frame is the cheapest reliable style lever for video.** Compose the styled frame in NB2 (cheap), hand it to Seedance/Kling image-to-video, and describe only what CHANGES (motion). Never re-describe the style in the i2v prompt — the frame already encodes it.\n\nNever stack style buzzwords (\"ARRI ALEXA, 35mm, film grain, depth-of-field mastery…\"). One or two register tokens maximum — piles of specs dull the image.\n\n## Photoreal\n\n- **NB2:** never the literal word \"photorealistic\". Describe *a real photograph*: natural skin texture and imperfection, motivated lighting, one lens/film register (\"shot on a 50mm, soft window light\"). Photographic composition terms: wide-angle / macro / low-angle.\n- **Seedance:** put \"sharp focus, natural color, high detail\" in the image-quality slot and always include a lighting clause. Keep motion slow and coherent — fast/burst action is the #1 quality killer and reads most fake in photoreal.\n- **Kling:** the photoreal-PEOPLE lane — convincing acting, dialogue, lip-sync. It breaks on close-up hands, fine fluids, and crowds beyond ~5 faces: route those beats to Seedance or reframe.\n- **Faces on Seedance:** photoreal humans trigger the face-tier routing (AI face vs consented real face — see slates-prompting-seedance §Faces). Set the face flags honestly; never skip them to save credits.\n\n## Anime\n\n- **NB2:** open with the medium — \"A hand-drawn 2D anime cel illustration of…\" — then normal narrative Subject/Setting/Action. Clean line art, flat-shaded color, expressive eyes. NB2 has no negative prompt: phrase exclusions positively (\"flat cel shading with uniform focus\", not \"no depth of field\").\n- **Seedance:** visual-style slot = \"2D anime style, clean line art, flat cel shading\". The slow/coherent-motion preference still applies — burst sakuga actions are the same instability trap as in photoreal.\n- **Kling:** weakest anime lane (its strength is live-action-like acting); expect style drift on long prose-only shots. Prefer ground rule 4: NB2 anime start-frame → i2v with a motion-only prompt. *(hypothesis: refs hold Kling's anime better than prose — verify before promising.)*\n- Anime faces drift under multiple references faster than photoreal — the named-entity two-sheet doctrine applies unchanged.\n\n## Painterly\n\n- **NB2:** medium + technique in the style framing: \"digital concept-art painting, visible brushwork, painted edges\". At most ONE school/era register (\"classic gouache illustration\") — a register, not an artist-name pile.\n- **Video:** the least-supported style lane. Use ground rule 4 (painterly NB2 frame → i2v, motion-only prompt) and expect some cleanup of painterliness over the clip *(hypothesis — set user expectations, don't promise a perfectly painterly clip)*.\n- Camera language still applies — painterly ≠ static; \"slow push-in\" works the same.\n\n## 3D render\n\n- **NB2:** name the lineage register in the style framing: \"stylized 3D render, soft global illumination, subsurface skin\". Lighting vocabulary (GI, rim light) is unusually load-bearing for the 3D read.\n- **Seedance:** the physics/effects lane flatters 3D content — visual-style slot \"stylized 3D animation\", image-quality slot \"clean render, high detail\".\n- **Kling:** same start-frame preference as anime.\n- *(hypothesis)* An engine token (\"Unreal Engine 5 render\") may help NB2; if used, ONE token, style slot only — never on Seedance where spec-stuffing hurts.\n\n## Routing recipe (what to actually do)\n\n1. Style reference available → attach it, rely on inherit. Done.\n2. No reference, image request → styled NB2 prose per the section above.\n3. No reference, video request → NB2 styled start-frame first, then i2v with motion-only prompt. Direct styled text-to-video is the fallback when a start frame doesn't fit (e.g. dialogue-first Kling shots).\n4. Multi-shot run → byte-identical style clause per shot + shared references.\n",
|
|
28
33
|
"slates-ugc-influencer-ad": "---\r\nname: slates-ugc-influencer-ad\r\ndescription: Build a UGC-style AI-influencer ad in Slates — one synthetic person, phone-grade footage, one shot per generation, cut to a vertical direct-response ad. Read before making any talking-to-camera creator video, AI spokesperson, faceless-brand UGC ad, TikTok/Reels/Shorts ad with a person in it, or a testimonial-style spot. NOT for polished cinematic spots — that is a different register with an inverted rulebook, and mixing the two ruins both.\r\n---\r\n\r\n# UGC influencer ad — the full production doctrine\r\n\r\nOne synthetic person, talking to a phone, selling one thing. This is the highest-converting short-form ad shape on paid social right now, and almost every rule below exists because the obvious approach fails.\r\n\r\n**Read this file end to end before generating anything.** The phases are not independent: the plate rules decide whether the video rolls land, and the pacing arithmetic decides how long the script can be.\r\n\r\n---\r\n\r\n## 🚨 THE GOVERNING LAW: UGLY ON PURPOSE\r\n\r\n**Handheld, blown highlights, flat light, no colour grade, no music bed.** That is not a shortcut, it is the argument. The ad's implicit claim is *this is a real person filming herself*, and cinematic polish is exactly what makes AI legible as AI.\r\n\r\n**If a clip looks like a commercial, it failed.** Every competitor reaches for cinematic. The winners reach for boring.\r\n\r\n**Photoreal is a flaw budget, not a quality setting.** Everything that makes a frame read as real is something the model must be talked out of: even skin, symmetric light, a clean silhouette, a posed smile. Spend the prompt on imperfections. **Never spend it on quality words** — \"hyperrealistic\", \"8k\", \"masterpiece\" and \"ultra-detailed\" do nothing here and push toward the rendered look you are avoiding.\r\n\r\n---\r\n\r\n## The pipeline — nothing skips a stage\r\n\r\n```\r\nscript → character sheet → beat sheet → plates (one per beat) → video (one per beat) → edit\r\n [ slates_generate_image ] [ slates_generate_image ] [ slates_generate_video ]\r\n```\r\n\r\nEvery video roll starts from an approved plate. Every plate starts from a beat. Every beat starts from a finished script. **A video roll with no plate behind it is the most expensive mistake available in this pipeline** — images are cheap and video is not.\r\n\r\nEstimate before every stage with `slates_estimate_generation_cost`, and read `slates-cost-discipline` before the first generation.\r\n\r\n---\r\n\r\n## PHASE 1 — THE SCRIPT\r\n\r\n**Start from a proven ad, not a blank page.** Find an ad in this format that is currently running, transcribe it, and put its script beside yours. Diagnose why theirs works before writing a word. **Clone the structure; swap the product and the specifics.** A paraphrase of a working script performs worse than the script.\r\n\r\n### Write the argument as one unbroken paragraph\r\n\r\nNo beats attached, no shot list, no timings. Get it to where **no sentence can be moved without breaking the one after it.** If two sentences can swap places, it is a list, and a list reads staccato on camera.\r\n\r\n### The four tests\r\n\r\n1. **Can any two sentences swap?** Then it is a list, not an argument.\r\n2. **Does the voiceover describe what is on screen?** It must not. **The picture proves the realism; the words argue the business case.** Two channels, two jobs.\r\n3. **Does one named person recognise themselves in the first sentence?** *\"Freelancers who haven't offered video to clients yet\"* works. *\"You're scared of AI\"* names nobody.\r\n4. **Does the close force a binary?** A question where both answers belong to the viewer and one of them is unacceptable.\r\n\r\n### Line-level rules, each earned by a failure\r\n\r\n- **Clarity beats cleverness, every time.** Write it so a ten-year-old follows it. A line the viewer has to decode is not a hook.\r\n- **Use the plain word.** \"Subscription\", not \"renting access\". \"Buy it once\", not \"perpetual license\".\r\n- **Never sell a feature — sell the end state.** Nobody cares what the tool does. They care about money kept, clients won, competitors beaten.\r\n- **Give the claim its context.** \"No subscription\" means nothing on its own — a subscription to *what*? Say what is for sale before saying why it is better.\r\n- **Fear of missing out must name the loss.** \"Your competitors are using this\" is nothing. Name what it costs them: the customers being taken, the winning ad someone else found first.\r\n- **No invented numbers.** A statistic you cannot source is a liability, and the model will happily produce one.\r\n- **No contrastive negation** — *\"this isn't X, it's Y\"* / *\"Not X. Y.\"* It is the single most recognisable AI-writing tell.\r\n\r\n### Runtime is arithmetic\r\n\r\n**Words ÷ 3.4 = seconds.** Budget the fast number. A 17-word line is a 5-second shot; a 24-word line is 7 seconds. Decide length by cutting words, never by asking for a slower read.\r\n\r\n⚠️ **A generous window manufactures a slow delivery.** Give a 5-word line a 4-second shot and the model stretches the words to fill it. That is what \"she talks too slowly\" actually is, and no adjective in the prompt fixes it.\r\n\r\n⚠️ **The model normalises non-standard grammar and you cannot argue with it.** \"One less client\" comes back as \"one fewer client\" every roll. Rewrite the line so the construction never appears rather than re-rolling against it.\r\n\r\n---\r\n\r\n## PHASE 2 — THE CHARACTER\r\n\r\n**One person carries the entire ad.** Build her once, lock her, and every plate afterwards references her.\r\n\r\n### Build order, and it is counter-intuitive\r\n\r\n1. **Generate one ordinary plate first** — any location, described positively: bone structure, colouring, eye spacing, lip shape, hair texture, build.\r\n2. **Crop the face out of that plate.** That crop is now the seed.\r\n3. **Generate the identity sheet from the crop.** Sheets seeded from a rendered image come back rendered; sheets seeded from a photographic plate come back photographic. **Realism carries through the reference chain.**\r\n\r\n### The sheet itself\r\n\r\nThree panels on one plate, 16:9: a large chest-up portrait at three-quarter angle on the left, a full-body A-pose centre, a full-body back view right with hair visible. The portrait is the largest panel and carries the face at maximum detail. **No second rendering of the face anywhere on the sheet.** Identical wardrobe and hair across all three panels. Plain neutral-grey background.\r\n\r\n⚠️ **Phrase a cropped panel as FRAMING, never as absence.** *\"The head not shown\"* is a content-policy refusal. *\"Cropped at the collarbone\"* states a camera fact and passes.\r\n\r\n⚠️ **Light the sheet with flat phone light and a raking side source, never studio light.** The sheet drives lighting on every plate built from it, so a studio-lit sheet contaminates the whole ad with a studio look.\r\n\r\n### Making skin read as photographic\r\n\r\n**Name the photographic source. Do not inventory flaws.** A list — *\"open pores, oily sheen, a blemish\"* — gets treated as tokens and produces plastic. This works:\r\n\r\n> These are photographs off someone's camera roll that were never opened in an editor. Daylight arrives from one side and rakes across her face, so the texture catches the light along the cheekbone and the bridge of the nose while the other side sits in soft shadow. Slight JPEG softness, visible sensor grain in the shadows, white balance left a little cool and uncorrected.\r\n\r\n**Flat light hides texture. Raking side light is what makes pores visible at all.**\r\n\r\n**Give her a name**, in the prompt and in the script. A name creates a person; \"an AI influencer\" creates nothing.\r\n\r\n### 🚨 References decide things prompts cannot\r\n\r\n| The REFERENCE decides | The PROMPT decides |\r\n|---|---|\r\n| face, body, build, skin tone, framing, crop | skin detail, light quality, expression, what the camera is, what else is in frame |\r\n\r\n**Text cannot override the left column.** Asking for fair skin and an ordinary build against a tanned, model-built reference returns tanned and model-built. **Do not argue with a reference — replace it.**\r\n\r\n⚠️ **Never drop the reference to win the left column.** Running the same beat text-only returns a stranger and breaks the one thing this format cannot lose.\r\n\r\n---\r\n\r\n## PHASE 3 — THE BEATS\r\n\r\nCut the finished script into scenes. **Cut mid-clause, never on a full stop.** A line that resolves lets the generator sit in one room; an unresolved clause forces the location change.\r\n\r\n**Each shot gets one complete phrase — roughly 12 to 18 words.** Cut the script into phrases first, then assign a scene to each phrase. Never cut a phrase to fit a scene.\r\n\r\n### 🚨 THE CAMERA IS THE VARIETY AXIS, NOT THE LOCATION\r\n\r\nEight plates in eight different rooms, all carrying *\"shot on a phone at arm's length\"*, produce eight shots that look identical. Rewrite the **camera position** per shot and the same eight locations become a real ad.\r\n\r\n**Six generators — assign a different one to each consecutive beat:**\r\n\r\n1. **Inside an object, looking out** — washing machine drum, fridge, microwave, locker, glovebox, mailbox, vending machine, oven. The object's mouth rings the frame out of focus.\r\n2. **On the floor, looking up** — sidewalk at ankle height, base of a pillar, stairwell landing, under a bench.\r\n3. **High, looking down** — wedged on a shop shelf, on top of a fuel pump, a ceiling corner, one level above.\r\n4. **Set on a surface she walks into frame of** — car roof, folding table, bus bench, tailgate.\r\n5. **Behind or through something** — a hot food counter, chain-link, a clothes rack, a rain-covered window.\r\n6. **Reflections that are not a bathroom mirror** — polished elevator steel, a dark shop window at night, a wing mirror, a puddle, a dead ATM screen.\r\n\r\n⚠️ **UGC does not mean selfie.** An arm's-length clause in a shared prompt tail produces one camera position N times *and* puts her extended arm through the corner of every frame. **The phone is propped, set down, wedged or left somewhere far more often than it is held.**\r\n\r\n⚠️ **Rooms of a house are a cop-out.** A place with a job beats a place to live: laundromat, parking garage, corner store, gas station, car wash, storage corridor, elevator, stairwell, loading dock.\r\n\r\n⚠️ **Changing location costs nothing.** Identity travels on **wardrobe + a fixed hair style + one accessory motif**, never on the room. Never let set continuity argue you into staying put.\r\n\r\n⚠️ **Fast cutting is close-weighted.** A wide shot needs time for the eye to find the subject; a close-up lands instantly. At 1.5–2.5 seconds a beat, weight the set toward tight.\r\n\r\n---\r\n\r\n## PHASE 4 — THE PLATES. One per beat.\r\n\r\n`slates_generate_image`, model `gpt-image-2`, `quality: high`, vertical `9:16`. **Fire concurrently — 8 slots run at once; serial calls waste the day.** Pass `projectId` so every plate lands in the gallery where you can see it.\r\n\r\n**GPT Image 2 is the rail for photoreal people.** Head-to-head against the alternatives it is the one that returns photographic rather than plastic skin. Routing detail: `slates-model-selection`.\r\n\r\n### 🚨 GPT Image 2 routes references through its EDIT endpoint\r\n\r\nTwo consequences, both of which waste a generation:\r\n\r\n1. **A prompt that opens by describing the reference gets the reference edited.** Open with *\"one reference image is a three-panel character identity sheet\"* and it returns a brand-new character identity sheet. The head block below is written the way it is precisely to prevent this.\r\n2. **One reference alone drags the scene into that reference's background.** A sheet-only roll puts her on the sheet's plain grey backdrop with no location at all. **Always pass two references:** the identity sheet, plus a second image supplying either the environment or the skin quality to match.\r\n\r\n### 🚨 THE PLATE IS FRAME ZERO\r\n\r\nThe plate is the video roll's first frame, so **whatever is going to happen has not happened yet.** If the beat is something breaking, the thing is intact in the plate. A plate showing the aftermath gives the model nothing to do and opens the shot on a result instead of an event.\r\n\r\n**Sole exception:** a background element that must be visible in frame one to stop the scroll.\r\n\r\n### Build every plate from three blocks\r\n\r\n**HEAD — identical every time. The anti-sheet clause is load-bearing.**\r\n\r\n> Reference image 1 is a character identity sheet showing one woman across several panels — the face in the large portrait panel is the authority for her identity. Use that exact woman. Reference image 2 is [the second reference and its job]. Produce a single photograph, not a sheet and not multiple panels.\r\n\r\n**MIDDLE — the only part that changes:** location, camera position, wardrobe, **expression, and hair state.**\r\n\r\n**TAIL — identical every time.**\r\n\r\n> Shot on a phone, slightly soft, mild wide-lens distortion, no colour grade. Camera-original skin with open pores across the nose and cheeks, an oily sheen on the forehead, faint creases under the eyes. These are photographs off someone's camera roll that were never opened in an editor. No retouching and no skin smoothing. Nobody is holding a camera and no phone, camera or device is visible anywhere in the picture. Clean unmarked frame with no text and no logo.\r\n\r\n### 🚨 Expression and hair state go in the MIDDLE, never the tail\r\n\r\nPutting *\"caught mid-sentence, mouth slightly open, eyes on the lens\"* in the shared tail produces the identical face in every location.\r\n\r\n**Hair STYLE stays fixed** — that plus wardrobe is what carries identity. **Hair STATE varies:** tucked behind an ear, blown across her face, tangled from lying down, scraped back.\r\n\r\nExpressions that worked: mid-sentence and locked on the lens · laughing with eyes half shut · concentrating on something, not the camera · squinting into daylight · flat and unimpressed, waiting · bored and blinking, about to speak and not.\r\n\r\n### 🚨 The plate decides whether a physical feat is possible at all\r\n\r\n**The model will mime an action it cannot resolve.** Three rolls failed the same way on 2026-08-24: a dumbbell whose bar stayed straight while her hands moved, a pan that floated free of her grip and folded against her chest, a steel pole that leaned instead of folding.\r\n\r\n**All three were plate problems.** The pan plate had her holding it one-handed at arm's length with the phone in her other hand — no second hand existed to fold it with, so the model invented one and the object drifted.\r\n\r\n- **If the act needs both hands, the plate must show both hands free.** That means the camera is propped, set down or wedged — never held at arm's length.\r\n- **Direct the resistance, not the result.** Knuckles whitening, tendons standing, a beat where it holds, then the give.\r\n- **State the finished shape.** *\"Folded in half so the two ends touch\"* is checkable. *\"Bends it\"* permits a lean.\r\n\r\n### 🚨 NEVER composite a character onto a finished scene. Generate the whole frame at once.\r\n\r\n**Receipt, 2026-08-24.** A spectacle plate was generated first (a street, correctly lit), then the character was added by passing that plate as a second reference. Every attempt came back looking green-screened: her face carried a soft frontal key that existed nowhere in the scene, she was sharper and cooler than the background, and no haze or flare crossed in front of her. **A finished scene handed in as a reference tells the model to paste, not to light.**\r\n\r\n**The fix is to describe one scene from scratch with only the identity reference attached.** Same subject, same location, same everything — the difference is that the model renders one frame in one pass instead of merging two. The first from-scratch attempt landed.\r\n\r\nUse a second reference for *design* (a creature's build, a style) — never for a whole composed frame the character has to be inserted into.\r\n\r\n### 🚨 Write the light as ONE physical system, or the character reads as pasted in\r\n\r\nThe single most common tell is a key light on the subject's face that has no source in the picture. Name all four of these explicitly:\r\n\r\n1. **One source, and where it is.** *\"The sun is low and directly down the avenue behind everything.\"*\r\n2. **What that does to HER specifically.** If she is backlit, say her face is in ambient bounce with no highlight and no catchlight, and put the hard rim on her hair, one shoulder and the collar.\r\n3. **Forbid the key that does not exist.** *\"There is no light in front of her: no frontal key, no fill, no soft source on her face.\"* Without this clause the model adds one every time.\r\n4. **Atmosphere in FRONT of her, not only behind.** Haze, dust and veiling flare must cross the foreground, so her edges are no sharper than the parked cars beside her. **Every shadow in frame runs parallel**, hers included.\r\n\r\n**Let the camera's exposure be part of the physics.** Backlit means the phone lifts for her face and the sky blows to white. Night means the fire blows out and the blacks lift. That single decision ties subject and background into one image better than any amount of description.\r\n\r\n⚠️ **Do not stack grain adjectives.** *\"Heavy luminance noise\"* plus *\"aggressive noise reduction\"* plus *\"milky lifted blacks\"* in one prompt produced a clip so noisy it read as broken. Modern phones are clean at night — name the light, not the sensor damage.\r\n\r\n### Other plate rules\r\n\r\n- **Never describe the phone as an object.** *\"She lifts the phone\"* renders a phone in her hand. Describe what the camera does.\r\n- **Write negatives as positives.** *Matte uneven skin*, not \"not smooth\". *Flat daylight*, not \"no studio lighting\". *Caught mid-step*, not \"not posed\". A \"no X\" list is either ignored or quietly summons X.\r\n- **Text on props renders cleanly and is worth using.** A label reading `YOUR PRODUCT` comes back legible.\r\n- **Content refusals are stochastic. Re-roll the identical prompt before rewriting it.** A plate can refuse once and pass on an unchanged second call. A refused job returns no image and costs nothing. Only redesign after two or three refusals.\r\n- **Generate a pool and pick.** A mediocre plate wastes a metered video roll, and video is the only expensive stage.\r\n\r\n---\r\n\r\n## PHASE 5 — THE VIDEO. One generation per shot.\r\n\r\n`slates_generate_video`, vertical `9:16`, the plate as the first frame. Model routing lives in `slates-model-selection` — read it rather than guessing, and check `slates_estimate_generation_cost` before firing.\r\n\r\n### 🚨 ONE SHOT PER GENERATION. Never a multi-scene take.\r\n\r\nMeasured directly: a six-scene roll returned **nothing usable**, a three-scene roll returned about one usable second, and **the same beats shot as ten separate single-scene generations all landed on the first attempt.**\r\n\r\nCost is linear per second, so splitting is free. What it buys:\r\n\r\n- **A bad shot costs one shot, not the whole ad.** In a long take one broken scene kills every good scene beside it and the retry re-buys all of them.\r\n- **Every shot re-rolls independently**, so a note lands on one shot.\r\n- **8 concurrent jobs means the whole ad shoots in one wave anyway.** A long take buys no wall-clock.\r\n- **No transition can fail**, because there are no transitions inside a generation. Cuts happen in the edit, where they are free and reversible.\r\n\r\nA short line padded into the minimum duration is trimmed in the edit for nothing. **That padding is a far cheaper problem than a dead long take.**\r\n\r\n### The plate is the first frame, always\r\n\r\nPassing the plate as the first frame locks the opening on a composition you already approved, so the model animates a frame you chose instead of inventing one. Pass the identity sheet alongside it as a reference.\r\n\r\n**The one exception** is a shot whose first frame must not exist yet — a reveal, an assembly, anything resolving *into* the plate. There, pass the plate as a reference only.\r\n\r\n⚠️ **Re-read the plate before writing its prompt.** A prompt describing a camera resting on a counter, against a plate that is plainly a held selfie, is a contradiction the model resolves badly.\r\n\r\n### 🚨 Eyeline decides whether a beat lip-syncs or becomes voiceover\r\n\r\n**A character not addressing the lens reads as B-roll, and the model lays the voice over silent footage.** This is not a frame-size problem — the identical shot lip-syncs correctly once the eyeline is locked.\r\n\r\n**Write where her eyes ARE for the whole duration:** *\"her eyes are locked on the lens for the entire shot and she talks straight into it.\"*\r\n\r\n⚠️ **A brief exception becomes the whole shot.** *\"Glances at her feet once and back up\"* produces five seconds of staring at her feet. *\"Never looks down at her hand\"* produces her looking down at her hand. The model takes the vivid clause and runs the beat on it. State the eyeline as the dominant instruction and add exceptions only if you must.\r\n\r\nMixed voiceover and on-camera is a legitimate choice in this format. It has to be chosen, not discovered.\r\n\r\n### 🚨 Name the rig, THEN the operator's body\r\n\r\n**\"Single continuous handheld shot\" tells the model what the camera IS. The operator's body tells it what the camera DOES.** Ship one without the other and it renders its default: a smooth slow push with almost no shake.\r\n\r\n**Write a person's body, never a camera path.** Not *\"the camera drifts along the tailgate\"* but *\"the phone is lying flat on the tailgate metal, held loosely by a hand at the corner, so the frame sags to one side and gets nudged back level once.\"* Arrives, sags, overshoots, corrects, gets bumped, catches up. **And the world must register it** — a move nothing reacts to is a move nobody made.\r\n\r\n**An unusual camera position is still handheld.** Inside a fridge, on a car roof, in the gutter — someone is holding the phone there. A locked-off version reads as a tripod and loses the whole register.\r\n\r\n### Micro-movement is directed, never assumed\r\n\r\nEvery beat carries an explicit list of small involuntary actions. A beat that only says what she says produces a mannequin talking.\r\n\r\n> Small things: she blinks twice, her weight shifts onto one hip, a strand of hair slips forward over her shoulder, and the framing drifts and corrects the way a held phone does.\r\n\r\nOthers that work: a container tipping as she takes its weight · her shoulder rising as she reaches · her hand sliding along a handrail · picking dry skin off a lip · blowing hair out of the corner of her mouth.\r\n\r\n🚨 **Small involuntary business only — never a big physical action at the lens.** Directing her to climb onto something threw her whole body across a close frame and wrecked it. Re-rolled with nothing but a hair flip, a weight shift and two fingers tapping, it landed. **Small business reads as captured; a big action reads as staged, and at close framing it also destroys the composition.**\r\n\r\n⚠️ **When a re-roll must hold the plate's pose, say so as a prohibition:** *\"She does not climb onto the truck, she does not sit down, and she does not lean any further toward the camera than she already is.\"* Pair it with *\"the camera never travels and nothing in the shot jolts it.\"*\r\n\r\n**For a physical feat, direct the struggle, not the event.** Something that gives way on contact reads as a trick; something that **resists for a beat and holds** before it gives reads as real — knuckles whitening, tendons standing out, the forearm tensing, the grip shaking.\r\n\r\n### Audio\r\n\r\n**Always on.** \"No music\" means no score; it never meant no audio. Say what you want present — her lip-synced dialogue, the sound the action makes, footsteps, room tone — then close with **\"No music. No score. No background track of any kind.\"**\r\n\r\nGenerating with audio disabled produces a mouth moving in silence and the roll is wasted.\r\n\r\n---\r\n\r\n## PHASE 6 — THE EDIT\r\n\r\nFree, local, and where the ad is actually made. Trim dead air off a beat that ran slow. Drop a re-rolled beat over the original. Burn captions — all-caps, centred low, one or two words at a time, cut on the stressed syllable.\r\n\r\n**A one-second overrun is an edit problem, not a re-roll.** Re-rolling a shot to fix a second of air is the expensive way round.\r\n\r\n### Verify by WATCHING, never by exit code or by sampling stills\r\n\r\nA job that exits cleanly can still be a refusal with no file, and a landed take can still have a beat that never cut. **Check the file has an audio stream and the right dimensions, then look at a frame from each beat.**\r\n\r\n---\r\n\r\n## Anti-patterns\r\n\r\n- **Don't** write cinematic. Polish is the tell.\r\n- **Don't** put quality words in a prompt. Spend it on imperfections.\r\n- **Don't** combine scenes into one generation to save money. It costs more and returns less.\r\n- **Don't** generate video without a plate behind it.\r\n- **Don't** generate text overlays in an image. Captions happen in the edit.\r\n- **Don't** rewrite a prompt after one content refusal. Re-roll it unchanged first.\r\n- **Don't** describe the reference at the top of a prompt. Describe the photograph you want.\r\n- **Don't** fire the next roll because the last one failed. Diagnose against this file first.\r\n",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slatesvideo/shared",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Shared operations layer for the Slates MCP server and CLI: auth, cloud/desktop clients, and the single tool surface both consume. Most users want @slatesvideo/mcp-server or @slatesvideo/cli instead.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|