Practical guide

Create a movable information panel

Declare a panel contribution, query detached data, and compose a semantic movable panel without owning gameplay state.

Procedure

  1. Add an extend contribution targeting ui.surface.player-hud/panels to the package manifest.
  2. Implement the declared callback and request only the bounded detached records it needs through world.query.
  3. Open one panel with a package-stable ID, anchored inset geometry, movable enabled, and explicit semantic label and role.
  4. Append rows, progress indicators, text, and tooltips, then balance the block with ui.end_panel.
  5. Validate the package, reload at a frame boundary, and inspect package diagnostics if the prior graph remains active.

Example

function compose_resource_counts()
    local result = world.query("world.resource.counts", {page_size = 16})
    assert(result.status == "completed", result.detail)
    ui.begin_panel({
        id = "addon.resource-counts",
        title = "Resources",
        anchor = "bottom-left",
        x = 24, y = 24, width = 280, height = 180,
        movable = true,
        semantic_label = "Current settlement resources",
        semantic_role = "status"
    })
    for _, record in ipairs(result.records) do
        ui.row(record.key, tostring(record.total))
    end
    ui.end_panel()
end

Constraints and recovery

Related symbols

Project references