Cinematic Shotlist Toolkit
A practical offline Elixir toolkit for expanding creative briefs into shot lists, comparing written continuity details, composing scene prompts, planning a timed storyboard, and exporting an editorial CSV. The emphasis is on deciding what each shot contributes before spending time generating or editing media. It is designed for small product demonstrations, explanatory sequences, mood studies, and narrative concepts that benefit from an explicit plan.
The package contains 24 scene templates, 6 camera presets, 6 visual-style presets, a deterministic prompt composer, and a storyboard planner, 8 shot-role definitions, a brief-to-shot-list builder, a continuity comparison helper, CSV export, and a structural review checklist. It runs entirely in your application. It does not connect to a provider, generate video files, upload images, make network requests, or require an API key.
This is a provider-independent local creative-planning utility, not an SDK for a video-generation service. It does not claim compatibility with undocumented APIs. Prompts can be reviewed and adapted for the generation or editing tool you actually use.
Optional external references are distributed throughout this guide. They are supplied as browsing resources, not as the origin of the code or built-in templates, and do not imply an endorsement or service integration. The runtime does not fetch these pages or make claims about their availability.
Contents
- Brief-to-shot-list planning, continuity comparisons, CSV export, and review
- Installation and a first complete example
- What the toolkit does and does not do
- Prompt structure and input validation
- Camera and visual-style presets
- Twenty-four templates with practical usage notes
- Single-shot, product-demo, education, and narrative workflows
- Timed storyboard planning and text export
- Elixir modules, immutable maps, and serialization
- Continuity, negative instructions, and iteration practices
- Limitations, troubleshooting, and frequently asked questions
Start with the job of each shot
A shot list is useful when it explains why a sequence needs several images rather than treating every shot as a slightly different version of the same prompt. An establishing view answers where the subject is. A detail insert answers what deserves attention. A primary-action shot answers what changes. A closing hold gives the audience time to understand the result. These roles are editorial intentions, not instructions that a video model is guaranteed to obey.
This toolkit has thirteen local functions. Five focus on the sequence as a whole: get_shot_roles, plan_shot_list, continuity_report, export_shot_list_csv, and review_shot_list. The remaining functions provide the prompt composer, template library, presets, reference list, timing planner, and readable text formatter. Use the higher-level brief builder when you need a quick first draft, and use the lower-level composer when the actions need precise individual wording.
The brief builder does not invent a story, understand an uploaded image, or decide which footage is available. Its behavior is deterministic: the same subject, role order, and options produce the same plan. That makes it appropriate for a notebook, a small editorial script, or an application that needs an inspectable draft before a human chooses a generation service or footage source.
A complete role-based example
alias CinematicShotlistToolkit, as: Kit
board = Kit.plan_shot_list(%{
"title" => "Brass lamp concept",
"subject" => "a small brass desk lamp with a green fabric cable",
"setting" => "an uncluttered wooden desk beside a blue notebook",
"style" => "product", "aspect_ratio" => "9:16",
"roles" => ["establishing", "hero", "detail", "closing"],
"duration_seconds" => 3,
"continuity" => ["Keep the same cable color and notebook position."]
})
csv_text = Kit.export_shot_list_csv(board)
report = Kit.continuity_report(Enum.map(board["shots"], & &1["scene"]))
review = Kit.review_shot_list(board)
12.0 = board["total_duration_seconds"]
true = report["text_fields_consistent"]
4 = review["summary"]["shot_count"]
IO.puts(csv_text)The resulting plan contains the ordinary storyboard timing fields plus a role identifier and an editable scene map for each shot. The scene map records the fields used to compose that shot's prompt. The role metadata helps an editor distinguish the purpose of the shot without trying to infer that purpose from a long text description.
The continuity list is a separate set of production notes. It does not become hidden model configuration and is not silently appended to every prompt. Review those notes while adapting a sequence. When a note must also be visible in a generated prompt, express the relevant information explicitly in each scene field before recomposing the prompt. Separating the planning note from the actual instruction makes that decision easy to audit.
The eight built-in shot roles
| Role | Default viewpoint | Editorial intention |
|---|---|---|
establishing | Stable wide composition | Introduce placement and surroundings |
hero | Slow push-in | Reveal the main silhouette |
detail | Stable close composition | Inspect one surface or mechanism |
action | Lateral tracking | Show one deliberate visible change |
reaction | Stable framing | Pause for a consequence or response |
transition | Gentle push-in | Create a visual bridge for editing |
comparison | Overhead layout | Make a contrast easier to read |
closing | Stable final composition | Leave room for later editorial text |
alias CinematicShotlistToolkit, as: Kit
roles = Kit.get_shot_roles()
8 = length(roles)
IO.inspect(Map.new(roles, &{&1["id"], &1["purpose"]}))These defaults are deliberately restrained. A role is not a complete screenplay, and the generic action description may need editing to fit the subject. An inanimate object does not perform an action in the same way as a person, and a moving landscape may need a stable camera rather than tracking. Start with the role, then decide whether its suggested viewpoint supports the specific scene. If not, use create_storyboard with your own scene maps.
Repeated roles are allowed because a sequence may need more than one detail or reaction shot. The builder preserves the supplied order and creates between one and twelve shots. Its default sequence is establishing, action, detail, and closing. Every role-based shot uses the same requested duration; use the lower-level timing planner when different shots need different lengths. Timing remains a draft for editing rather than a statement about any provider's supported output length.
Brief fields and explicit limits
A brief requires a nonempty subject string. Optional shared prompt fields are setting, style, lighting, aspect_ratio, and negative. The sequence-specific fields are title, roles, duration_seconds, and continuity. Unknown keys are rejected. Do not place a provider model name, account identifier, API token, seed, price, or generation endpoint in this brief; those do not belong to a local editorial plan.
The roles field is a list of supported role identifiers. An unsupported identifier raises ArgumentError rather than being converted into an undocumented role. The continuity field accepts at most twenty nonempty notes and removes exact duplicates after whitespace normalization. Notes and prompt text share the text-length checks described later in this guide. Neither duplicate removal nor a length check establishes that a note is relevant or correct.
Durations must be finite numbers between one and sixty seconds. Boolean values are rejected because durations must be numbers, not atoms. Durations are rounded to three decimal places, and start times are accumulated from the rounded values. Avoid interpreting this precision as a promise of frame-exact timing. If you need a frame-based edit, translate the plan into the editor's frame rate and check the timeline there.
The builder returns a new plan and does not mutate the brief. Accessors return immutable values. That permits application-specific editing without replacing the built-in catalog for other callers. However, it is still your application's responsibility to save an edited brief or plan. This library does not create a project directory, maintain an autosave session, or synchronize revisions with a cloud service.
Compare written continuity before generating
Continuity failures often begin in the plan. A lamp becomes chrome in one prompt and brass in the next. A notebook changes color because one shot describes it specifically while another shot adds a different adjective. A room is present in the first shot but omitted from later descriptions. Comparing written fields can expose these differences early, even though it cannot tell whether a generated image actually follows the wording.
alias CinematicShotlistToolkit, as: Kit
report = Kit.continuity_report([
%{"subject" => "a brass lamp", "setting" => "a wooden desk", "style" => "product"},
%{"subject" => "a chrome lamp", "setting" => "a wooden desk", "style" => "product"}
])
false = report["text_fields_consistent"]
"subject" = hd(report["changes"])["field"]
IO.inspect(report["changes"])By default, the helper compares subject, setting, style, and aspect ratio between adjacent scenes. Whitespace is normalized, but wording is not paraphrased or interpreted semantically. "A brass lamp" and "a brass lamp" remain different strings because capitalization is not discarded. "A wooden desk" and "a timber table" remain different even when a person might consider them similar. This conservative behavior makes the report predictable and avoids pretending that the library understands visual identity.
You can supply a supported field list when a workflow needs a narrower comparison. Lighting is an additional supported continuity field. Missing optional values are compared as missing values, so an omitted setting followed by an explicit setting produces a change record. The record includes the field, adjacent shot indices, and before/after values. It is information for review, not an automatic decision that the sequence is wrong.
An intentional contrast should remain visible in the report. For example, an educational sequence may switch from a wide arrangement to a single object, or a narrative sequence may move from an interior to an exterior. Do not edit the text merely to make the report show no changes. Instead, document the transition and decide whether the actual footage explains it clearly. The goal is deliberate continuity, not identical descriptions at any cost.
Export a practical CSV handoff
export_shot_list_csv validates storyboard timing before returning a CSV string. The columns are shot index, role, start time, end time, duration, and composed prompt. Multiline prompts are quoted with the local CSV escaping helper, so a real CSV parser can keep the entire prompt in one cell. A text editor may show those quoted cells on several physical lines; that is normal and does not imply extra shots.
The function does not write a file or open a spreadsheet. Your application can decide whether to display the CSV in a text area, copy it into another tool, or save it to a chosen output path. Avoid putting export files in a public directory unless their contents are intended to be public. Prompts may contain unpublished creative ideas or client material even when the library itself has no credentials or network functionality.
The exporter guards text cells that begin with spreadsheet formula markers by adding a leading apostrophe. This is separate from CSV quoting: quotation marks preserve the field boundary but do not universally prevent a spreadsheet from interpreting a cell as a formula. The guard applies to exported role and prompt text. Treat the apostrophe as an export safety convention rather than modifying the original board or prompt.
The CSV is a simple editorial handoff, not a native project file for a video editor. It does not contain source media paths, frame rates, transitions, audio tracks, captions, or export presets. Add those details in the production system you use. If a receiving tool converts seconds to frames, check its rounding behavior and ensure the total still matches the intended sequence.
Structural review versus creative judgment
review_shot_list first checks that the timing is internally consistent. It then looks for explicit action and camera labels in each composed prompt. A missing label produces a small warning with a shot index and code. The result also contains a manual checklist for subject continuity, action clarity, camera movement, editorial text, timing, accessibility, and independent factual verification.
Warnings are deliberately limited to observable structure. An action line can be present while describing too many events. A camera line can be present while contradicting the scene. A prompt can be well formed while requesting an impossible mechanism. The review helper does not rate aesthetics, predict generation quality, certify a model output, moderate material, or resolve licensing and consent questions. A clean report means those narrow checks passed, not that the plan is ready for every use.
Use the review result to make a production checklist rather than a leaderboard. If a shot intentionally has no camera instruction, note that the tool may warn and decide whether that omission is appropriate. If exact labels were removed during manual editing, the helper does not infer their intended replacements from prose. Keeping a small structured scene map alongside the prompt is often easier than trying to recover structure from a long unstructured sentence later.
Workflow: a restrained product demonstration
Begin with a specific subject description that can be repeated without ambiguity: material, identifying shape, and one color cue are usually enough. Choose establishing, hero, detail, action, and closing if each role answers a different question. If the hero and establishing prompts produce almost identical images, remove one rather than adding adjectives just to justify another generation.
For the action shot, replace the generic movement with the actual interaction: a lid opens, a switch moves, or a page turns. Keep the surrounding objects stable. Use a detail shot only when its close view teaches something about the object, such as a hinge, texture, or join. A visually attractive insert can still interrupt the sequence if the audience cannot understand how it relates to the action.
Reserve exact product names, prices, measurements, and legal copy for editorial text that you can control and verify. The closing role leaves room for that text but does not ask a generator to create it. After generation, compare each clip with the brief and inspect actual continuity. The fact that written fields match does not establish that object proportions, hands, labels, or motion remain consistent in the output.
Workflow: an explanatory sequence
Use establishing to orient the viewer and comparison or detail to isolate a relationship. A stable overhead view can help with two objects or a diagram, while an action shot can show a single movement. State what the viewer should notice before choosing the camera. If several relationships need explanation, split them into separate scenes and add clear captions in an editor rather than requesting a complex diagram to transform repeatedly inside one clip.
Educational plausibility is not factual validation. A gear can look realistic while rotating incorrectly, a paper diagram can imply the wrong relationship, and a laboratory-looking scene can suggest a measurement that was never made. Keep the visual brief separate from the factual explanation. Review any teaching claim against an appropriate source before presenting a generated scene as evidence.
The structural checklist can remind a team to validate timing and labels, but it cannot complete that factual review. An intentional field change should be explained by the lesson, not hidden to obtain a consistent-text report. Save the revised scene maps with the lesson plan so a future editor can understand why a particular transition or comparison was chosen.
Workflow: a short narrative concept
Give each shot one narrative beat. An establishing view can introduce a place, an action can reveal a discovery, and a reaction can give that discovery meaning. Repeating a clothing description or prop description in every relevant scene makes the plan clearer, but the library does not carry visual memory between independent generation calls. A model or editor must still manage identity and spatial continuity.
The brief builder uses shared fields for speed. When a sequence needs a change of location, a new viewpoint, or a different action in every shot, use the lower-level storyboard planner instead. Keep transition shots purposeful: a slow move toward a doorway or a cut to a matching shape can help an editor bridge two scenes, but a transition is not a substitute for explaining where the character went.
Maintain a separate continuity note for important details: which hand holds a prop, where the light comes from, what remains outside the frame, and whether a door is open or closed. These are production decisions rather than hidden parameters. Include relevant details explicitly in prompts and verify them in the actual media. A deterministic text plan does not guarantee a deterministic video.
Workflow: a small creative experiment
Choose one scene and vary one decision at a time. For a camera experiment, keep subject, setting, action, lighting, and style constant while comparing static and push-in descriptions. For a material experiment, keep the viewpoint and motion fixed while changing the object surface description. Save both the input map and the composed prompt so the comparison remains intelligible later.
Do not treat repeated generation as a controlled experiment unless the provider's settings and output variability are accounted for. This package has no seed management, statistical scoring, or service integration. It can make the written changes explicit, which is useful, but it cannot isolate every cause of a visual difference. Review the output qualitatively and note the generation environment separately.
The supplied external references are optional browsing material distributed later in this guide. The package does not fetch them, endorse their contents, or treat them as documentation for a provider API. The collection preserves the original ten selected URLs in their original order, followed by an additional user-supplied preprint download reference. The same ordered collection is available as bundled JSON. Their indexing, moderation state, availability, and current contents are not implied by inclusion in a package.
Editing plans without losing the source of truth
Keep the brief, structured scenes, composed prompts, and editorial notes as distinct records. If you edit a prompt directly but leave its scene map unchanged, the two representations can diverge. That is not automatically an error, but it should be intentional. Recompose prompts after scene changes when you want the structured fields to remain authoritative. Store a revision note when you deliberately replace a prompt with custom prose.
The planner does not automatically resynchronize those representations, because a manual edit might add information that is not captured by the built-in fields. Similarly, changing a duration without updating later start and end times invalidates a timed board. Rebuild the timeline through create_storyboard rather than repeatedly patching individual numbers. The formatter and exporter reject inconsistent timing instead of silently correcting it.
For team handoffs, include a short statement of what the plan does not contain: footage, provider settings, sound design, captions, and final approval are separate. A useful CSV makes the shot sequence visible without pretending to be a completed edit. Review the sequence, test one representative shot, and then decide how much of the remaining plan still makes sense. The toolkit supports that decision process; it does not replace it.
Installation
# Add this entry to the deps list in your project's mix.exs:
{:cinematic_shotlist_toolkit, "~> 0.1.1"}
# Then run mix deps.get in your project terminal.Elixir 1.15 or newer is required for the supported runtime. The package has no runtime dependencies and no custom installation code. Its functions use ordinary Elixir maps and lists rather than a provider-specific request format.
Quick start
A complementary browsing resource is Reference 01: diary page.
alias CinematicShotlistToolkit, as: Kit
prompt = Kit.build_prompt(%{
"subject" => "a matte ceramic travel mug",
"action" => "rests on a wooden desk while a thin thread of steam rises",
"setting" => "a quiet home office beside a window",
"camera" => "push-in", "style" => "cinematic",
"lighting" => "soft early morning window light",
"pacing" => "one calm continuous action", "aspect_ratio" => "9:16",
"negative" => ["unwanted text", "abrupt camera jumps"]
})
IO.puts(prompt)The returned string is structured by subject, action, setting, camera, style, lighting, pacing, frame, and optional avoidance instructions. Known preset identifiers expand into readable descriptions. Custom descriptions remain usable when a preset does not fit the scene.
Copy the resulting text into the generation interface you choose, then inspect the output. This package creates instructions, not a rendered clip. A stronger prompt can make a request clearer, but the actual model, reference material, generation settings, and editorial decisions still determine the result.
Why use a structured prompt?
A useful video prompt describes a scene rather than a list of fashionable adjectives. Start with a recognizable subject, give that subject one main action, and describe enough of the environment to establish spatial context. Camera movement, lighting, and visual treatment should reinforce that main action instead of competing with it.
For example, asking for a person to enter a room, open a box, react, walk to a window, and transform the scene into a different location places many separate events in one short clip. A storyboard is usually a better way to express that sequence. Each shot can carry one action, and an editor can control the transitions between them.
The composer makes those decisions visible. It does not score your prose or infer missing story elements. If you omit a lighting field, it simply leaves lighting out. If you supply conflicting descriptions, it preserves them rather than pretending to resolve a creative contradiction. Read the final prompt before using it.
API overview
| Function | Result | Use |
|---|---|---|
build_prompt(input) | String.t() | Compose a single structured prompt |
build_from_template(id, overrides) | String.t() | Start from a template and replace selected fields |
list_templates(category \ nil) | list(map()) | Browse all templates or one category |
get_template(id) | map() | Retrieve an immutable template value |
get_presets() | map() | Retrieve independent camera and style maps |
list_references() | list(String.t()) | Return the immutable list of eleven optional external references |
create_storyboard(shots, options \ %{}) | map() | Plan sequential shot timing |
format_storyboard(board) | String.t() | Export a validated plan as readable text |
get_shot_roles() | list(map()) | Browse eight reusable editorial shot roles |
plan_shot_list(brief) | map() | Expand a brief into a timed role-based sequence |
continuity_report(scenes, fields \ nil) | map() | Compare selected written fields between adjacent scenes |
export_shot_list_csv(board) | String.t() | Export a validated plan as CSV text |
review_shot_list(board) | map() | Return structural warnings and a separate manual checklist |
No function performs a network request. Template and preset accessors return immutable values, so editing a result does not change the package's built-in library.
Prompt fields
Subject and action
For a public creator-profile example, see Reference 02: podcast page.
subject is required and must be a nonempty string. Choose an object, character, group, or environmental feature that a viewer could identify in a frame. A subject such as "a ceramic mug on a wooden table" is easier to work with than an abstract intention such as "productivity and inspiration."
action is optional, but it is often the most important field for video. Describe what changes over time: a hand turns one page, leaves move in a breeze, or a traveler pauses beside a doorway. If the action requires several distinct beats, break it into separate shots rather than lengthening a single instruction indefinitely.
Setting, camera, and style
setting establishes location and object relationships. Keep the environment specific enough to support the action, but do not add unnecessary background characters or props that must remain consistent across multiple frames.
camera can be a built-in identifier or a custom sentence. A stable shot is often preferable when the subject already has substantial motion. A moving camera can make a static subject more interesting, but combining camera orbit, zoom, tracking, and multiple cuts usually creates an unnecessarily difficult request.
style can also use a preset or custom text. Material detail, line quality, color palette, and composition are more actionable than a long sequence of unrelated style labels. Keep the chosen treatment consistent across a storyboard unless the contrast between styles is an intentional editorial choice.
Lighting, pacing, frame, and negative instructions
lighting describes the source, direction, and softness of illumination. Choose a coherent setup: a window on one side, diffuse overcast light, or a controlled studio arrangement. Do not request contradictory times of day unless you deliberately want a transition and have planned enough shots to show it.
pacing describes how the action should feel. Terms such as "one deliberate action with a short pause" can communicate an editorial intention more clearly than a vague instruction to make the clip exciting.
aspect_ratio accepts 16:9, 9:16, 1:1, 4:3, or 3:4. The value is written into the prompt. It does not set a provider parameter or change the dimensions of an output file. Select the actual aspect ratio separately in the tool you use.
negative accepts a string or a list of strings. Repeated items are removed while preserving their first occurrence. Avoidance instructions are plain text: this package does not translate them into a model's separate negative-prompt channel or guarantee that a model will honor them.
alias CinematicShotlistToolkit, as: Kit
prompt = Kit.build_prompt(%{
"subject" => "a paper landscape with layered hills",
"action" => "moves slightly to create gentle parallax",
"camera" => "tracking", "style" => "stop-motion",
"negative" => ["unwanted lettering", "sudden scene changes", "unwanted lettering"]
})
IO.puts(prompt)Validation behavior
Inputs must be plain maps with string keys. Atom-keyed maps and structs are rejected. Unknown fields are rejected so misspellings do not silently disappear. For example, use lighting, not lightning, and use aspect_ratio, not a provider-specific ratio field.
Text values are trimmed and internal whitespace is collapsed into single spaces. Each text field has a limit of 3,000 Unicode characters. A missing optional text field is omitted; a non-string value is rejected. An empty required subject or empty negative-instruction item is also rejected. Use an empty negative list if you want no avoidance line.
Invalid values throw ArgumentError. Applications that gather user input should catch these errors and explain the relevant field rather than showing a generic failure message.
alias CinematicShotlistToolkit, as: Kit
try do
Kit.build_prompt(%{"subject" => " "})
rescue
error in ArgumentError -> IO.puts(Exception.message(error))
endValidation protects the data shape, not the factual accuracy of a scene. It does not establish that a mechanism is physically possible, that an educational demonstration is correct, or that a described location exists.
Camera presets
| Identifier | Intended effect |
|---|---|
static | Stable framing without zoom |
push-in | Slow movement toward the subject |
orbit | Gentle partial movement around the subject |
tracking | Lateral movement following the subject |
overhead | Top-down arrangement and visible surfaces |
handheld | Restrained documentary-style movement |
Presets are descriptive text, not executable camera controls. Their role is to provide a consistent starting vocabulary. Replace a preset with a custom description when a scene requires a more precise viewpoint, such as a shoulder-level shot with the subject remaining on the left side of the frame.
Visual-style presets
| Identifier | Intended treatment |
|---|---|
cinematic | Realistic scene geometry and coherent proportions |
documentary | Observational detail and restrained color treatment |
product | Studio-style material detail and uncluttered framing |
illustration | Consistent editorial illustration in motion |
stop-motion | Tactile materials and deliberate incremental movement |
minimal | Simple shapes and a limited color palette |
alias CinematicShotlistToolkit, as: Kit
available = Kit.get_presets()
IO.inspect(Map.keys(available["camera"]))
IO.inspect(Map.keys(available["style"]))Template library
A public collection-of-links reference is Reference 09: university-hosted post.
Every template contains an identifier, name, category, practical purpose, and structured prompt fields. The categories are product, lifestyle, nature, education, abstract, and narrative, with four templates in each category.
alias CinematicShotlistToolkit, as: Kit
IO.inspect(Enum.map(Kit.list_templates("product"), & &1["id"]))
template = Kit.get_template("product-hero")
IO.puts(template["purpose"])
prompt = Kit.build_from_template("product-hero", %{
"subject" => "a matte ceramic travel mug", "aspect_ratio" => "9:16"
})
IO.puts(prompt)An unknown template identifier throws a ArgumentError. An unknown category returns an empty list. Overrides replace individual fields; they do not merge negative-instruction lists. Supplying %{"negative" => []} replaces a template's default avoidance instructions with an empty list.
Product templates
product-hero - Product hero reveal
Use a single recognizable object and one reveal. Leave negative space for editorial text that will be added later, rather than asking the generator to produce a brand label.
product-detail - Material detail study
Use a close view when surface texture matters more than the entire product. Describe the material in concrete terms, and keep the requested movement small enough to preserve the shape.
product-use - Everyday product use
Show one functional action instead of several unrelated interactions. Specify the number of hands and the unchanged product identity, then use editing to connect the clip to a wider demonstration.
packaging-reveal - Simple packaging reveal
Keep packaging unbranded and request one reveal with a stable viewpoint. Separate elaborate unboxing sequences into individual shots so each action can be evaluated and revised independently.
Lifestyle templates
coffee-morning - Morning coffee atmosphere
Atmosphere works best with a stable scene and subtle movement. Focus on steam, light, or a small interaction; do not combine them with several camera moves and a dramatic scene change.
desk-routine - Focused desk routine
Use this scene for a routine or productivity story. Establish clothing, position, and desk layout early, and repeat those details in later shots if continuity is important to the edit.
city-walk - Quiet city walk
Give the subject one visible action and let the camera follow it. A stable outfit and restrained setting help the viewer read the motion without competing details or unnecessary scene transformations.
cooking-step - Single cooking step
Choose one visible preparation step instead of a full recipe. Use the overhead view to make object positions easy to understand, and add labels or quantities in the editing stage.
Nature templates
forest-morning - Forest morning
Anchor the composition with a path or another stable feature. Keep the wind and camera motion gentle so the scene reads as one coherent landscape rather than a moving collection of details.
river-closeup - River surface detail
Use water as the main moving element and hold the surrounding geometry steady. Avoid stacking weather changes, large camera moves, and rapid water motion into a single short scene.
coastal-breeze - Coastal breeze
Describe the foreground and distant background separately, but give only one element a primary action. A gentle foreground movement can communicate weather and mood without requiring a complex sequence.
rain-window - Rain on a window
Use the window as a stable reference plane and emphasize one subtle movement. Defocused backgrounds reduce unnecessary object changes and leave room for a calm voiceover or music-led edit.
Education templates
paper-diagram - Paper diagram explanation
Demonstrate relationships through objects and movement rather than generated labels. Keep the number of elements small, and add exact terminology, measurements, or arrows as separate editorial overlays.
mechanical-motion - Mechanical motion concept
Treat the scene as a visual concept, not a certified technical simulation. Keep the mechanism simple and verify physical or educational accuracy separately before using the result as instructional material.
classroom-object - Classroom object study
Use a clear object and a restrained demonstration when explaining a concept. Generated images can be suggestive rather than scientifically precise, so validate the intended phenomenon before publishing an educational claim.
tutorial-transition - Tutorial chapter transition
Use simple motion to mark a chapter change without relying on readable generated text. Leave the cards blank and place the actual chapter titles over them in an editor.
Abstract templates
color-ribbons - Abstract color ribbons
Define a small palette and a single direction of movement. Abstract scenes become easier to evaluate when shape, color, and motion are each constrained rather than changed simultaneously.
paper-landscape - Paper landscape
Describe the material and movement together so the tactile style remains coherent. Use a simple landscape silhouette and slight parallax instead of demanding a complicated transformation of the entire scene.
light-study - Soft light study
Make light the only changing element. Keeping the object and viewpoint stable makes this scene useful for testing how lighting instructions affect contrast, texture, and visual emphasis.
loop-shapes - Loop concept with simple shapes
Returning to the starting pose is a planning instruction, not a guarantee of seamless looping. Inspect the first and last frames and create the final loop with trimming or transitions if needed.
Narrative templates
arrival-scene - Character arrival
Introduce a character with one identifiable action and a small set of stable visual details. Reuse the clothing and bag description in later shots rather than relying on the model to infer continuity.
discovery-scene - Small discovery
Use a restrained discovery beat instead of describing the entire plot. Separate noticing, reaching, and opening into multiple clips when each action needs precise timing or clear object interaction.
reaction-scene - Restrained character reaction
A short reaction shot should communicate one emotion without an elaborate performance. Describe the gaze direction and keep the camera stable so facial movement remains the focus of the scene.
closing-scene - Quiet closing image
Use a stable final composition to let an edit settle. Match identifying details from earlier shots and keep the ending action simple enough to hold under a final voiceover or music cue.
Planning a product demonstration
An optional external scheduling-profile reference is Reference 06: project profile.
A concise demonstration usually needs an establishing shot, a functional action, and a closing image. These three shots do not need identical prompts, but the product description should remain consistent. Use the same material, color, identifying shape, and surrounding objects where continuity matters.
The first shot can establish the object without showing hands. The second can show one interaction, such as opening a lid or turning a page. The final shot can return to a stable view that leaves room for a caption added in an editor. Avoid asking the generator to create exact packaging text, prices, or legal copy inside the scene.
alias CinematicShotlistToolkit, as: Kit
board = Kit.create_storyboard([
%{"subject" => "a closed matte ceramic travel mug", "action" => "rests on a wooden desk",
"camera" => "static", "duration_seconds" => 3},
%{"subject" => "the same matte ceramic travel mug", "action" => "is opened slowly by one hand",
"camera" => "push-in", "duration_seconds" => 4},
%{"subject" => "the same matte ceramic travel mug", "action" => "remains beside a notebook",
"camera" => "static", "duration_seconds" => 3}
], %{"title" => "Travel mug concept"})
10.0 = board["total_duration_seconds"]
IO.puts(Kit.format_storyboard(board))Storyboard timing
A public publication-profile reference is Reference 05: public profile.
create_storyboard accepts between 1 and 50 shots. Each shot uses the same prompt fields plus an optional duration_seconds. The default duration is four seconds, and an options map can change it with default_duration_seconds.
Durations must be finite numbers from 1 to 60 seconds and are rounded to three decimal places. The returned plan contains sequential shot indices, start and end times, per-shot durations, and composed prompts. The total is the sum of the planned durations.
These are editorial planning values, not assertions about a service's supported clip length. The package cannot force a generator to produce exactly four seconds, preserve a character between independent runs, or create an edit automatically. Match the plan to the options your generation tool actually offers, then adjust timing in an editor.
format_storyboard validates shot order, finite timing, contiguous intervals, and a matching total before producing text. If you manually edit a serialized storyboard, keep those values consistent. A plan with overlapping shot times or a mismatched total is rejected rather than formatted as though it were valid.
Education and explanatory scenes
For an optional article-profile reference, see Reference 08: shot-list article.
For instructional content, separate visual demonstration from exact information. A video can illustrate an idea with colored objects, a simple mechanism, or a single observable motion. Precise terminology, measurements, equations, and warnings are usually better added as editorial text or narration that you can independently check.
alias CinematicShotlistToolkit, as: Kit
prompt = Kit.build_from_template("paper-diagram", %{
"subject" => "three paper circles in blue, yellow, and green",
"action" => "move one at a time into a simple triangular arrangement",
"negative" => ["readable generated labels", "extra objects", "abrupt cuts"]
})
IO.puts(prompt)The educational templates are creative starting points. They are not scientific simulations or verified teaching assets. A prism, gear, or diagram may render plausibly while still containing a factual error. Review the final visual against the intended lesson before using it as evidence or instruction.
Character continuity and narrative scenes
A narrative plan benefits from a short continuity note outside the prompt: the character's clothing, the important prop, the setting, and the time of day. Repeat those concrete details in every relevant shot. The package does not maintain a visual memory, attach reference images, or control a model's identity consistency.
Begin with one arrival or establishing beat, then one discovery or interaction, and finish with a reaction or closing image. If a sequence requires a character to perform several precise actions, create several prompts instead of a single paragraph describing all of them.
Use a restrained camera for reactions. A large camera move can make a small expression harder to read, and a complicated background may pull attention away from the performance. Stable framing also makes it easier to compare successive generations when testing one prompt change.
Image-reference workflows
For a separate bookmark-collection reference, see Reference 04: prompt-notes page.
The kit can help write the motion instructions that accompany an image-to-video workflow, but it does not accept image files or upload references. Choose and manage the actual reference image in the tool you use.
When a reference already establishes subject, clothing, and composition, focus your text on what should move and what should remain stable. A small head turn, gentle fabric motion, or subtle camera push can be easier to evaluate than a large transformation of the scene. Avoid asking the prompt to contradict the reference's object layout unless that change is intentional.
A practical iteration loop
An optional public conversation-profile resource is Reference 03: public resource page.
- Write a plain one-sentence description of the desired shot.
- Put the recognizable subject and primary action into separate fields.
- Add only the setting details that support the action.
- Choose either restrained camera motion or substantial subject motion first.
- Select a consistent lighting setup and visual treatment.
- Build and read the resulting prompt before generation.
- Inspect the generated result for identity, motion, framing, and unwanted changes.
- Change one instruction at a time and compare the next result.
- Keep a small record of the prompt, actual settings, and observed outcome.
- Use an editor for transitions, exact typography, audio, and final timing.
A useful comparison might keep every field fixed while changing only camera from static to push-in. Another might compare a short action sentence against a longer description. Changing subject, style, camera, and lighting simultaneously makes it harder to understand which instruction mattered.
Negative instructions without overloading the scene
Use avoidance instructions for a short list of concrete problems that you have observed. "Unwanted readable text" or "abrupt camera jumps" can identify a useful constraint. A long list of unrelated negatives can obscure the positive description and may not help a particular model.
The package deduplicates repeated entries, but it does not reconcile contradictions. If an avoidance instruction conflicts with the primary action, revise the scene yourself. For example, asking for a handheld documentary shot while also demanding absolutely no camera movement describes two different intentions.
External reference data
The eleven optional references in this guide are also included in references.json, under the opaque collection identifier REF-29. The JSON contains source URLs only; it does not contain account credentials, target-site mapping, cookies, or analytics data. The entries are supplied by the package maintainer as optional external resources, not verified runtime dependencies.
alias CinematicShotlistToolkit, as: Kit
references = Kit.list_references()
11 = length(references)
IO.inspect(references)For applications that need the raw data, the package includes priv/references.json; use the public reference accessor for ordinary runtime access. Deriving a new list from list_references() does not change the built-in collection. Links are not opened, pinged, downloaded, or checked automatically by this function. Any external page can change independently of a package release, so its current contents and availability must be assessed separately if you choose to use it.
Elixir modules, immutable maps, and serialization
Call the functions on CinematicShotlistToolkit. Plans are ordinary maps with string keys. This example round-trips a locally created plan using Erlang external-term serialization; do not treat external-term decoding as a general untrusted-file input format:
alias CinematicShotlistToolkit, as: Kit
board = Kit.create_storyboard([%{"subject" => "a quiet forest path", "camera" => "static"}])
encoded = :erlang.term_to_binary(board)
restored = :erlang.binary_to_term(encoded, [:safe])
true = restored == board
IO.puts(Kit.format_storyboard(restored))The public module accepts maps, lists, strings, and numeric durations, returning ordinary immutable Elixir values. Validation still applies when input originates from a form, a JSON file, or another untyped source. The examples use string keys consistently and never create atoms dynamically from user input.
alias CinematicShotlistToolkit, as: Kit
scene = %{"subject" => "a small glass vase on a wooden table",
"camera" => "static", "aspect_ratio" => "1:1"}
prompt = Kit.build_prompt(scene)
true = is_binary(prompt)The Elixir edition has no browser component, telemetry, background jobs, or application initialization step. A generated data module embeds the immutable template, role, preset, and reference values; it never contacts external reference pages. Equivalent JSON files are bundled in priv/ for inspection, without adding a JSON parser as a runtime dependency. The API uses snake_case field names consistently, including aspect_ratio, duration_seconds, and default_duration_seconds.
Examples included in the package
examples/product_demo.exscomposes a product prompt and exports a three-shot plan.examples/storyboard.exscombines nature templates into a short two-shot storyboard.
The source project also contains ExUnit tests, executable documentation examples, and Python/Elixir cross-runtime fixture checks. Tests are development files and are intentionally excluded from the published runtime archive. The published examples use only the package's own exports and do not require provider credentials.
Troubleshooting
A separate discussion-profile reference is Reference 07: publication post.
An unknown-field error appears. Check the spelling of the field against the prompt interface. Provider-specific parameters such as model names, seeds, resolution, or credits are not part of this local planner. Configure those separately in the tool you use.
The action looks too complicated. Break it into smaller shots. A scene with several interactions can be grammatically clear while still being an impractical request for a short generated clip.
The output contains unwanted writing. Remove instructions that imply exact signage or labels, keep the scene visually simple, and add the required typography afterward. Negative text is not a guarantee that unwanted writing will disappear.
The character changes between shots. Repeat concrete identifying details, use the reference controls offered by your generator, and inspect each result. The package cannot enforce cross-generation identity.
The result does not match the planned duration or frame. Storyboard durations and aspect-ratio descriptions are planning metadata and prompt text. They do not control generation settings. Select compatible settings in your provider or editor.
A formatted storyboard is rejected after manual editing. Check the shot indices, start times, end times, durations, and total. They must form a contiguous sequence. Recreate the plan with create_storyboard when unsure.
Frequently asked questions
Does this package generate videos?
No. It returns prompt text and storyboard data. It does not render, download, or host media.
Is an API key required?
No. All exported functions work locally. Any credentials required by a separate generation service belong to that service and are not handled by this package.
Are the templates guaranteed to work with every model?
No. They provide readable creative instructions, not verified model-specific syntax. Review and adapt them to your actual tool and settings.
Can I replace the built-in subject and action?
Yes. Use build_from_template with overrides, or retrieve a template copy and edit its fields before calling build_prompt.
Can I add my own templates?
Yes. Store your own scene maps in your application and pass them to the composer. This release does not provide a global template-registration API or write changes back to its built-in JSON files.
Does it translate prompts?
No. Text is preserved apart from whitespace normalization. You can supply your own language, but the package does not perform translation or infer a model's preferred language.
Does it guarantee a seamless loop or accurate simulation?
No. Loop and demonstration templates express an intention. Inspect the result, validate relevant details, and use editing where needed.
Can it validate generated media?
No. Input validation checks local data shape and storyboard timing. It does not analyze images, assess movement, verify scientific claims, or compare a generated clip with a reference.
Does it send prompts anywhere?
No. There are no network calls, telemetry events, remote template updates, or background uploads in the runtime code.
Privacy, limitations, and license
A separate personal-profile reference is Reference 10: resource collection.
Your application decides where to store or send the generated text. The toolkit itself does not collect it. When integrating the composer into a larger system, review that system's logging, analytics, provider requests, and retention rules separately; local behavior in this package does not establish privacy properties for another service.
The toolkit is intended for creative planning, not as a substitute for an editor, a factual review, a technical simulation, or the controls of a video-generation interface. It cannot enforce model behavior, establish service availability, or guarantee a specific artistic result.
The package is distributed under the MIT License. See LICENSE for the full terms. The initial release includes the offline composer, template library, preset maps, storyboard planner, examples, and declarations described above. Future interfaces are not promised by this README.
Elixir integration patterns
Keep prompt construction separate from provider submission. A command-line script can read a scene map from a JSON file, call build_prompt, and write the resulting text to standard output. A Livebook notebook can browse list_templates() and copy the returned fields into a cell for editing. A web application can validate its form input server-side and display a preview without transmitting that text to any generation service. All three workflows use the same local functions.
For repeatable experiments, save the input map alongside the generated prompt and note which template identifier you started with. If you change a subject, camera movement, and visual treatment simultaneously, it becomes difficult to identify which change helped. Keep a small experiment log with one intentional change per iteration. This package does not write that log automatically, because storage location and retention policy belong to the application using it.
Returned template, preset, and reference values are immutable. You can derive a new template map with Map.put, append an application-specific reference with ++, or replace preset wording in your own configuration without modifying the built-in data. Copying is not a versioning mechanism: persist your modified inputs explicitly if they must survive a process restart. The bundled library remains the same until you deliberately install another release.
Storyboards are JSON-compatible planning records, not a video file format. A downstream editor can use their start times and durations as a draft timeline, but this package does not create subtitles, render frames, synthesize audio, or enforce cuts. Check the final result with the media tools you use. A JSON round trip preserves the plan's values; format_storyboard still checks timing consistency after loading a record that may have been manually edited.
Handle invalid input with a focused message. ArgumentError identifies a wrong data type, unexpected key, disallowed value, missing subject, unsupported ratio, unknown template, or invalid timing. Neither exception proves that the creative description is accurate. Validation does not moderate a scene, resolve contradictory instructions, certify a teaching example, or guarantee a provider will follow the prompt.
The reference helper is optional. Calling list_references() returns eleven strings embedded in the data module; the same URLs are present in the bundled JSON manifest. It does not request a URL, test indexing, inspect a profile, submit a bookmark, or validate any claim made on an external page. Keep any network fetching in a separate application component with its own error handling. The supplied links can change or become unavailable independently of this release.
Elixir edition notes
The Hex application is named cinematic_shotlist_toolkit, while its public module is CinematicShotlistToolkit. Function names remain snake_case. Input and output maps use string keys for predictable interchange with forms and JSON-compatible application data. The package never calls String.to_atom on user data, and it does not accept provider credentials as prompt fields.
Elixir data is immutable. Change a scene by deriving another map, then call the composer again; do not expect assignment to alter a previously returned board. The planner retains role and scene metadata explicitly so an application can decide which representation is authoritative. It does not automatically rebuild a prompt when an application derives a modified scene map.
There are no production dependencies. ExDoc is a development-only build dependency used to publish the guide and API reference. Template and preset values are embedded in a generated module, and the equivalent JSON files are included under priv/. The JSON files are reference artifacts, not instructions fetched from an external service. A JSON parser is deliberately not part of the runtime API; applications can choose their own encoder or decoder for their environment.
ArgumentError is the public input-validation exception for unsupported field names, incorrect shapes, missing subjects, invalid template identifiers, and inconsistent timing. A successful call validates only that narrow contract. It does not establish creative quality, factual accuracy, indexing, external-page availability, or compatibility with a media-generation provider.
Additional preprint download reference
An additional optional resource is Reference 11: user-supplied preprint download link.
This entry is provided as a reference URL only. The package does not download the document, summarize its claims, establish its review status, or treat it as evidence of provider compatibility. No paper title, author identity, research result, or endorsement is inferred from its address. The original ten references remain unchanged, and this URL is appended as the eleventh entry in the bundled REF-29 collection and the local reference accessor.