All pages

Windows and responsive layouts

window(player, spec) opens or replaces one window for that player.

window(player, spec) opens or replaces one window for that player. close(player) removes it. Welcome windows, HUDs and scoreboards are retained and replayed after scene entry or reconnect; scripts do not need an arrival-delay timer to display them.

Spec fields: id, title, text, skin, layout, items. id identifies the window in window_closed; it is optional, then nil. Window text preserves line breaks. A long window scrolls on small screens.

Item kindFields and interaction
buttonid, label; sends ui(player, id, nil)
cardid, label, image (room asset name/id), text, badge, accent (#rrggbb), disabled; illustrated action tile
inputid, label, placeholder; submits trimmed text, up to 40 characters
texttext; preserves paragraphs and newlines
friendsid, optional label; selects an online friend, sends their id as value
listrows = {{"name", "value"}, ...}; display only

Action ids must be present and unique in a window. Player actions are input to your rules: validate them against the current game state, including UI events that arrive after a different screen has opened.

Default windows fit phone and desktop screens. layout supports:

  • width: integer from 240 to 960, in layout pixels.
  • dock: center (default) or right. Right-docked flow windows have a draggable desktop header and a scrolling two-column phone panel above combat controls.
  • columns: 1 or 2 for buttons and cards. Text, lists and fields span all columns.
  • skin: auto, fit, or flow.
  • phone and desktop: tables overriding these same settings.

Phone layout is selected below 700 CSS pixels wide or 500 high. A small desktop window can use it too. Players interact with the creator's controls; they do not edit the creator's UI. Docked desktop windows can be moved by dragging their header.

skin at the spec's top level names a thing from the room, including stock. The window's artwork is that thing seen from straight above (its plan view, frame 0): voxel column x runs left to right and row y top to bottom, with the thing's +y side at the bottom. The window is as many voxels wide and high as the thing is in x and y, drawn at 3 screen pixels per voxel at scale 1 and shrunk to fit the screen. Paint a skin as a panel one voxel tall and colour its top. Items can use x, y, w, h in the skin's voxels (x = 4, y = 10 is 4 voxels from the left edge, 10 from the top), with item-level phone and desktop overrides.

layout.skin says what happens on a small screen: auto (the default) keeps the artwork while it can be drawn at least 0.65 of its size and switches to the plain flowing window below that; fit always keeps the artwork, however small; flow never uses it and lays the items out as a plain window. Use layout.phone.skin = "flow" to replace precise skin positioning with a scrolling phone layout. Start with flow layouts for dependable touch controls.

on("enter", function(p)
  window(p, {
    id = "signals", title = "SIGNALS",
    layout = {width = 600, columns = 2,
      phone = {width = 320, columns = 1, skin = "flow"}},
    items = {
      {kind = "text", text = "Watch the light.\nChoose its colour."},
      {kind = "button", id = "red", label = "RED"},
      {kind = "button", id = "blue", label = "BLUE"}
    }
  })
  every(1, "signals:" .. p.id)
end)

on("window_closed", function(p, id)
  if id == "signals" then stop_timer("signals:" .. p.id) end
end)

on("leave", function(p)
  stop_timer("signals:" .. p.id)
end)

The X reports window_closed once for the window the player actually dismissed. Calling close(player) from Lua does not emit it. Closing does not automatically cancel all of a game's timers: stop the relevant timer or mark the screen closed in your handler, so a subsequent timer does not reopen it.

Window validation refuses invalid fields with an actionable error, for example window.items[1].text allows at most 4096 characters. It does not silently shorten the window. Limits per spec:

FieldMaximum
title, item label, item placeholder, list cell80 characters
Top-level text, each text item's text4096 characters
Window id, item id64 characters
Items12
Rows per list, cells per row12 rows, 3 cells
Skin coordinatesWhole numbers from -4096 to 4096; width/height positive

This page as markdown, for you or your agent: /api/windows-and-responsive-layouts.md