FolioTier 3
locations
Navigable named places. Imported from Ren'Py screen blocks; author scripts navigate them with `goto` and pop with `return-to-map`.
What Locations does
A location is a named place with art, optional time-of-day variants, and optional clickable hotspots over the art. Together the locations in a project form a navigable world — the surface Tier 3+ Ren'Py games approximate by writing custom screen-language map screens.
Two facts to internalize before writing anything:
- Locations are declared by the importer, not by author scripts.
When you upload a Ren'Py project, every location screen the
importer recognizes lands as an entry in
canonicalProject.subsystems.locations. Your scenes navigate between them viagotoandreturn-to-map; they don't create locations. - Hotspots are a sub-shape inside Locations, not a parallel
subsystem. Schema slot:
CanonicalLocation.hotspots. Per G6.5.
The Studio's Locations + Time rail (Script tab) lists every declared
location and every goto <name> site in the open buffer — that's
your authoring surface, not a hand-written location: block.
The two hotspot positioning shapes
The schema carries both forms because the corpus uses both. The audit doc has the full reasoning.
| Form | Source pattern | Hit-test |
|---|---|---|
| Alignment-anchored | Ren'Py imagebutton with xalign / yalign — Eternum's house style (88 sites) | Anchor at (canvasW × xalign, canvasH × yalign), dimension from the idle PNG's natural size. |
| Pixel rectangle | Ren'Py imagemap hotspot (x, y, w, h) calls — STS / MilfyCity's house style | Direct screen-coordinate rectangle. |
Both forms carry width / height. The runtime always computes an
absolute hit area; the form distinction matters at authoring time +
for re-export, not at hit-test time.
Hover affordance — both shapes ship
| Shape | When it applies |
|---|---|
| Explicit hover swap — hoverAssetId is set | Eternum's house style. The renderer swaps idle → hover on pointer-enter. |
| Default-glow filter — idleAssetId is set, hoverAssetId is null | STS / MilfyCity's house style. The renderer applies a theme-skinnable filter on hover (no second PNG). |
G6.5 decided this. The importer collapses imagebutton idle X hover HoverImage(X) (same PNG, filtered) to hoverAssetId: null; different
hover args land both ids.
Navigation verbs
| Verb | Page |
|---|---|
| goto <name> | /docs/folio/goto |
| return-to-map | /docs/folio/return-to-map |
Hotspot action shapes (importer output)
Ren'Py imagebutton actions reduce to four shapes in the canonical hotspot's action chain:
| Ren'Py source | Canonical |
|---|---|
| action Jump('label') | { kind: "jump-label", targetSceneId: "label" } |
| action [Play("sound", "x"), Jump('label')] | [{ play-sound }, { jump-label }] (source order) |
| action ShowMenu('point') | Manual lane — sub-menu pattern out of v1 |
| hovered [Play("sound", "x")] | hoverSoundAssetId set on the hotspot |
Importer translation — Eternum's shape (Tier 3 ship target)
screen hallways:
imagebutton:
idle "hallway1"
hover "hallway1b"
xalign 0.26
yalign 0.38
action Jump('corridorl')
Lowers to a CanonicalHotspot with:
position: { kind: "align", xalign: 0.26, yalign: 0.38, width, height }idleAssetId,hoverAssetIdresolved againstcanonicalProject.assetsactions: [{ kind: "jump-label", targetSceneId: "corridorl" }]
The screen-to-label binding (call screen <name> from a label
body) becomes a CanonicalLocation keyed on the screen name.
See also
goto— navigate to a declared locationreturn-to-map— pop the location stacktime— paired subsystem;time.periodgates andat periodart variantsstats— sister subsystem; both ship as typed engine slots