---
title: "loadingScreen"
description: "The screen players see while your world loads, as an asset: a <name>.loadingScreen/ folder whose screen.yaml states the title, a line of text or rotating tips…"
section: "Types"
slug: "types-loadingscreen"
canonical: "https://origozero.ai/docs/types-loadingscreen"
updated: "2026-10-10T16:24:25.481866972+00:00"
tags: ["asset-type", "reference"]
---

# loadingScreen

## Make one and show it

```luau
local screen = asset.create("loadingScreen", "title", { folder = "branding" })   -- /zero/source/branding/title.loadingScreen/
vfs.write(screen.path .. "/screen.yaml", [[
title: "Skyward"
text: "The islands are waking up"
tips:
  - "Hold Shift to sprint."
  - "Wind currents carry you further."
background: background.png
logo: logo.png
colors:
  background: "#0b1626"
  accent: "#7ad3ff"
  text: "#f2f7ff"
progress: bar
]])
world.loading_screen = screen        -- writes [world] loading_screen = "branding.title"
```

Put the pictures in the folder (`upload_file`, `vfs.write`, or a generated
image saved there), then push the world (`zm add . && zm commit -m '...' &&
zm push`). The screen is part of the world's content: it is versioned and
published with it like everything else, and an unset `world.loading_screen`
(`world.loading_screen = nil`) brings back the engine's own loading screen.

`.world_settings` holds the choice as an asset identity:

```toml
[world]
loading_screen = "branding.title"
```

## `screen.yaml`

Every key is optional. A key left out keeps the engine's own loading screen
look: the origozero.ai palette, the world's cover picture as a card, its title,
and a progress bar with the percentage under it.

| Key | Type | What it states |
|---|---|---|
| `title` | text | Drawn large in the middle. The world's title when left out. |
| `text` | text | One line under the title. |
| `tips` | list of text | Lines shown one at a time under the text, each for `tipSeconds`. A single text counts as a list of one. |
| `tipSeconds` | number | Seconds each tip stays up (default 6). |
| `background` | picture | Fills the whole window behind everything, cropped to cover it. |
| `logo` | picture | Drawn above the title, 96 pixels tall. |
| `cover` | true / false | Whether the world's cover picture shows as a card above the title (default true). |
| `status` | true / false | Whether the line naming the step the load is at shows (default true). |
| `progress` | `bar` / `percent` / `none` | A bar with the percentage under it (the default), the percentage alone, or no progress. |
| `colors` | mapping | `background` (the window), `accent` (the status line and the bar), `text` (title and text), `muted` (tips and the percentage), `track` (the bar's empty part). Each is `#rgb`, `#rrggbb` or `#rrggbbaa`. |

A picture is a file name inside the screen's folder (`background.png`) or a
path from the world's source root (`/source/art/key.png`). PNG and JPEG both
work. A key the type does not take, a colour that is not a colour and a value
of the wrong kind are each named in `ref:spec().problems` and in the
Inspector, and the screen keeps the default for that key.

## When it shows

The engine shows the screen from the moment it knows which world it is
loading, before the world's content has synced: it reads the world's
published `.world_settings`, `screen.yaml` and pictures from ZeroMind first,
which is what a player opening the world sees. A player sees the screen the
world's latest push states, so a change to it reaches players with the next
`zm push`, and a world that has pushed nothing yet shows its screen once its
own content is in place. Once the world's own content is in place, the screen
is read again from it, so an editor sees the screen their working copy states.

The screen stays up until the window shows the world's first frame, so the
handover from the screen to the world shows no black frame. The world's first
frame follows the world's `onWorldLoad` returning: work that runs for the
whole session goes in a component, a service or a `task.spawn` that
`onWorldLoad` starts, and an `onWorldLoad` that keeps running holds the
screen up for as long as it runs.

A world that names no loading screen, or names one whose `screen.yaml` is
missing, shows the engine's own loading screen.

## See it

`screen:preview(seconds)` draws the screen over the whole window exactly as a
boot of the world draws it, for `seconds` (default 15): the progress fills and
the tips change on the screen's own clock. Capture it while it is up:

```luau
world.loading_screen:preview(20)    -- then: capture { source = "window" }
world.loading_screen:preview(0)     -- takes it down early
```

## From a script

```luau
local read = world.loading_screen:spec()   -- { spec, problems }
print(read.spec.title, read.spec.progress, #read.problems)
print(world.loading_screen:isShown())       -- true: the world names it
```

## In the Inspector

Loading screen: the title, text, number of tips, pictures, whether the cover
card and the status line show, how progress is drawn and the colours, whether
the world shows this screen while it loads, every problem that kept a key out,
**Preview**, which draws the screen over the window for 15 seconds as a boot
does, and **Show while the world loads**, which names this screen in the
world's settings.
