> For the complete documentation index, see [llms.txt](https://docs.xeutrino.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xeutrino.com/api-reference/imgui.md).

# ImGui rendering

Scripts can draw custom windows, widgets, and screen-space overlays through the `imgui` table.

## Threading (important)

All `imgui.*` functions must be called from inside a **draw callback** registered with `imgui.add_draw(fn)`. Calling them from your script's main loop will raise a Lua error.

```lua
imgui.add_draw(function()
    imgui.begin("My Overlay")
    imgui.text("Hello from Lua!")
    imgui.end()
end)
```

If a draw callback throws, it is unregistered automatically.

## Registration

### `imgui.add_draw(fn)`

Register `fn` to be called every frame. May be called from anywhere. Calling it again adds another callback. Use `imgui.clear_draw()` to stop.

### `imgui.clear_draw()`

Removes **all** draw callbacks registered by the current script.

Colours are given as four integers `(r, g, b, a)` in `0–255`; `a` defaults to `255` when omitted.

## Windows

| Function                                                      | Args                | Description                                                                              |
| ------------------------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------------- |
| `imgui.begin(name[, flags])`                                  | string, int         | Start a window. Returns `true` while open. Must call `imgui.end()` if it returns `true`. |
| `imgui.end()`                                                 | —                   | Close a window.                                                                          |
| `imgui.set_next_window_pos(x, y[, cond[, pivot_x, pivot_y]])` | floats, int, floats | Position the next window. `cond` from `imgui.cond`.                                      |
| `imgui.set_next_window_size(w, h[, cond])`                    | floats, int         | Size the next window.                                                                    |
| `imgui.set_cursor_pos(x, y)`                                  | floats              | Set the next item's screen-space position.                                               |
| `imgui.set_next_window_bg_alpha(a)`                           | float               | Background opacity `0.0`-`1.0` for the next window.                                      |

`flags` come from `imgui.flags` and combine with `+` (they are distinct bits), e.g. a click-through HUD panel:

```lua
imgui.begin("HUD", imgui.flags.no_decoration + imgui.flags.no_inputs)
```

## Text

| Function                              | Args         | Description                         |
| ------------------------------------- | ------------ | ----------------------------------- |
| `imgui.text(s)`                       | string       | Draw text at the cursor.            |
| `imgui.text_colored(r, g, b[, a], s)` | ints, string | Draw coloured text.                 |
| `imgui.text_wrapped(s)`               | string       | Text that wraps at the window edge. |
| `imgui.bullet_text(s)`                | string       | Bulleted line.                      |

## Widgets

| Function                                          | Args                  | Returns        | Description                                  |
| ------------------------------------------------- | --------------------- | -------------- | -------------------------------------------- |
| `imgui.button(label[, w, h])`                     | string, floats        | boolean        | Clickable button.                            |
| `imgui.checkbox(label, v)`                        | string, boolean       | changed, v     | Toggle; returns whether changed + new value. |
| `imgui.slider_float(label, v, min, max)`          | string, floats        | changed, v     | Draggable float slider.                      |
| `imgui.slider_int(label, v, min, max)`            | string, ints          | changed, v     | Draggable int slider.                        |
| `imgui.combo(label, current, items)`              | string, int, table    | changed, index | Dropdown; `items` is a Lua array of labels.  |
| `imgui.selectable(label, selected)`               | string, boolean       | clicked        | Selectable row, for lists.                   |
| `imgui.radio_button(label, active)`               | string, boolean       | clicked        | Radio button.                                |
| `imgui.input_text(label[, text[, maxlen]])`       | string, string, int   | text, changed  | Text field. Returns the new text.            |
| `imgui.progress_bar(fraction[, w, h[, overlay]])` | float, floats, string | —              | Progress bar, `fraction` is `0.0`-`1.0`.     |

## Containers

Scrollable regions and collapsible sections. Pair every `begin_*` with its `end_*`, and only call `imgui.tree_pop()` when `tree_node` returned `true`.

| Function                                           | Args                      | Returns | Description                                          |
| -------------------------------------------------- | ------------------------- | ------- | ---------------------------------------------------- |
| `imgui.begin_child(id[, w, h[, border[, flags]]])` | string, floats, bool, int | visible | Scrollable sub-region. Always pair with `end_child`. |
| `imgui.end_child()`                                | —                         | —       | Close a child region.                                |
| `imgui.collapsing_header(label[, flags])`          | string, int               | open    | Collapsible header; draw contents when `true`.       |
| `imgui.tree_node(label)`                           | string                    | open    | Tree node; call `tree_pop()` **only** when `true`.   |
| `imgui.tree_pop()`                                 | —                         | —       | Close an open tree node.                             |
| `imgui.indent([w])` / `imgui.unindent([w])`        | float                     | —       | Shift following items horizontally.                  |

```lua
if imgui.collapsing_header("Players") then
    imgui.begin_child("plist", 0, 120, true)
    for i = 0, 31 do
        if imgui.selectable("Player " .. i, i == sel) then sel = i end
    end
    imgui.end_child()
end
```

## Layout

| Function                                                                   | Args                         | Description                         |
| -------------------------------------------------------------------------- | ---------------------------- | ----------------------------------- |
| `imgui.same_line()`                                                        | —                            | Continue on the same line.          |
| `imgui.separator()`                                                        | —                            | Horizontal separator.               |
| `imgui.spacing()`                                                          | —                            | Vertical spacing.                   |
| `imgui.new_line()`                                                         | —                            | Move to a new line.                 |
| `imgui.dummy(w, h)`                                                        | floats                       | Invisible spacer.                   |
| `imgui.push_item_width(w)` / `imgui.pop_item_width([n])`                   | float / int                  | Scope the width of following items. |
| `imgui.push_style_color(col, r, g, b[, a])` / `imgui.pop_style_color([n])` | `imgui.col`, ints / int      | Push/pop a colour style.            |
| `imgui.push_style_var(var, v)` / `imgui.pop_style_var([n])`                | `imgui.style_var`, float/int | Push/pop a style variable.          |

## Queries

| Function                              | Returns     | Description                                              |
| ------------------------------------- | ----------- | -------------------------------------------------------- |
| `imgui.get_cursor_screen_pos()`       | x, y        | Current cursor position in screen pixels.                |
| `imgui.get_viewport_size()`           | w, h        | Main viewport size.                                      |
| `imgui.get_fps()`                     | number      | Current frame rate.                                      |
| `imgui.get_mouse_pos()`               | x, y        | Cursor position in screen pixels.                        |
| `imgui.get_time()`                    | number      | Seconds since ImGui started; handy for animation.        |
| `imgui.calc_text_size(s)`             | w, h        | Size the string would render at.                         |
| `imgui.is_item_hovered()`             | boolean     | Was the last item hovered?                               |
| `imgui.is_item_clicked()`             | boolean     | Was the last item clicked?                               |
| `imgui.is_item_active()`              | boolean     | Is the last item being interacted with?                  |
| `imgui.set_tooltip(s)`                | —           | Tooltip for the last item (pair with `is_item_hovered`). |
| `imgui.push_id(v)` / `imgui.pop_id()` | string\|int | Disambiguate widgets that share a label.                 |

`push_id` matters in loops — two buttons with the same label are the same widget to ImGui, so only the first responds:

```lua
for i = 1, 5 do
    imgui.push_id(i)
    if imgui.button("Delete") then remove(i) end
    imgui.pop_id()
end
```

## Screen-space primitives

These draw on top of the game and every ImGui window. Coordinates are screen pixels with origin at top-left of the viewport.

| Function                                                                | Args                 | Description               |
| ----------------------------------------------------------------------- | -------------------- | ------------------------- |
| `imgui.add_line(x1, y1, x2, y2, r, g, b[, a[, thickness]])`             | floats, ints         | Line segment.             |
| `imgui.add_rect(x1, y1, x2, y2, r, g, b[, a[, rounding[, thickness]]])` | floats, ints         | Rect outline.             |
| `imgui.add_rect_filled(x1, y1, x2, y2, r, g, b[, a[, rounding]])`       | floats, ints         | Filled rect.              |
| `imgui.add_circle(x, y, radius, r, g, b[, a[, segments[, thickness]]])` | floats, ints         | Circle outline.           |
| `imgui.add_circle_filled(x, y, radius, r, g, b[, a[, segments]])`       | floats, ints         | Filled circle.            |
| `imgui.add_text(x, y, r, g, b[, a], s)`                                 | floats, ints, string | Text at a fixed position. |
| `imgui.add_triangle_filled(x1, y1, x2, y2, x3, y3, r, g, b[, a])`       | floats, ints         | Filled triangle.          |
| `imgui.add_quad_filled(x1, y1, x2, y2, x3, y3, x4, y4, r, g, b[, a])`   | floats, ints         | Filled quad.              |

## Enum tables

| Table             | Purpose                                                                                                                                                                                                                                                                  |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `imgui.col`       | `ImGuiCol` values, e.g. `imgui.col.window_bg`, `imgui.col.text` — for `push_style_color`.                                                                                                                                                                                |
| `imgui.cond`      | `ImGuiCond` values: `always`, `once`, `first_use_ever`, `appearing` — for `set_next_window_*`.                                                                                                                                                                           |
| `imgui.style_var` | Float `ImGuiStyleVar` values, e.g. `window_rounding`, `frame_border_size` — for `push_style_var`.                                                                                                                                                                        |
| `imgui.flags`     | Window flags for `begin` / `begin_child`: `none`, `no_title_bar`, `no_resize`, `no_move`, `no_scrollbar`, `no_collapse`, `always_auto_resize`, `no_background`, `no_saved_settings`, `no_mouse_inputs`, `no_focus_on_appearing`, `no_nav`, `no_decoration`, `no_inputs`. |

## Full example

```lua
-- An FPS / position overlay
imgui.add_draw(function()
    local vw, vh = imgui.get_viewport_size()
    imgui.set_next_window_pos(20, 20, imgui.cond.always)
    imgui.set_next_window_size(260, 0)
    imgui.begin("Overlay", 0)
    imgui.push_style_color(imgui.col.text, 0, 255, 0)
    imgui.text(string.format("FPS: %.0f", imgui.get_fps()))
    imgui.pop_style_color()
    imgui.text(string.format("Viewport: %.0f x %.0f", vw, vh))
    if imgui.button("Close") then
        imgui.clear_draw()
    end
    imgui.end()

    -- Red dot at screen center
    imgui.add_circle_filled(vw / 2, vh / 2, 5, 255, 0, 0, 255)
end)
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.xeutrino.com/api-reference/imgui.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
