# Godot runtime

> Run Envy game UI in Godot 4.3+ with the EnvyUI node. Real Control nodes, data binding, events, animation, overlays, translations and hot reload while the game runs.

Source: https://envyui.com/docs/godot

The Godot runtime is an addon written in GDScript, so there's nothing to compile. The `EnvyUI` node reads a `.envy.json` document and builds real Control nodes from it: Panels, Containers, Labels and TextureRects. Focus, gamepad input and theming stay Godot's own.

Requires Godot 4.3 or newer. Importing `.envy.json` as a resource, and live reload through it, needs Godot 4.6 or newer; on older versions point `document_path` at the file instead.

## Install

1. Copy `addons/envy_ui` into your project (it's in every Godot package and AI handoff export) and enable **Envy UI** in Project Settings › Plugins.
2. Put your document in the project, for example `res://ui/my_ui.envy.json`. In Godot 4.6+ it's imported as an **EnvyDocument** resource.
3. Add an `EnvyUI` node and set its document, or create it from code.

```gdscript
var ui := EnvyUI.new()
ui.document_path = "res://ui/my_ui.envy.json"
add_child(ui)
ui.ui_event.connect(_on_ui_event)
ui.set_data("player.hp", 40)
ui.goto("HUD")
ui.play("LevelUp")
ui.focus_first_button()
```

## Live reload

In Godot 4.6+, with the document imported as a resource and `hot_reload` on, saving the document reloads it in the running game. Link the document to the file in the editor and every Ctrl S shows up in Godot while you play.

## Properties

| Property | Meaning |
|---|---|
| `document` | An EnvyDocument resource |
| `document_path` | Or a path to a `.envy.json` file |
| `start_screen` | Screen to show first (defaults to the first screen) |
| `scale_mode` | `FIT` scales the design resolution into the node and stretches to its aspect |
| `autoplay` | Play autoplay animations when a screen shows |
| `use_sample_data` | Start with the document's sample data |
| `hot_reload` | Reload when the document changes on disk |
| `locale` | Locale for translated text |
| `fonts` | Family name → Font, for fonts the document doesn't embed |
| `cancel_closes_overlay` | `ui_cancel` closes the top overlay |

## Methods

| Method | Does |
|---|---|
| `goto(screen, transition = {})` | Shows a screen by name or id |
| `push(screen, transition = {})`, `pop()` | Opens an overlay, closes the top one |
| `get_stack()`, `get_screen_names()` | The open screens, every screen |
| `set_data(path, value)`, `merge_data(patch)`, `get_data(path)` | Data |
| `play(anim)`, `stop(anim)`, `is_playing(anim)` | Animations |
| `set_locale(locale)`, `get_locales()` | Language |
| `get_control(name_or_id)` | The Control built for a layer |
| `focus_first_button()` | Starts keyboard and gamepad navigation |
| `load_document(path)`, `load_resource(res)` | Loads another document |

## Signals

| Signal | When |
|---|---|
| `ui_event(event, payload)` | A button emitted an event |
| `screen_changed(screen_name)` | goto, push or pop ran |
| `data_changed(data)` | A button set or toggled data |
| `document_reloaded` | The document changed on disk and was reloaded |

## Tests

The addon has a headless test suite: `godot --headless --path runtimes/godot -s res://tests/run_tests.gd`. See [known differences](/docs/differences) for where Godot and the web draw slightly differently.
