> For the complete documentation index, see [llms.txt](https://docs.autowall.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.autowall.fun/documentation/vars/events.md).

# Events

## <i class="fa-webhook">:webhook:</i> Events

### Core events

```lua
events.update:set(function() ... end)   -- once per frame, before render
events.render:set(function() ... end)   -- once per frame, drawing pass
on_shutdown(function() ... end)          -- once, when the script is Stopped
```

{% hint style="info" %}
`events.render`/`events.update` are plain tables with a `:set(fn)` method — calling `:set` again **replaces** the previous handler, it does not add a second one. There is no `events.render:remove()` — set a no-op function instead if you need to disable it temporarily, or gate on a `ui.switch`.
{% endhint %}

### Execution model

* Both events run inside a protected call. A Lua error inside either one is caught, recorded to `c_lua_manager::m_last_error` (shown in the Lua tab), and does **not** stop the script — it'll be called again next frame.
* `events.render` specifically runs while a full-screen transparent ImGui window is the active window, so `render.*` calls draw into it — see Render.
* There is no event ordering guarantee between *different* scripts, but within one script it's always `update` then `render`, every frame, in that order.

### Error handling

```lua
events.render:set(function()
    local ok, err = pcall(function()
        -- code that might throw
    end)
    if not ok then
        print_error(err)
    end
end)
```

You don't strictly need the inner `pcall` — an uncaught error inside `events.render` is still caught at the dispatch level — but wrapping risky sub-sections lets the rest of your render function keep running even if one part fails.

### Patterns

{% tabs %}
{% tab title="Gate on a switch" %}

```lua
local enabled = ui.switch("Lua", "myscript", "general", "enabled", true)

events.render:set(function()
    if not enabled:get() then return end
    -- ...
end)
```

{% endtab %}

{% tab title="Cache in update, draw in render" %}

```lua
local cache = { }

events.update:set(function()
    cache.players = entity.get_players()
end)

events.render:set(function()
    for _, p in ipairs(cache.players or {}) do
        -- draw using cached data, don't re-fetch every frame
    end
end)
```

{% endtab %}

{% tab title="Cleanup on unload" %}

```lua
on_shutdown(function()
    print("goodbye")
end)
```

`on_shutdown` fires exactly once, right before the script's Lua state is closed (pressing **Stop**, or **Start** again on an already-running script, which stops the old instance first).
{% endtab %}
{% endtabs %}


---

# 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.autowall.fun/documentation/vars/events.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.
