The Unreal player
The session, the component that owns one, the subsystem that builds one without an actor, every verb, the frozen policy, and how a playthrough ends.
All documentation — Reference
Start here
Concepts
Authoring for a build
Playing a story
The generated assets and code
The plugin and sync
On this page
TaleShardSession is the one object an Unreal game holds to play a story. It is not a widget and
ships none: bind its steps and draw what it hands you.
Three ways to hold one, and where to start
| What it adds | |
|---|---|
TaleShardSession | the policy, the playthrough’s end, language codes rather than storage keys, the events, and a refusal with a reason on every verb |
| the TaleShard Player component | lifetime and binding order: it owns a session for as long as its actor lives, re-raises every event, and forwards every verb and read under the same name |
| the TaleShard game-instance subsystem | a session with no actor: an ambient conversation, a preview in a debug overlay. It lives as long as the game instance, so a session survives a level transition |
Getting one
| Route | When |
|---|---|
| the TaleShard Story actor | no wiring at all: it owns a component, puts the plugin’s dialogue screen on the viewport and starts the story when play begins. Get Player gives its component |
| the component’s Details panel | the ordinary case: set the payload, the policy asset, the command handler class and the node handlers, and the component builds its session when play begins |
| the component’s Create | the same, from code, with a payload and a language |
| the component’s Adopt | a session somebody else built — the subsystem’s, say — with Owned deciding who releases it |
| the subsystem’s Create Session and Create Session From Directory | no actor at all. The second reads the payload from a sync output directory and needs neither an asset nor generated code |
A policy is handed in at construction and freezes there. One setting can only be honoured at that moment — the one that asks the engine to offer a board’s remaining ways in when a path ends — because the engine takes it as a construction argument and never re-reads it. That is why there is no Set Policy on a live session.
Events
| Event | Raised when |
|---|---|
| On Step Presented | a moment the player sees. Draw it. Fires for every step, before any node handler runs |
| On Error Raised | the engine could not do what the data asked and carried on. Not the end. With nothing bound, an error goes to the log |
| On Ended | the playthrough is over, however it ended. Exactly once per playthrough |
| On Language Changed | the language changed and every drawn step has already been re-drawn in it |
| On Diagnostic | everything the engine reports, at every level, with its location. Always on the game thread |
| On Command | a command the story called that nothing registered a handler for |
On Language Changed carries the project’s code, never the engine’s storage key — so your own chrome follows in one node.
State
| Read | Notes |
|---|---|
| Get Payload, Get Policy | the story, and what this host declared. The policy is frozen |
| Get Current Step | the step on screen; false when there is none |
| Is Playing | a story is under way — neither idle nor finished |
| Is Awaiting Choice | |
| Is Suspended | a command is running and the story is waiting |
| Get Pending Command Code | lets you say cannot save during startCombat rather than cannot save |
| Get Last End | how the last playthrough ended; false when none has |
| Can Back, Can Forward | |
| Get Audio | the current step’s audio |
| Get Entity Palette | how to draw an entity — see entity display |
| Get Visit Count | how many times a node has been played this playthrough |
Gate a Back button on Can Back. Back from the opening moment rewinds past the beginning: it restores the variables the story opened with, leaves the engine idle, and blanks the screen.
Language
| Read | What it is |
|---|---|
| Get Language | the project’s code — en, it. What UI strings, a string table and a picker all want. Empty when the project never named a master language |
| Get Language Key | the engine’s storage spelling. Only for a host talking to the engine’s own view |
| Get Languages | everything a picker needs, in offer order: master first, then each declared language, blanks dropped and duplicates collapsed |
Draw the option’s Label; hand its Code to Set Language.
Driving it
| Verb | Notes |
|---|---|
| Play | begin at the board and node the author chose, or at the named board — at the named node, or the board’s own way in |
| Restart | begin again from the beginning, variables and all |
| Advance | move on from a step the player has read |
| Choose | the one to prefer — resolves by the choice’s id, so a choice held across a re-draw still works |
| Choose By Id | refuses a port id by name |
| Choose At | positional, and it goes stale |
| Lapse | the countdown ran out and the player picked nothing |
| Back, Forward | |
| Stop | end it. Always works, including mid-command |
| Redraw | re-present because something it depended on resolved late |
| Set Language | |
| Next Line | a node’s next line, without moving the story — see node handlers |
| Save, Restore | see saving |
| Register Command, Register Async Command, Fire Command, Reread Command Arguments | see implementing commands |
| Get Variable, Set Variable, and the typed pairs | a variable as a story value, by its TaleShard.Variable.<Code> tag, or TaleShard.Variable.<Context>.<Code> for a scoped one |
| Get Entity, Find Entity, Get Entity Field Value, Set Entity Field Value, Get Entity Overlay | an entity by its TaleShard.Entity.<Code> tag, and the per-playthrough overlay over its fields |
| Use Node Handlers | install the per-type handlers — see node handlers |
Every verb answers true when it ran and false with a reason when it was refused, and a refusal is also reported on the diagnostics channel.
A choice that is on the step but cannot be taken is refused and nothing changes. Advance is ignored when the story is not presenting, and so is Choose when nothing is awaited — a player mashing Continue during a fade is normal, not an error.
Stop always settles: every in-flight command completion goes stale, so an abandoned fade cannot resume the next playthrough.
Redraw re-traverses nothing and re-runs no script, so it cannot fire a command twice or re-count a visit.
Play Story And Wait For End
An async action for the graph that wants to run an intro to its end and then carry on. It plays the session — on a board and node when given, else where the author chose — and fires On Ended when the playthrough it began is over: by reaching the end, by Stop, by an engine error, or by a Back out of the opening moment. On Superseded fires instead when another playthrough began under it, the session was released, or the story could not begin.
It does not hand out steps. Bind On Step Presented for those.
How a playthrough ended
The end struct has a Reason and four booleans. Prefer the booleans to a string comparison.
| Reason | Boolean | Meaning |
|---|---|---|
end-of-path | Reached The End | the story ran out of story |
stopped | Was Stopped | somebody called Stop |
error | Failed | the engine could not carry on — see Error |
rewound | Was Rewound | the player rewound past the beginning |
Failed is not the same as an On Error Raised, after which the story continues.
Was Rewound is not a failure at all: the variables the story opened with are restored, the engine is idle, and Forward takes it back in.
Declaring what your host draws
A TaleShard Player Policy asset tells the engine which node types and fields your host never shows — and it matters more than it looks. Create one from the Content Browser as a Data Asset and assign it to the component.
| Property | Declares |
|---|---|
| Silent Node Types | node types whose nodes run without presenting a step. Wins over Always Present Node Types |
| Always Present Node Types | node types whose nodes always present a step, even with nothing to show — a node drawn as a beat |
| Silent Fields | individual fields, each as its node type and the field’s code — never its key, because a repeated field’s key embeds an instance id that exists only inside one node’s own data |
| Board Entries | what happens when a path ends and the board has other ways in |
Silent Fields silences presentation, never content: the field still reaches you in Get Fields and is only absent from Get Presented. It does not touch a choice’s label.
An asset is shared by every actor that references it, so it cannot be a policy — it builds one, and each session gets its own, unfrozen until that session applies it. A policy naming a node type or a field the project does not have is an inert mistake, reported on the diagnostics channel rather than refused.
Board Entries
| Value | Meaning |
|---|---|
| End The Path | the default. A path that ends, ends |
| Offer Ways In | when a path ends with no call frame waiting, offer the board’s remaining ways in as choices on the final step |
End The Path is what a game whose entry nodes are world triggers needs — entered by walking into a zone or clicking an NPC — since offering the other entries would end every scene in a menu the player cannot leave.
With Offer Ways In, those choices arrive with the Board Entry choice kind, and a board that has
ways in never produces a step flagged Is Terminal.
The component
The TaleShard Player component appears in the Add Component menu under TaleShard.
| Member | Notes |
|---|---|
| five of the six events | re-raised from the session, bindable before a story exists. On Command is not among them: an unregistered command reaches the command handler’s own On Command |
| Get Session | the session it holds, or null |
| Require Session | the session, with a Valid and an Invalid exec pin |
| Create | build a session here over a payload |
| Adopt | hold a session built elsewhere. With Owned off, the caller keeps the release duty |
| Release | drop the session. Called when the actor ends play; safe to call twice |
| Save Story to Slot, Load Story from Slot | Save to a save slot, and Restore from one, in one node each — see saving |
| Follow Game Language | on by default: with no Start Language set, the story plays in the game’s current language and follows it when it changes — see starting a session |
What to release
| Release | ends the session’s hold on its story. It does not stop the story — call Stop first if ending it is what you mean. Every verb is refused afterwards |
| Your own bindings | Release detaches the session from the story; it does not clear what you bound. A presenter outliving its binding unbinds itself |
| Media | held by whatever holds the asset — see loading media |
| The subsystem’s sessions | kept alive until End Session, or until the game instance ends |