Skip to content

The three files

runtime.json, codegen.json and the generated code — who writes each, who reads each, and what changes when.

All documentation — Concepts
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 byConsumed byChanges when
runtime.jsonthe sync serverthe runtime, while the game is playinganyone edits a board, a node, or a field value
codegen.jsonthe sync serverthe code generator, while the editor syncsanyone adds an entity, an enum, a variable, a command, a table
the generated codethe code generatoryour compiler — C# in Unity, C++ in Unrealthe 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.

Written for
Unity developers · Advanced integrators
Last updated