Skip to content

Your first attempt

The ordering rules and one-shot constraints that cost an afternoon each — the frozen policy, handlers before Play, and the tags the sync owns.

All documentation — Start here
On this page

Every item here is something the plugin refuses, reports, or silently does not do, and each of them is easy to hit on a first integration. None of them is a bug to work around; every one is a rule with a reason, and the reason is on the page it links to.

Order of operations

Bind before Play. A step presented before your binding is not replayed. The component’s events can be bound before a story exists, which is the whole reason to bind on the component rather than on the session.

Install node handlers before the story starts. Use Node Handlers after a step has been presented does not see that step. On the component, the Node Handlers list is installed for you when the session is built.

Register commands before the story starts. The component asks your command handler to register its commands when the session is built; a hand-built session needs your Register Commands call before Play. A command the story calls before anything registered it reaches On Command, runs, and answers nothing — implementing commands.

Do not call Advance from inside your step handler. The engine is mid-transition. Hand control back first — a button, a timer, a latent node — or an auto-advancing story recurses until the engine’s own limit stops it with a diagnostic.

The policy freezes

A policy is handed to a session at construction and never again. The Board Entries setting is read then, and only then; every write to a policy after it was applied is refused, naming the property. A policy asset is shared by every actor that references it, so it builds a fresh policy per session rather than being one — the player.

A policy naming a node type or a field the project does not have is an inert mistake. It is reported, once, on the diagnostics channel, and it silences nothing.

Play is not Restart

Play clears history, taken choices and said lines and leaves every variable where the previous run left it. Restart is the one that throws the world away. A “new game” button that calls Play plays the new game with the old game’s variables — starting a session.

The tags the sync owns

Node types, fields, entities, variables, commands, boards and media are all addressed by gameplay tags under TaleShard., and the sync registers them. They are what a tag picker shows, what a handler’s Node Type holds, and what Find Field takes.

Two consequences:

  • A tag is only there after a sync. A Blueprint written before the first sync has no tags to pick from. Sync first.
  • A code renamed in the editor keeps working in a tag. The sync writes a gameplay tag redirect from the old tag to the new one, so a tag a Blueprint held follows the rename. A code deleted is a tag gone from the tree after the next sync: every Blueprint that held it shows the break, and nothing matches silently in a shipped build.
  • The TaleShard field, variable and command nodes do not follow a rename. They name what they read by its code, so a renamed field reads as a removed one: the node shows an error and the sync window names it. Place the node again from the menu, under its new name.

The tag is the code, sanitised: letters, digits and underscores survive; anything else is dropped. A code that is nothing but punctuation becomes _.

Media

A step’s media reference is an id and possibly a URL. It does not load. Resolve it through the project’s media index into an address, and load that with the Load Media action — an address the index cannot resolve fails at once with its own reason, rather than arriving as a blank. Keep your own reference to what arrived; the action holds it only until it fires — loading media.

Language codes, not storage keys

The session’s Get Language is the project’s code. Get Language Key is the engine’s storage spelling, and the master language’s key is not its code. Hand the code to Set Language, to the UI strings and to a picker; hand the key to nothing — starting a session.

Saving

Save is refused while the story is waiting on a command, and before anything has been presented. The save is text; store it as text, in the plugin’s save-game object or in a string field of your own, and never through a second serializer — saving.

The sync tool starts and nothing happens

The sync window’s Cancel button works from the first second, including while the sync tool is still starting. Cancelling ends the tool: nothing is left half-written, and the next sync starts from where the cancelled one began.

The first wait — for the tool’s ready message — also gives up on its own after thirty seconds rather than waiting for ever, and the message names the binary it started. The usual cause is a binary that cannot run on this machine: another platform’s build, a partially downloaded file, or security software holding it. Check the Output Log for [TaleShardSync] lines, which are the tool’s own error output, then replace the binary with the one for this operating system from the release matching the plugin version.

Next

Reading a step, or where to go next.

Written for
Unity developers
Last updated