Loading media
The media index, the resolved address and the Load Media action — how a reference becomes an asset, and who holds it afterwards.
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
A step hands you a media reference: an id, possibly a URL, and possibly a focal point (Focal, with Has Focal — where the picture’s face is, for a widget that crops; see Reading a step). Turning that into a texture or a sound goes through two things: an address that has been resolved through the project’s media index, and the Load Media action that loads what the address names.
The shape of it
media reference → Resolve Media Ref → media address → Load Media → asset ↑ the media indexNothing here is a raw string. A reference goes through the index or it does not load, which is what keeps a mistyped id a reported miss rather than a blank.
The media index
TaleShardMediaIndex is a primary data asset the sync writes after each media import: where every
synced file landed, looked up by the media’s id or by its code. Every entry is a soft
reference, so loading the index loads no texture and no sound — a consumer resolves the one it
needs.
| Read | What it gives |
|---|---|
| Find By Id | the asset for a media id, or a null soft pointer when that id was never imported. Resolves through both the item’s id and its storage id, because a stored reference may hold either |
| Find By Code | the asset for a media code, or null when no imported media carries it. A media entry with no code is present by id only |
Never edit the index by hand; the next sync overwrites it. Assign it wherever your game needs media — a widget, a subsystem of your own — and hand it to the library’s resolve functions.
The media address
TaleShardMediaAddress is a media reference that has been through the index. Resolution happens
once, when the address is made; afterwards it either carries a path or says why it does not.
Getting one
The TaleShard Media function library:
| Function | Use it for |
|---|---|
| Resolve Media Ref | the ordinary path — what a step’s fields, audio and cast all carry |
| Resolve Media | an id or a code, whichever you have. Ids are tried first — an id is what a stored reference holds, a code is what a human types |
| Resolve Media By Tag | a TaleShard.Media.<Code> tag, from the tag picker |
| Raw Media Address | an address you assert — a soft object path to your own asset, passed through verbatim |
Reading one
| Pin | Notes |
|---|---|
| Requested | what the caller asked for, in the author’s own words. Kept even when resolution failed — it is the only thing a diagnostic can name |
| Path | the address: the imported asset, as a soft object path. Empty when unresolved |
| Is Asserted | did you assert this, rather than the index deriving it |
| Unresolved Reason | why there is no path, or empty when there is one |
Is Media Resolved answers whether an address carries a path. Media Address To String reads as the address when resolved and as the failure when not, so an address printed into a log line can never look like a working one. Describe Media says what a load would do with it.
Two addresses are equal — Media Addresses Equal — when they resolve to the same path, not when they were asked for the same way: an id and a code naming one file are one picture. Is Asserted is not part of identity.
Load Media
An async action: give it an address, and it fires On Loaded with the asset or On Failed with the reason, on the game thread. An unresolved address fails at once with its own reason, so a missing picture names itself rather than arriving as a blank.
The load holds the asset for as long as the action is alive, which is until it has fired one of its pins. Keep your own reference to the asset if it must outlive that — a texture assigned to an image widget is held by the widget; one you only read from is not held by anything.
Cancel drops a load still in flight without firing either pin, and a load still in flight when the game instance ends is cancelled with it.
Planning what to load
What a thing needs, so you can preload it or report what is missing before a player sees a hole. All four take the media index and answer a list of addresses:
| Function | Returns |
|---|---|
| Portraits Plan | every entity’s portrait, across every definition in the project |
| Entity Media Plan | one entity’s portrait plus every media its fields hold |
| Step Media Plan | everything a step could draw or play: its fields, its choices’ content, its audio, and the portrait of everyone in its cast |
| Board Media Plan | everything a board could need before the player enters it — every reference on every node, the board’s voice-over clips in the one Language you pass it, plus the portraits of the entities those nodes point at |
An unresolved reference is kept rather than dropped — that is the point, if you are auditing. Duplicates collapse by address, so one portrait shared by four characters is one load. Step Media Plan reads the node’s fields rather than its presented ones, because a field with no text still carries a picture.
The picture for a character lives on the character rather than on the node that references it, which is why Board Media Plan walks the entities too: walking only the nodes’ own media would preload the backdrops and none of the faces.
Board Media Plan’s Language pin is there because a voice-over clip is per language and a board is planned before a session exists — pass the same language you will play in. Leave it empty for the master language’s clips, which is what an unlocalized build plays, and which is also what the project’s own code for that language plans. It never plans every language at once: that is a whole extra copy of the dialogue audio.