Displaying a background: the three-block chain
🖼️ Displaying a background: the three-block chain
A full-screen background is never placed with a single block. It takes three, chained together: one that fetches the image, one that prepares how it should fit the screen, and only one that actually threads into the story's flow. The first two are value blocks: they plug into an input, they never sit between two other blocks in the flow. The third is a flow block: it, and only it, takes a place in the sequence, right before the line it's meant to dress.
🧩 The diagram
Load image ──image──▶ Background image ──background image──▶ Background
(imageFromUrl) (createBackgroundImage) (switchBackground)
url: Text image: Image in: Stream ◀── threads in here
image: Image (output) size: cover (default) background: Background image
color, repeat, duration, in effect,
x position, y position out effect,
background image: output text, text position
value block value block out: Stream
no in/out stream points no in/out stream points flow block
Only Background has "in" and "out" points of type Stream: it's the only one of the three that occupies a slot in the graph's sequence. Load image and Background image have neither — there's no way to thread them into the flow even if you wanted to; they only have value points to wire up.
🔗 Block by block
Load image (imageFromUrl)
- Input: url (Text) — the direct link to the file (
https://…). - Output: image (Image).
- No stream point: this block only converts a URL into an "Image" value, usable by any block that accepts an image (Background image, but also Edit character for a portrait).
Background image (createBackgroundImage)
- Input image (Image) — receives the previous block's output.
- Input size — a choice among contain, auto, cover (the block's default value).
- Inputs color, repeat, x position, y position — for cases where the image doesn't fill the whole frame.
- Output: background image — a "Background image" object, not a raw image. It's this specific type that the Background block expects.
- No stream point either: this block only assembles a setting, it doesn't display anything by itself.
Background (switchBackground)
- Input in (Stream) — this is where the block threads in, before the line it should dress.
- Input background — receives the background image output from the previous block. It's the only point that accepts the full "Background image" type (color, repeat and position included); wiring a plain Image directly into it, skipping Background image, runs into the same problem as the legacy Stage block covered in Legacy blocks: the expected fields (size, color, repeat) are missing, and the render stays blank or inconsistent.
- Inputs duration, in effect, out effect, text, text position — the transition animation and an optional text overlay.
- Output out (Stream) — the rest of the flow.
📐 "Cover" doesn't stretch what you'd expect
The cover setting on the Background image block doesn't produce a standard background-size: cover — the kind that fills the whole frame, cropping whatever overflows. What it produces, checked directly in the player's code, is background-size: 100% auto:
- the image's width is always locked to the frame's width;
- the height then follows, proportionally to that width, based on the image's own aspect ratio — with no distortion of the image itself.
So the result depends on your image's proportions relative to the frame:
- an image wider than it is tall, in a frame taller than it is wide (a phone screen), leaves the background color showing above and below;
- an image taller than it is wide, in a wide frame, overflows the frame vertically — the excess is simply clipped, not resized.
So there's no stretching of the image in the strict sense (no distortion), but the frame isn't necessarily covered either. If you need an actual edge-to-edge crop, a CSS block setting background-size: cover !important on the background remains, as of now, the only way — see Formatting without writing CSS to check whether a native module setting already does the job before reaching for that.
🌐 An image from an external URL: what actually happens
Nothing gets uploaded into the project: the Load image block simply wraps the URL you typed into an "Image" value. None of the three blocks in the chain waits, before moving on, for the image to actually finish loading — unlike the Play music block, which does block the flow until the sound has started. In practice:
- the flow continues immediately; the image loads in the background like any web page image;
- if the URL is unreachable, malformed, or refused by the remote site (anti-hotlinking protection, CORS), the background simply doesn't appear — the background falls back to the color set in Background image, with no error and no blocking;
- nothing warns you of this failure during testing: the only way to see it is to open Test play and actually look at the background, not just the validator.
So pick stable URLs (Wikimedia Commons, for instance, serves direct URLs designed for external use) rather than a link copied from a site that might one day start blocking requests coming from anywhere but itself.
→ Next step: if a background already wired through this chain still stays invisible, re-read Legacy blocks — you may have placed Stage instead of Background.
Updated on: 21/09/2026
Thank you!
