Skip to content

Screenplay import#

Write the screenplay with an LLM, import it as a project, map the reference pictures and voices, generate. The LLM does the writing inside Maystro's envelope; Video Studio checks the package before it creates anything. Maystro's own writer model can do the writing too, from a brief, without leaving the app: see Write it inside Maystro.

The workflow#

  1. Give your LLM (Grok, ChatGPT, Claude, …) the screenplay writing guide and the brief at its end: story, style, dialogue language, characters, target length, format, seed base, optional guide pictures. The guide makes the model write a package that fits the machine: full MiniMax H3 reference prompts, frame counts from the supported list, numbered reference pictures (people, places, and pose, composition or prop guides), dialogue within the speech budget.
  2. Save the JSON block of the answer as a .json file, or copy it.
  3. In Video Studio open Projects and click Import screenplay. Paste the JSON or choose the file. The package is checked before anything is created: the report shows scenes, shoots, frames and duration, the shoot table, and every issue found. Errors block the import; warnings do not.
  4. Check the preset for all shoots. For a package that uses reference pictures the dialog preselects MiniMax H3 — Referanslı (Ref2VA), the only preset family that reads them; any other choice shows a warning. The preset also decides the step count (a Turbo preset keeps its own); a step count in the package is ignored. Click Import. The project opens with its scenes and shoots: prompts, clip chains, "keep references", seeds and frame counts are already set.
  5. Click Screenplay in the project header. The panel lists the cast, the locations and the guides (pose, composition, prop) with their identity locks and reference briefs. Generate each reference picture in Image Studio from its brief (Copy brief), pick it in the panel, choose a voice reference for every speaking character, and click Apply to all shoots. The pictures land in the shoot panel's reference list, not in the single start-frame slot; the panel can also switch the preset of every imported shoot.
  6. Generate shoot by shoot, per scene, or the whole project. Re-takes follow the seed plan of the package (base seed + 10).

What the check looks at#

Result Condition
Error (blocks the import) A shoot has more than nine references (the model's limit) or the same reference twice, an unknown reference id, more than sixteen clips, or an empty prompt. A variant_of that points to an unknown subject. Duplicate shoot ids. A mapped picture or voice that does not exist.
Warning (changes the video; fix it by hand) An identity lock or a guide description is not repeated verbatim; a <Picture N> the prompt never defines, or fewer subject_definitions lines than references; a prompt without a detailed_description section; dialogue exceeds the speech budget of the clip; speaker ids that still differ from the dialogue table after the repairs; a speaker id written after another person's <Subject N> tag; a narrator line that shares its clip with an on-screen speaker; a Turkish line written without its Turkish letters that the importer cannot restore; a shot cut outside the clip; more than three speaking voices in one shoot; a guide role other than pose, composition or prop; a laugh, a line or a hum for someone on screen in a narrated clip; a shoot whose references are only partly mapped.
Fixed (repaired by the importer) Line breaks that arrived as a literal \n because the JSON was escaped twice; a frame count outside the supported list (set to the nearest one); a clip count that does not match the chain prompts; a style anchor that is missing or not first; a continuation clip without its opening sentence; a missing speaker id in a clip with one spoken line; a speaker id without its <Subject N> tag; a narrator shot that does not open with the closed-lips sentence; frequent Turkish words written without their letters (degil → değil). Each repair is listed with what changed.
Hint (second-order) A clip description under 100 words; seeds missing or out of sequence; negative phrasing; a scene reference that is not an id; settings the importer ignores (a step count, keep_references or keep_voice where they do not apply); a location brief that says "plate" (image models draw a dinner plate).

Fix errors and warnings in the JSON (or ask the LLM to) and paste again; the check reruns as you type. When neither is left, the dialog shows No critical issues: the repairs are already in the prompts that will be imported, and the hints point at a richer package without blocking anything.

Reference pictures and voices#

The package names people, places and guides by id (SUBJ_1, LOC_1, GUIDE_1). A picture mapped to an id goes to every shoot that references that id, in the order the prompt numbers them as <Picture 1>, <Picture 2>, … A voice mapped to a character goes to every shoot where that character speaks, in speaker order, three voices at most per shoot.

  • Map every reference of a shoot. A shoot takes its pictures in reference order and skips the ones without a picture, so a single missing picture shifts the rest and the prompt's <Picture N> numbers stop matching. The panel warns about such shoots.
  • Guides are pictures that are neither a character nor a place: a pose on a mannequin, a composition sketch for one shot, a prop. Generate them from their briefs like the others; they take no voice.

  • Costume variants. A character in a second costume is a second subject id linked with variant_of. Generate its picture from the base picture (same face, new clothes) rather than from scratch: two independent generations give two faces. The variant inherits the base character's voice; the panel shows this instead of a voice selector.

  • Narrator. Voiceover lines have no subject; the panel offers a Narrator row for their voice reference. Without one the model picks a voice from the description in the prompt.
  • Voices need a picture. A shoot with voice references but no reference picture cannot render (the model's reference contract); the panel warns.

See Reference images and voices for the picture rules and Continuity for clip chains and "keep references".

The panel only knows the shoots it created

Editing an imported shoot's prompt, frames or references by hand is fine. But the Screenplay panel applies its mapping only to the shoots the import created; shoots you add later get their references in the shoot panel.

Write it inside Maystro#

Instead of an external LLM, the assistant's writer model can write the package from your brief: Projects → Write screenplay from brief. The dialog takes the filled brief (the block at the end of the writing guide, or free text), the writer model (the configured writer, or any GGUF the assistant serves — your own included), the writing guide (the built-in one, or a .md file of your own, which travels with the request and is not stored), the target length and shoot count, and whether you want to read the storyboard before the JSON is written.

The job runs in three steps and shows each one — model, guide, seconds, characters written, rounds:

  1. Storyboard — the guide's sections 1–7: cast, locations, every shoot with its prompt, the dialogue table, the seed and frame plan. With Show me the storyboard on, the job pauses here. Read it, write notes ("make the host's lines longer", "add a shot of the gate") and have it revised, or accept it.
  2. Package JSON — the JSON export of exactly that storyboard. Decoding is constrained to the importer's schema, so the structure cannot go wrong: frame counts from the supported list, guide roles, speaker ids, every field present.
  3. Check and repair — the importer's report (the same one the import dialog shows) plus a length check against your target. Every error and warning goes back to the writer, for up to the chosen number of repair rounds.

The finished package opens in the import dialog with Import as project…; a copy is saved under screenplays in your Maystro root, next to the storyboard. A frame plan computed from the target length is appended to the brief: without it the model writes 124-frame clips and a film a third as long as asked.

On a 16 GB card the catalogue writer takes about three to four minutes for a ten-shoot film (storyboard, JSON and one repair round at roughly 90 tokens per second). It needs the whole card: switch the voice services off first, and expect the chat model to be unloaded while it writes. The writer runs with a 32k context for this (agent_llm_writer_context_size). Before it starts, Maystro checks that the chosen model fits the card's free memory and makes room — the chat model is unloaded, Vireo's warm pipeline is released after a video job, and only as a last resort do a few layers run on the CPU; the line under the model name in the writer window shows the result (How the writer fits the card).

What the checks cannot see, you see in the storyboard: whether every beat of the story is there, whether a narrator you asked for survived, how much the characters speak. The writer is asked to give spoken lines to at least half of the shoots and to say the story's moral in full sentences; it still tends to keep lines short, so if you want more dialogue, ask for it in the storyboard notes. The report flags thin shot descriptions (under 100 words), common Turkish words spelled without their letters (degil instead of değil, with the correct spelling) and long Turkish lines without any ç ğ ı ö ş ü (ASCII substitutes, which the model reads letter by letter; a correct line is left as it is). A writing guide of your own pairs best with a model that follows it: the catalogue writer keeps to its own alignment, a GGUF you add on the Assistant tab may be freer.

Automation#

The same import is available to scripts: POST /api/v1/video-studio/projects/import with {"package": …, "dry_run": true} returns the report without creating anything; without dry_run it creates the project and returns it together with the report. PUT /api/v1/video-studio/projects/{id}/screenplay-mapping applies a mapping {"references": {id: image_name}, "voices": {id: audio_name}}.