> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/ui/world-space-ui.md).

# World Space UI

World space UI is drawn in the 2D world instead of on the screen. Use it for nameplates, health bars, signs, and any text that should feel anchored to game objects.

{% hint style="info" %}
World space UI uses **meters** for sizing. If you use screen-style pixel sizes, your UI will be enormous.
{% endhint %}

### Core Rules

* For UI anchored to a moving entity, call `UI.begin_world_space_ui(entity)` and `defer UI.end_world_space_ui()` so render interpolation follows that entity.
* Use `UI.push_world_draw_context()` only for unanchored world drawing.
* Use meters for rect sizes and offsets.
* Push Z for proper depth sorting (commonly use `pos.y`).
* Use `subrect` only for percentage fills (like health bars).

### Examples

#### Displaying a player's level

```csl
draw_player_level :: proc(player: Player) {
    UI.begin_world_space_ui(player.entity);
    defer UI.end_world_space_ui();

    pos := player.entity.world_position;
    UI.push_z(pos.y);
    defer UI.pop_z();

    ts := UI.default_text_settings();
    ts.size = 0.30; // World space text size
    ts.halign = .CENTER;
    ts.valign = .CENTER;

    text_pos := pos + v2{0, 1.7};
    rect := Rect{text_pos, text_pos}.grow(0.05, 0.4, 0.05, 0.4);
    UI.text(rect, ts, "Lvl %", {player.level});
}
```

#### Player base signs

```csl
draw_base_sign :: proc(sign: Entity, label: string) {
    UI.begin_world_space_ui(sign);
    defer UI.end_world_space_ui();

    pos := sign.world_position;
    UI.push_z(pos.y);
    defer UI.pop_z();

    ts := UI.default_text_settings();
    ts.size = 0.30;
    ts.halign = .CENTER;
    ts.valign = .CENTER;

    text_pos := pos + v2{0, 2.2};
    rect := Rect{text_pos, text_pos}.grow(0.06, 0.8, 0.06, 0.8);

    // Optional dark backing for readability
    UI.quad(rect, core_globals.white_sprite, {0, 0, 0, 0.6});
    UI.text(rect, ts, label);
}
```

#### Health bars

```csl
// Note: health/max_health are user-defined fields on your own class, not built-in Entity fields.
draw_world_ui :: proc(entity: My_Entity) {
    UI.begin_world_space_ui(entity.entity);
    defer UI.end_world_space_ui();

    pos := entity.entity.world_position;
    UI.push_z(pos.y);
    defer UI.pop_z();

    bar_pos := pos + v2{0, 1.5};
    bar_rect := Rect{bar_pos, bar_pos}.grow(0.1, 0.5, 0.1, 0.5);

    UI.quad(bar_rect, core_globals.white_sprite, {0, 0, 0, 0.8});

    health_pct := entity.health / entity.max_health;
    fill_rect := bar_rect.inset(0.02).subrect(0, 0, health_pct, 1);
    fill_color := lerp(v4{1, 0, 0, 1}, {0, 1, 0, 1}, health_pct);
    UI.quad(fill_rect, core_globals.white_sprite, fill_color);
}
```

### Coordinate Conversion

```csl
// Convert world position to screen position
screen_pos := world_to_screen(entity.world_position);

// Convert screen position to world position
world_pos := screen_to_world(get_mouse_screen_position());
```

### Tips

* Keep world UI minimal and readable at distance. If you have a zoomable camera, make sure to adjust text size when you zoom out.
* Use `fit_aspect(texture.get_aspect())` if you draw icons in world space.
* If text flickers or overlaps, check your Z values and spacing.


---

# 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.allout.game/ui/world-space-ui.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.
