The parallel-files problem
Every localisation team has felt this. A feature film ships, subtitles get commissioned in 24 languages, dubbing scripts in 6. Somewhere along the way, the production team made three edits to the English master that didn’t propagate evenly across all 30 derivative files. By the time anyone notices, three of the Italian subtitles disagree with the English, the Japanese dub is five seconds out of sync, and the localisation vendor is asking for the v4 final final FINAL script by EOD.
ScreenJSON ends that workflow. It doesn’t improve the management of parallel files; it makes parallel files unnecessary.
One file, every language
Every user-facing textual field in a ScreenJSON document is a map keyed by BCP 47 language tag, not a plain string:
{
"text": {
"en": "We have ninety seconds.",
"fr": "Nous avons quatre-vingt-dix secondes.",
"ja": "九十秒しかない。",
"es": "Tenemos noventa segundos.",
"de": "Wir haben neunzig Sekunden."
}
}
One line of dialogue, five languages. The viewer picks one at render time. The exporter picks one at export time. The whole screenplay is a single artifact.
Where translations actually live
At the root: title, logline.
On the cover: title again, with optional extra free text.
On every scene: the slugline’s desc.
On every element: the text field for action, dialogue,
parentheticals, shots, transitions, and general.
On every note: the note text itself.
Character fields are usefully bilingual-or-more: desc is language-keyed,
and the canonical name (the uppercase cue used in formatting) stays a
single string because cue conventions are fixed per language. Alternate
spellings for other languages go in aliases.
The translation workflow in practice
A realistic path looks like:
- Author in the source language. Final Draft, Fountain, whatever — export to ScreenJSON.
- Snapshot. Tag the document with a revision label like
"en-final"and record it inrevisions. - Project. Emit a translation-ready bundle: every element’s
text.en, keyed by element UUID, in a flat file your TMS can ingest. The JSON structure means this is a one-liner. - Round-trip. Your TMS returns a bundle of translated strings, keyed by element UUID. Merge them back into the same ScreenJSON document under the target language key. No file duplication; no parallel-file drift.
- Render in any supported language with
screenjson export --lang fror by settingviewer.lang = 'fr'.
Because every element has a stable UUID, that merge is deterministic and idempotent: you can re-import the same translation bundle a dozen times and end up with the same document. You can also diff “what translations changed between build 14 and build 15” with ordinary JSON diff tooling.
On right-to-left languages
Each text field can be accompanied by a dir flag (ltr or rtl) on the
element. A screenplay with Arabic or Hebrew dialogue can intermix
directions without forcing the whole document into one direction. The
viewer respects dir per element.
On continuity and dubbing
Dubbing scripts care about things a literal translation doesn’t: syllable
count, lip-sync shape, reaction beats. ScreenJSON doesn’t do that work
for you — that’s the dubber’s craft — but it gives you a clean place to
record the dubbed line as an alternate text key, and it lets you record
the dubber’s parentheticals as real parenthetical elements rather than
inline notation.
A common convention is to use region-qualified tags for dub-specific
lines: fr for a literal translation, fr-FR-dub for the lip-synced
dubbing version.
On subtitle timing
ScreenJSON doesn’t carry frame-accurate timing — that belongs in a subtitle format (SRT, TTML, WebVTT), and should be generated downstream from the locked ScreenJSON. But because every dialogue element has a UUID, the link back from a subtitle line to its source screenplay line is trivial: keep the element UUID as a sidecar in your subtitle file and you can round-trip between the two.
Multi-language title pages
The cover’s title field is a language map too. A screenplay released
internationally can carry “The Heist” (English), “Le Braquage” (French),
and “強奪” (Japanese) on the same cover, with the viewer picking the
right label for the right locale.
On machine translation
Nothing in the schema prevents you from running a first-pass machine
translation on every text field, keyed by source language, to seed a
target-language column. You’d then hand that seed to a human translator
in your TMS for review.
Because every string is keyed by element UUID, you can track exactly
which fields have been reviewed, which are still machine-seeded, and
which haven’t been touched yet — with any metadata discipline you like
in the meta block on each element.
Encryption and vendor trust
Pre-release translations are sensitive. AES-256 encryption of text runs (leaving structure, UUIDs, and revision metadata visible) lets you hand an encrypted document to a translation vendor’s ingestion pipeline — for routing, estimation, billing — without letting that pipeline see any dialogue. The vendor’s human translators decrypt locally, translate, re-encrypt, return.
Next
- Specification: language keys
- How-to: Localise dialogue into multiple languages
- How-to: Load a ScreenJSON document by URL
- Tool: screenjson-ui — supports multi-language rendering with a
langoption.