The three files
runtime.json, codegen.json and the generated code — who writes each, who reads each, and what changes when.
All documentation — Concepts
Start here
Concepts
Authoring for a build
Playing a story
The generated assets and code
The plugin and sync
On this page
A sync produces a directory. Three things in it matter to a game, and confusing them is the source of most “why is my change not showing up” questions.
| Written by | Consumed by | Changes when | |
|---|---|---|---|
runtime.json | the sync server | the runtime, while the game is playing | anyone edits a board, a node, or a field value |
codegen.json | the sync server | the code generator, while the editor syncs | anyone adds an entity, an enum, a variable, a command, a table |
| the generated code | the code generator | your compiler — C# in Unity, C++ in Unreal | the shape of the project changes — a new entity definition, a renamed variable |
The distinction that matters: a writer editing dialogue changes only the runtime file. No code is regenerated, nothing recompiles, and a build that ships it as data can take new content without a new binary. Adding a variable is a different kind of change, because a variable becomes a typed property and that is code.
Both files are resolved. Neither one is a dump of how TaleShard stores anything, and nothing in the plugin knows what a field’s storage looks like. That is deliberate: every rule about where a value lives is applied once, in the exporter, rather than re-implemented by each engine that reads the output.
runtime.json — the resolved story
This is the file the engine plays from. Every node in it arrives with its fields already read out of whichever store held them, its references already looked up, its rich text already rendered per language, and its exits already classified. It exists to enforce one rule, which has its own page: node meaning is resolved once.
It also carries the project-level tables the runtime needs — entities, entity definitions,
variables, contexts, media, tags, and the parsed
expression trees — plus a diagnostics array.
If runtime.json is missing, unreadable, or a format version the generator does not support, the
whole sync is refused rather than generating the other domains quietly. A half-generated project
compiles and is indistinguishable from a whole one, which is the worst available outcome.
codegen.json — the resolved declarations
Entity definitions, traits, enums, commands, variables, contexts, tables, media, tags, the board
tree, and every translation. The generators read this: it is what your Character class, your
Gender enum and your GameVariables properties are built from.
Everything in it arrives resolved too. An inheritance chain is already walked. A trait application’s fields already carry the address their values are stored at — which matters because a definition can apply the same trait twice, and each application’s values live under their own key. A command’s parameters are in the author’s order, with the position the caller’s arguments are indexed by. Every translation is already collected and rendered.
It carries no language names. What a definition becomes as a class, what a field becomes as a
property and how two colliding names are told apart are decided by each engine’s generator, because
those follow the target language’s rules and no other’s. The same codegen.json feeds the C#
generator and the C++ one.
The generated code
One tree, written into your project. Which assembly or module each part of it belongs to is on the two seams. Two rules about it:
Never hand-edit a generated file. The next sync overwrites it. There is exactly one deliberate exception, and it is the file that loads the payload — generated once when missing, never overwritten, so it is yours to change if you move off the default loading route.
The generated stores hold no storage. In Unity, GameVariables.Trust is a view over the
script runtime, not a field; in Unreal, a generated variable tag resolves through the session the
same way. Setting a value writes through to the runtime, which is what makes a save capture it and
a gate see it. A generated store that held its own copy would give you two answers to every
question.
What is also in the directory
manifest.json (the project’s name, slug and export-format version), media-map.json (filename to
media id), the media/ folder itself, and the sync’s own report. A board-only sync additionally
writes a delta file.