# Realot Studio — complete documentation
Generated 2026-11-02 from the supplied Realot Studio engine source. 86 pages follow; each page is identified by its stable URL.
---
# Realot Studio documentation
> Source-aligned documentation for Realot Studio: editor workflows, scripting API, components, physics, navigation and export.
> **What is Realot Studio?:** A browser-based 2D game engine with a visual editor, JavaScript gameplay scripting, PixiJS rendering and Rapier2D physics. The hosted engine is updated by publishing its web files; users do not need a separate engine installer.
## Start here
### [Open Realot Studio](getting-started/installation.html)
Use the hosted editor or serve the static distribution yourself.
### [Build your first game](getting-started/first-game.html)
Entities, components and a first script in a few steps.
### [Scripting quickstart](getting-started/scripting.html)
onStart, onUpdate, `this` and the component modules.
### [Editor controls](editor/controls.html)
Exact menu paths, panels and keyboard shortcuts.
## Browse by topic
### [Get started](getting-started/installation.html)
Run the editor, build a first game and learn the scripting model.
5 pages
### [Concepts](concepts/architecture.html)
Architecture, the entity–component model, the game loop and coordinates.
4 pages
### [Editor](editor/overview.html)
Every panel, menu path, shortcut and authoring workflow.
13 pages
### [Scripting](scripting/lifecycle.html)
Lifecycle, globals, input, physics, navigation, saving and debugging.
18 pages
### [API reference](api/index.html)
Component fields, script members, option shapes and prerequisites.
6 pages
### [Export & deploy](export/index.html)
HTML5, installable PWA and Android APK builds.
4 pages
### [Reference](reference/tuning-guide.html)
Tuning rules, scene and project formats, live updates and source map.
8 pages
### [AI & machine access](reference/ai-bridge.html)
llms.txt, Markdown twins, JSON catalogs and guidance for assistants.
3 pages
## Component reference
25 components, each documented with serialized fields, defaults, script API and editor location.
[**Transform**Position, rotation and scale. Every spatial entity uses a Transform.](api/components/transform.html)[**SpriteRenderer**Draw a 2D texture sprite for an entity.](api/components/spriterenderer.html)[**ShapeRenderer**Draw a procedural 2D shape without requiring a sprite asset.](api/components/shaperenderer.html)[**TextRenderer**Render text either in world space or as screen-space UI.](api/components/textrenderer.html)[**StrokePath**A variable-thickness strip along placed points — rivers, cables, roads, conveyor belts or walls — with flat color or…](api/components/strokepath.html)[**SpeechBubble**Speech bubble UI attached to an entity, useful for dialogue and NPC callouts.](api/components/speechbubble.html)[**ChatLog**Scrollable-style conversation log component for UI dialogue.](api/components/chatlog.html)[**TextInput**Interactive text input control driven by the runtime UI system.](api/components/textinput.html)[**Joystick**Virtual touch joystick for mobile and pointer-driven control schemes.](api/components/joystick.html)[**Rigidbody2D**2D physics body backed by the engine physics runtime. Dynamic, Kinematic and Static bodies have different script…](api/components/rigidbody2d.html)[**Collider2D**Physics collision shape and contact filtering. A Collider2D is also required for accurate pointer/touch hit tests.](api/components/collider2d.html)[**Joint2D**Connect physics bodies with Fixed, Revolute, Prismatic, Rope or Spring constraints.](api/components/joint2d.html)[**CharacterController**High-level movement modes: Character Controller, Platformer, Top-Down, Car, Follow, Patrol and Free.](api/components/charactercontroller.html)[**SpriteAnimation**Sprite-sheet/clip animation state on a SpriteRenderer.](api/components/spriteanimation.html)[**Camera**Orthographic 2D camera with reference resolutions, responsive scaling, follow, shake and optional pseudo-3D sprite…](api/components/camera.html)[**AudioSource**Play a local audio asset, optionally with distance-based 3D attenuation.](api/components/audiosource.html)[**AudioListener**Defines the hearing area for 3D audio and drives audio enter/leave callbacks.](api/components/audiolistener.html)[**Light**2D light source supporting Directional, Point, Spot, Area, GodRays and Freeform light shapes.](api/components/light.html)[**ShadowCaster**Marks an entity as a shadow occluder for the lighting system.](api/components/shadowcaster.html)[**LightingSettings**Scene-wide lighting quality and mood controls. Attach to one entity; the lighting system reads it scene-wide.](api/components/lightingsettings.html)[**NavAgent2D**Per-agent navigation settings and current path state for NavWorld2D pathfinding.](api/components/navagent2d.html)[**NavWorld2D**Shared navigation world for baked or dynamic 2D pathfinding, with 16 navigation areas.](api/components/navworld2d.html)[**Tileset**Defines a reusable 16-role autotile set. The editor can auto-slice one image or accept separate role images.](api/components/tileset.html)[**Tilemap**Sparse painted tile grid that references a Tileset entity by ID.](api/components/tilemap.html)[**Script**Script component holding a script name, source and enabled state.](api/components/script.html)
## For automated systems
Every page is complete static HTML with a Markdown twin (same URL, `.md`). Machine entry points: [llms.txt](../llms.txt), [llms-full.txt](../llms-full.txt) (all documentation in one file), [search-index.json](../search-index.json), [api/index.json](../api/index.json), [sitemap.xml](../sitemap.xml) and [robots.txt](../robots.txt). See [AI & crawlers](reference/ai-crawling.html).
---
# Realot Studio documentation
> Source-aligned documentation for Realot Studio: editor workflows, scripting API, components, physics, navigation and export.
> **What is Realot Studio?:** A browser-based 2D game engine with a visual editor, JavaScript gameplay scripting, PixiJS rendering and Rapier2D physics. The hosted engine is updated by publishing its web files; users do not need a separate engine installer.
## Start here
### [Open Realot Studio](getting-started/installation.html)
Use the hosted editor or serve the static distribution yourself.
### [Build your first game](getting-started/first-game.html)
Entities, components and a first script in a few steps.
### [Scripting quickstart](getting-started/scripting.html)
onStart, onUpdate, `this` and the component modules.
### [Editor controls](editor/controls.html)
Exact menu paths, panels and keyboard shortcuts.
## Browse by topic
### [Get started](getting-started/installation.html)
Run the editor, build a first game and learn the scripting model.
5 pages
### [Concepts](concepts/architecture.html)
Architecture, the entity–component model, the game loop and coordinates.
4 pages
### [Editor](editor/overview.html)
Every panel, menu path, shortcut and authoring workflow.
13 pages
### [Scripting](scripting/lifecycle.html)
Lifecycle, globals, input, physics, navigation, saving and debugging.
18 pages
### [API reference](api/index.html)
Component fields, script members, option shapes and prerequisites.
6 pages
### [Export & deploy](export/index.html)
HTML5, installable PWA and Android APK builds.
4 pages
### [Reference](reference/tuning-guide.html)
Tuning rules, scene and project formats, live updates and source map.
8 pages
### [AI & machine access](reference/ai-bridge.html)
llms.txt, Markdown twins, JSON catalogs and guidance for assistants.
3 pages
## Component reference
25 components, each documented with serialized fields, defaults, script API and editor location.
[**Transform**Position, rotation and scale. Every spatial entity uses a Transform.](api/components/transform.html)[**SpriteRenderer**Draw a 2D texture sprite for an entity.](api/components/spriterenderer.html)[**ShapeRenderer**Draw a procedural 2D shape without requiring a sprite asset.](api/components/shaperenderer.html)[**TextRenderer**Render text either in world space or as screen-space UI.](api/components/textrenderer.html)[**StrokePath**A variable-thickness strip along placed points — rivers, cables, roads, conveyor belts or walls — with flat color or…](api/components/strokepath.html)[**SpeechBubble**Speech bubble UI attached to an entity, useful for dialogue and NPC callouts.](api/components/speechbubble.html)[**ChatLog**Scrollable-style conversation log component for UI dialogue.](api/components/chatlog.html)[**TextInput**Interactive text input control driven by the runtime UI system.](api/components/textinput.html)[**Joystick**Virtual touch joystick for mobile and pointer-driven control schemes.](api/components/joystick.html)[**Rigidbody2D**2D physics body backed by the engine physics runtime. Dynamic, Kinematic and Static bodies have different script…](api/components/rigidbody2d.html)[**Collider2D**Physics collision shape and contact filtering. A Collider2D is also required for accurate pointer/touch hit tests.](api/components/collider2d.html)[**Joint2D**Connect physics bodies with Fixed, Revolute, Prismatic, Rope or Spring constraints.](api/components/joint2d.html)[**CharacterController**High-level movement modes: Character Controller, Platformer, Top-Down, Car, Follow, Patrol and Free.](api/components/charactercontroller.html)[**SpriteAnimation**Sprite-sheet/clip animation state on a SpriteRenderer.](api/components/spriteanimation.html)[**Camera**Orthographic 2D camera with reference resolutions, responsive scaling, follow, shake and optional pseudo-3D sprite…](api/components/camera.html)[**AudioSource**Play a local audio asset, optionally with distance-based 3D attenuation.](api/components/audiosource.html)[**AudioListener**Defines the hearing area for 3D audio and drives audio enter/leave callbacks.](api/components/audiolistener.html)[**Light**2D light source supporting Directional, Point, Spot, Area, GodRays and Freeform light shapes.](api/components/light.html)[**ShadowCaster**Marks an entity as a shadow occluder for the lighting system.](api/components/shadowcaster.html)[**LightingSettings**Scene-wide lighting quality and mood controls. Attach to one entity; the lighting system reads it scene-wide.](api/components/lightingsettings.html)[**NavAgent2D**Per-agent navigation settings and current path state for NavWorld2D pathfinding.](api/components/navagent2d.html)[**NavWorld2D**Shared navigation world for baked or dynamic 2D pathfinding, with 16 navigation areas.](api/components/navworld2d.html)[**Tileset**Defines a reusable 16-role autotile set. The editor can auto-slice one image or accept separate role images.](api/components/tileset.html)[**Tilemap**Sparse painted tile grid that references a Tileset entity by ID.](api/components/tilemap.html)[**Script**Script component holding a script name, source and enabled state.](api/components/script.html)
## For automated systems
Every page is complete static HTML with a Markdown twin (same URL, `.md`). Machine entry points: [llms.txt](../llms.txt), [llms-full.txt](../llms-full.txt) (all documentation in one file), [search-index.json](../search-index.json), [api/index.json](../api/index.json), [sitemap.xml](../sitemap.xml) and [robots.txt](../robots.txt). See [AI & crawlers](reference/ai-crawling.html).
---
# Use Realot Studio
> Realot Studio is a browser-based engine. Open the hosted site; local hosting is optional.
## Normal use: open the website
> **No engine installer is required:** Realot Studio runs as a browser application. Open the hosted Realot site in a modern browser and use the Hub to create or open a project. The editor and runtime are delivered as web files; you do not need to download a separate engine installer to use the hosted version.
When the engine owner publishes an update to the hosted site, the new files are available from the same website address. A normal page reload while online retrieves the published files. A previously installed PWA can continue using cached assets offline until it reconnects and refreshes.
## Optional browser installation
On a supported browser and deployment, choose the Hub's **Install app** action or use the browser's own install option. This adds an app-like launcher entry. It is still the same web application and does not create a separate downloadable engine release.
## Optional: host the engine yourself
The supplied engine project is a static web application. To preview a local copy or publish your own deployment, serve the project folder over HTTP(S). For a quick local preview, run this command from the folder containing the engine files:
```
python3 -m http.server 5000
```
Then open `http://localhost:5000/`. Do not open the main HTML file directly with `file://`; browser module, fetch and WebAssembly loading require an HTTP origin.
## Browser requirements
- A modern browser with JavaScript modules and WebAssembly.
- Canvas/WebGL support for the renderer.
- Browser storage for project data and preferences.
- HTTPS for production deployments that need secure browser APIs or PWA installation (localhost is treated as secure for development).
## Android APK export
Android APK export is separate from normal browser use. Realot packages the game in the browser and sends the standalone web export to the configured Android build service. The editor does not run Android Studio, Gradle or an Android SDK locally. See [Android APK export](../export/android.html) for the current workflow.
---
# The Realot Hub
> Use Projects to create and reopen games, and Learn to open the built-in guide.
## Overview
The Hub is the Realot Studio home screen. It is the starting point for opening projects, creating a new game from a template, and opening the built-in learning material. The current Hub has two views: **Projects** and **Learn**.
| View | What it does |
| --- | --- |
| Projects | Shows your saved project cards. Start with a template, create a blank project, search/sort your projects, switch between grid and list layouts, or reopen a recent project. |
| Learn | Opens the Hub's learning area. The built-in quick guide is part of the engine distribution and can be cached for offline access. |
## Starter templates
The current template gallery includes:
| Template | Starting point |
| --- | --- |
| Blank Canvas | An empty project for custom 2D scenes and logic. |
| Platformer Kit | A platformer starter with a kinematic character controller and one-way platforms. |
| Top-Down | A top-down starter with a player, NPCs, collectibles and a dungeon scene. |
| Flappy Bird | A flap-to-fly starter with scoring and a simple game-state flow. |
| Sky Jumper | An endless jumping starter with platforms, stars and a following camera. |
| Physics Sandbox | A scene for experimenting with Rapier2D bodies, colliders and joints. |
## Install the Hub as an app
Realot is a web application. On browsers and deployments that support installation, the title bar can show an **Install app** action when the browser confirms the site is installable. Installation creates an app-like shortcut; it does not download a separate engine release. The service worker can cache the Hub, editor and runtime for supported offline use.
Updates are published to the hosted site. When the browser is online, reload the site to receive the current published files. An installed PWA may continue using cached files while offline and will need to reconnect to refresh them.
## Project files
**File → Save Project** downloads your project as a `.realot` file. This is Realot Studio's portable project format and includes the scenes, assets, prefabs, tags, navigation-area names and scripts needed to continue editing the game.
**Open a project from your computer:** install Realot Hub as a PWA in a supported desktop browser. Then double-click a downloaded `.realot` file in your file manager. The operating system opens the installed Realot app, and Realot loads that project in the editor. When asked, you can allow Realot to keep saving changes back to that same file. This file-opening behavior requires an installed PWA and browser/operating-system support for web-app file handling; if that option is unavailable, open the editor and use **File → Load Project**.
---
# Build your first game
> A practical first-game path using entities, components and a simple script.
## 1. Start with a scene
Create a scene and add an entity. The editor stores scene state as JSON-compatible data: entities have IDs, names, tags, active state, optional hierarchy folders/prefab metadata, and a component map.
## 2. Add a visual
Attach a `SpriteRenderer` and assign a sprite asset, or use a `ShapeRenderer` when you want a procedural primitive. Add a `Camera` and mark one camera as the main camera.
## 3. Add physics when you need it
A typical physics actor uses a `Rigidbody2D` plus a `Collider2D`. Choose Dynamic, Kinematic or Static based on who is responsible for movement.
## 4. Add a Script component
Put a script on the entity and define lifecycle functions. Realot Studio calls `onStart()` once and `onUpdate(dt)` every render frame.
```
function onStart() {
this.speed = 220;
}
function onUpdate(dt) {
if (input.keyDown("ArrowRight")) {
this.x += this.speed * dt;
}
if (input.keyDown("ArrowLeft")) {
this.x -= this.speed * dt;
}
}
```
## 5. Prefer frame-rate-independent movement
Use `time.deltaTime` (or the `dt` lifecycle argument) when movement is expressed in units per second. Keep physics-step work in `onFixedUpdate(dt)` when the logic should track the fixed simulation cadence.
## 6. Run, iterate, export
Use the editor’s Play flow to test, inspect the Debug HUD when diagnosing runtime behavior, then use **Export** for HTML5, PWA or Android APK.
---
# Scripting quickstart
> Learn the Realot Studio JavaScript scripting model in one page.
## Script shape
Realot Studio scripts are plain JavaScript functions executed by the ScriptSystem. You do not create a class instance yourself. The engine binds the entity context to `this`.
```
function onStart() {
this.health = 100;
}
function onUpdate(dt) {
this.x += 100 * dt;
}
```
## The two layers of the API
| Layer | Examples | Use when |
| --- | --- | --- |
| Entity context (`this`) | `this.x`, `this.sprite`, `this.rigidbody`, `this.destroy()` | You are acting on the current entity. |
| Globals | `findFirst()`, `scene.load()`, `physics.raycast()`, `input.keyDown()` | You need scene-wide services or another entity. |
## Common component shortcuts
When a component exists on the entity, the corresponding module is exposed on `this`: `this.sprite`, `this.shape`, `this.text`, `this.rigidbody`, `this.controller`, `this.animator`, `this.camera`, `this.audio`, `this.collider`, `this.joint`, `this.navAgent`, `this.light`, `this.shadowCaster`, `this.strokePath`, and more.
## Discoverability
The editor’s script autocomplete is sourced from the same public API lists documented here. A good rule for generated code is: use documented globals and component modules; do not reach into internal runtime systems or editor modules.
---
# Architecture
> How Realot Studio separates runtime, editor, standalone runtime, components and systems.
## Runtime / editor / target
The distribution follows a hard separation: `project/runtime/` is the engine shipped with games; `project/editor/` is the development tool; `project/player/` is the standalone runtime shell. Runtime must not import editor code; editor may import runtime code.
## Components are data
Components are plain data objects. Rendering, physics, lighting, audio and other behavior live in systems. This keeps scene serialization straightforward and makes the same scene data usable by the editor and standalone runtime.
## Systems run in an explicit order
| Order | System |
| --- | --- |
| 1 | ControllerSystem |
| 2 | PhysicsSystem |
| 3 | AnimationSystem |
| 4 | SpeechBubbleSystem |
| 5 | TextInputSystem |
| 6 | JoystickSystem |
| 7 | AudioSystem |
| 8 | AudioListenerSystem |
| 9 | ScriptSystem |
| 10 | Late controller work |
| 11 | RenderSystem |
| 12 | TilemapSystem |
| 13 | NavWorldSystem |
| 14 | LightingSystem |
| 15 | CameraRenderSystem |
## Rendering containers
The runtime separates game-content rendering, screen-space UI and late letterbox/pillarbox bars. Debug lines render in the world container. This separation explains why screen-space UI components such as TextRenderer can remain fixed while the world camera moves.
---
# Entities & components
> Understand Realot Studio scene entities, IDs, tags, component composition and runtime cloning.
## Entity identity
An entity has a unique stable ID such as `e12`, a human-facing name, a tag, active state, optional hierarchy folder, prefab metadata and a component map. Names and tags are not unique; IDs are.
## Why IDs matter
Use `findById(id)` when you mean one exact entity. Use name/tag queries when you intentionally want one or many matches. Runtime clones keep unique IDs and expose `isClone`.
## Component composition
A gameplay actor can combine Transform + SpriteRenderer + Collider2D + Rigidbody2D + Script. A UI button might combine Transform + TextRenderer + Collider2D + Script. There is no requirement that every entity have every component.
## Runtime cloning
Use `spawn()` or `this.spawn()` to clone an authored entity. The returned context is the new live entity; `onClone()` runs for runtime clones before `onStart()`.
```
function onUpdate() {
if (input.keyPressed("Space")) {
var bullet = spawn("Bullet", { x: this.x, y: this.y });
bullet.rotation = this.rotation; // configure the clone right after spawning
}
}
// Inside Bullet’s own script:
function onClone() {
this.tag = "projectile"; // runs once, before this clone’s onStart()
}
```
## Destroying entities
`this.destroy()` queues destruction for the end of the frame. `onDestroy()` runs before removal. Waiting/repeating timers owned by the entity are automatically cancelled when the entity is destroyed.
---
# Game loop & scenes
> Understand frame updates, fixed physics updates and scene transitions.
## Render-frame lifecycle
| Hook | When it runs |
| --- | --- |
| onStart() | Once before the first onUpdate(). |
| onClone() | Once for runtime clones, immediately before onStart(). |
| onUpdate(dt) | Every render frame. |
| onClick() | On the frame a mouse/finger press targets an entity with a collider. |
| onFixedUpdate(dt) | Fixed 60 Hz simulation cadence. |
| onDestroy() | Before the entity is removed or the scene ends. |
## Collision & trigger lifecycle
Use `onCollisionEnter(other)`, `onCollisionStay(other)` and `onCollisionExit(other)` for physical contacts. `onCollision(other)` remains an alias for collision-enter behavior. Trigger-only callbacks are `onTriggerEnter(other)` and `onTriggerExit(other)`.
## Scene controls
Use `scene.current` to read the current scene name, `scene.load(name)` to switch scenes, `scene.restart()` to restart, and `scene.pause()`/`scene.resume()` to freeze gameplay while leaving rendering responsive.
```
function onTriggerEnter(other) {
if (other.name === "Target") scene.load("Level2");
}
function onUpdate() {
if (input.keyPressed("Escape")) {
scene.isPaused ? scene.resume() : scene.pause();
}
}
```
## Pause semantics
During `scene.pause()`, physics, scripts, animation and audio stop advancing until resume. Rendering stays responsive, which is useful for pause menus and debugging UI.
---
# Coordinate system & conventions
> The signs, units, axes, rotation conventions and reference-resolution rules that prevent common Realot Studio scripting mistakes.
> **Core convention:** Realot Studio is a 2D screen-style coordinate system: +X is right and +Y is down. Treat Y signs accordingly when writing movement, offsets, camera/UI positioning, and physics examples.
## Transform axes
| Value | Positive direction | Common use |
| --- | --- | --- |
| `x` | Right | Horizontal world movement and placement. |
| `y` | Down | Vertical placement; jumping/falling code should use negative/positive signs according to the movement system being used. |
| `z` | Depth layer / pseudo-3D input | Affects pseudo-3D rendering only when the camera’s pseudo-3D behavior is enabled. |
| `rotation` | Degrees around Z | Used by sprites, lights and directional orientation; 0 points along +X for directional/spot style aiming. |
| `scaleX` / `scaleY` | 1 = native size | Values above 1 enlarge; values below 1 shrink; negative values mirror the axis. |
## UI coordinates
Screen-space Text, TextInput, ChatLog and Joystick components use the reference-resolution pixel convention supplied by the Camera/device-fit pipeline. This is why HUD coordinates remain stable when the physical device resolution changes.
## Angles and vectors
Vector-like APIs use ordinary JavaScript objects such as `{x, y}`. When converting a direction to an angle, remember that the canvas/world Y axis points downward, so visually “up” is negative Y.
## Timing
| Concept | Meaning |
| --- | --- |
| `time.deltaTime` | Seconds since the previous script update; multiply speeds expressed per second by deltaTime. |
| `wait(seconds,...)` | Wall-clock game/script timer in seconds. |
| `repathInterval` | Navigation re-plan period in seconds. |
---
# Editor overview
> Navigate the Realot Studio editor and understand the main development surfaces.
## Main surfaces
| Area | Purpose |
| --- | --- |
| Hierarchy | Shows entities in the current scene, including hierarchy folders. |
| Inspector | Edits entity metadata and component properties. |
| Viewport | Scene/game editing and gizmos. |
| Script editor | Edit JavaScript with engine-aware autocomplete. |
| Bottom panels | Animation, tileset, navigation, status and related workflows. |
| Toolbar / menus | Save, project I/O, physics layers, navigation areas, entity creation and export. |
## Entity creation
The Add Component workflow exposes the engine’s authoring components, including Rigidbody2D, Collider2D, Joint2D, CharacterController, SpriteRenderer, SpriteAnimation, ShapeRenderer, StrokePath, Light, AudioSource, AudioListener, ShadowCaster, LightingSettings, Tileset, Tilemap, NavWorld2D, NavAgent2D, TextRenderer, SpeechBubble, ChatLog, TextInput and Joystick.
## Editor principle
The editor writes serializable scene/project data. Runtime systems consume that data. Private helper modules under `project/editor/` should be treated as implementation details, not game scripting APIs.
---
# Editor controls & exact locations
> Exact Realot Studio UI paths, panel positions, keyboard shortcuts, conditional tools, and where feature-specific buttons live.
> **Navigation rule:** This page is an index, not a substitute for feature docs. Each feature page also states the exact control path needed to perform its workflow.
## Editor layout
| Region | Location | What it contains |
| --- | --- | --- |
| Top toolbar | Across the top | File, Edit, GameObject, UI, Window; transform/navigation tools; Play/Pause; Export; Hub. |
| Hierarchy | Left, fixed-width column (~213px) | Current scene entity tree, search, folders, selection and add shortcuts. |
| Viewport | Center | Scene/Game tabs, viewport toolbar, canvas and editor gizmos. |
| Inspector | Right, fixed-width column (~255px) | Selected entity name/tag, components, property fields, Add Component and feature-specific buttons. |
| Bottom panel | Bottom edge | Project and Console tabs; scenes, sprites, audio, scripts, prefabs and runtime/editor logs. |
## Top menu paths
| Path | Open by clicking | Available commands |
| --- | --- | --- |
| File | File | Save Now / Saved, Save Project, Optimize Assets on Save, Load Project…, Export…, Extra Backup Storage, Restore from Backup Folder. |
| Edit | Edit | Physics Layers… and Nav Areas…. |
| Window | Window | Hierarchy, Asset Panel and Inspector show/hide checkboxes; Show All Panels while any panel is hidden. See [Editor settings & performance](settings.html). |
| GameObject | GameObject | Empty GameObject, Light, 2D Object, Shape. |
| UI | UI | Text, Speech Bubble, Chat Log, Message Input, Joystick. |
| GameObject → Light | GameObject → Light | Directional Light, Point Light, Spot Light, Area Light, God Rays, Freeform Light. |
| GameObject → 2D Object | GameObject → 2D Object | Tileset, Tilemap, Nav World 2D, Stroke Path. |
| GameObject → Shape | GameObject → Shape | Square, Circle, Capsule, Triangle. |
## Toolbar tools and shortcuts
| Key | Tool | When visible | Exact behavior |
| --- | --- | --- | --- |
| Q | Hand / Pan | Always | Drag to pan; scroll to zoom. |
| W | Translate | Always | Move selected entity with transform gizmo. |
| E | Rotate | Always | Rotate selected entity. |
| R | Scale | Always | Scale selected entity. |
| T | Tile | When a Tilemap or Tileset exists | Paint tile cells. |
| Y | Erase | When a Tilemap or a Nav World 2D exists | Erase tiles / relevant paint data. |
| P | Path | When a Stroke Path exists | Append/move/insert path points. |
| U | Nav paint walkable | When a Nav World 2D exists | Click = walkable; Alt-click = clear override. |
| I | Nav paint blocked | When a Nav World 2D exists | Click = blocked; Alt-click = clear override. |
| O | Nav area paint | When a Nav World 2D exists | Click = assign selected area; Alt-click = clear area. |
## Selection, history and playback shortcuts
These global shortcuts are ignored while you type in a text field, while the Script Editor is open, and while the Export window is open. Ctrl is Cmd on macOS.
| Shortcut | Action | Notes |
| --- | --- | --- |
| Delete / Backspace | Delete the selected entities | Requires a selection. |
| Ctrl+C | Copy selection | Yields to normal text copy when text is selected on the page. |
| Ctrl+V | Paste | |
| Ctrl+D | Duplicate selection | Copy + paste in one step. |
| Ctrl+Z | Undo | Scene edits and Animation-editor edits keep separate histories; undo acts on whichever editor is active. Up to 100 steps. |
| Ctrl+Shift+Z or Ctrl+Y | Redo | |
| Space | Toggle Play | Opens or closes the Play window. |
## Conditional controls
Some controls intentionally do not exist until the related scene object exists. This is important when documenting or generating instructions: do not tell users to click a hidden tool before creating the required object.
| Control | Condition |
| --- | --- |
| Tile (T) | A Tilemap or Tileset exists in the current world. |
| Erase (Y) | A Tilemap or a Nav World 2D exists (a Tileset alone does not enable it). |
| Path (P) | A Stroke Path exists. |
| U / I / O Nav brushes | A Nav World 2D exists. |
| Nav bounds/cells view | A Nav World 2D exists. |
| Paint Area selector | Nav Area tool O is active and named areas exist. |
---
# Editor settings and configuration
> Complete reference for the editor menus, panel visibility, physics layers, navigation areas, Inspector notes, saving preferences and performance defaults.
## Where the settings are
Realot Studio does not currently have one large Settings window. Options are placed beside the editor feature they control: use **File** for project storage and export, **Edit** for physics and navigation labels, and **Window** for panel visibility. Component-specific settings live in the Inspector and are documented on each [component reference page](../api/index.html).
## File menu
| Menu item | What it does | Availability / notes |
| --- | --- | --- |
| **Save Now / Saved** | Immediately saves the open Hub project to its browser autosave storage. The label shows whether there are unsaved changes. | Shown when the project was opened with a Hub autosave slot. |
| **Save Project** | Downloads a portable `.realot` project archive. When editing a supported file handle, the label can become *Save to [filename]*. | Available for project export to a local file. |
| **Auto-update file: ON / OFF** | Controls whether changes are automatically written back to the opened project file. | Only shown when a supported file handle is active. This is local file writing, not cloud sync. |
| **Save as copy (download)** | Downloads a separate copy without replacing the current file. | Shown when a file handle exists or the browser supports the Save File Picker. |
| **Optimize Assets on Save: ON / OFF** | Arms an optimization pass for the next Save Project operation. When enabled, supported PNG images are losslessly optimized and WAV audio is repacked before the archive is written. | Toggle does not save immediately; the next Save Project action performs the work. |
| **Load Project…** | Opens a saved Realot project file. | Choose a `.realot` project. Loading a project containing scripts asks for confirmation because scripts execute as page code. Loading a project containing scripts asks for confirmation because scripts execute as page code. |
| **Export…** | Opens the standalone game export window. | See [Export window](../export/export-window.html) and [Android APK](../export/android.html). |
| **Enable Extra Backup Storage…** | Lets you select a local folder for mirrored project autosaves, outside the browser's normal storage quota. | Requires browser support for the File System Access API and user permission. |
| **Extra Backup Storage: ON** | Turns off future mirroring to the selected folder. | Does not delete files already written to that folder. |
| **Restore from Backup Folder…** | Restores the most recent project snapshot mirrored to the selected folder. | Only shown while extra backup storage is enabled for the project. |
## Edit menu
| Menu item | What it configures |
| --- | --- |
| **Physics Layers…** | Opens the 16-slot physics layer-name editor. Slot 0 starts as `Default` and cannot be cleared, though it can be renamed. Slots 1–15 can be named or left blank. These names are labels for the fixed runtime layer indices used by Collider2D layer/mask filtering and physics queries. |
| **Nav Areas…** | Opens the 16-slot navigation-area name editor. Slot 0 starts as `Ground` and cannot be cleared; slot 1 starts as `Water`; slots 2–15 are initially blank. Names can be changed or cleared except for slot 0. The slot indices are stored in navigation cells and NavAgent2D area masks. |
Physics-layer and navigation-area names are saved with project data. The indices—not the text labels—are what collision filtering and pathfinding use at runtime. Renaming an existing slot does not move its contents to another index.
## Project tags
Use the selected entity's **Tag** dropdown in the Inspector to assign a tag. The initial list contains `Untagged`, `Player` and `Enemy`. These are ordinary tag names supplied as starting defaults; `Player` and `Enemy` do not have automatic engine behavior just because of their names.
- Choose **Add Tag…** in the dropdown to create a project tag.
- Custom tags can be removed from the tag list. `Untagged` is protected and cannot be deleted.
- `Player` and `Enemy` are not protected; they can be removed like other tags.
- Removing a tag removes it from the dropdown. Entities that already carry that tag keep their current tag value until you change it.
- The available tag list is included in the saved project snapshot. An entity's assigned tag is stored with its scene data.
Tags are separate from physics layers and navigation areas. Use physics layers for collision filtering and navigation areas for pathfinding costs or masks; use tags to identify objects in editor workflows and scripts.
## GameObject and UI menus
**GameObject → Empty GameObject** creates an empty entity. **GameObject → Light** provides Directional, Point, Spot, Area, God Rays and Freeform lights. **GameObject → 2D Object** creates a Tileset, Tilemap, Nav World 2D or Stroke Path. **GameObject → Shape** creates Square, Circle, Capsule or Triangle shapes with a matching visible ShapeRenderer and collider.
The **UI** menu creates a Text object, Speech Bubble, Chat Log, Message Input (TextInput) or Joystick. These are shortcuts for creating an entity with the corresponding component; the full settings are on each component's reference page.
## Window menu and panel visibility
| Panel | What it contains | Default |
| --- | --- | --- |
| **Hierarchy** | Scene entities and their selection/order. | Visible |
| **Asset Panel** | Bottom editor area for assets and related project panels. | Visible |
| **Inspector** | Selected entity properties and component settings. | Visible |
Choose a panel name under **Window** to show or hide it. Hiding a panel gives more room to the Scene view. When one or more panels are hidden, **Show All Panels** restores them. Visibility is remembered in this browser, not stored as a project setting.
## Inspector component notes
The Inspector's information toggle controls optional explanatory notes below component settings. It is a display preference; actionable setup warnings remain visible independently. The default is off.
## Performance preferences and defaults
The current source defines the following stored preferences under the browser storage key `realot_engine_settings`. This is a reference to the shipped implementation—not a hidden user settings screen. Apart from the Inspector component-notes toggle described above, the current editor does not expose controls for these performance preferences in a general Settings dialog.
| Stored setting | Default | Meaning / supported values |
| --- | --- | --- |
| `editorFpsFocused` | `60` | Target rendering rate for the editor viewport while the editor window is focused. |
| `editorFpsUnfocused` | `24` | Target rendering rate for the editor viewport while unfocused. |
| `gameFps` | `60` | Play-window target: `30`, `60`, `120`, or `0` for unlimited (limited by the browser's animation-frame scheduling). |
| `backgroundRendering` | `true` | Allows throttled editor rendering to continue while the editor is unfocused rather than fully pausing. |
| `vsync` | `true` | Stored vertical-sync preference read by the rendering scheduler. |
| `showComponentNotes` | `false` | Whether optional Inspector component notes are displayed. This one is toggled by the Inspector UI. |
These values are implementation defaults and targets, not guarantees that a browser, device or display can maintain a particular frame rate. The editor viewport's focused/unfocused caps are separate from the runtime frame loop in an exported game.
## Console and diagnostics
The Console is part of the bottom editor area. It displays editor messages and script output; use its **Copy** control to copy visible logs and **Clear** to clear them. The gameplay debug HUD is separate: scripts can enable it with `debug.show()` in the Play window. See [Global API](../scripting/globals.html).
## Component settings
Component-specific options are not centralized in this page. The source-derived [component reference](../api/index.html) lists every public scene field, its data type, current default and script-facing API members for all 25 components. For navigation, physics and animation workflows, start with the corresponding [Physics](physics.html), [Navigation](navigation.html) and [Assets & animation](assets-animation.html) guides.
---
# Hierarchy & Inspector
> Organize the current scene and edit entities/components with stable serialized data.
> **Exact control path:** Select the entity in the left Hierarchy panel or click it in the center Scene view. Its properties appear immediately in the right Inspector . The Add Component button is at the bottom of the Inspector’s component list; use its search field to find a component by name.
## Hierarchy
The Hierarchy shows only entities that belong to the active scene. Entities can also belong to hierarchy folders. The saved scene stores folders separately so folder IDs remain stable across save/load.
## Inspector
The Inspector edits the entity name, tag, active state, component properties and component-specific authoring fields. For many components, the Inspector exposes more authoring fields than the runtime script API intentionally does.
## Gizmos and shapes
Spatial editing uses scene-view gizmos for things such as triangle collider/shape points and other editable geometry. Treat these as authoring controls; scripts should use the documented component APIs instead of manipulating editor gizmo state.
---
# Scenes & projects
> Save, load, switch, duplicate and serialize Realot Studio scenes and project manifests.
> **Exact control path:** Project-level scene/file operations are in the bottom Project panel. Scene creation uses Project → Scenes → New Scene ; Save Project and Load Project are in the top File menu. The autosave indicator/action is also exposed through File → Save Now / Saved .
## Scene workflow
The Scene Manager supports creating, saving, switching, renaming, duplicating and deleting scenes. The last remaining scene cannot be deleted.
## Project compatibility
The project manifest stores compatibility metadata. When a project created by a newer engine build is opened in an older build, the editor can show a compatibility warning. This information belongs to the saved project and does not create versioned documentation pages or download releases.
## Recommended practice
Keep source projects with explicit scene names, tags and stable IDs. Keep backups of important project archives before opening them in a different engine build, especially when compatibility warnings appear.
## Save and reopen a project
Choose **File → Save Project** in the editor to download a `.realot` project file. To reopen it by double-clicking, install Realot Hub as a PWA in a desktop browser that supports file handling. Double-click the `.realot` file in your file manager; the installed Realot app opens the project in the editor. Realot can ask permission to save future changes back to the same file. If your browser does not support PWA file handling, use **File → Load Project** inside the editor.
---
# Assets & animation
> Use sprites, animation clips and audio assets from the editor.
> **Exact control path:** Imported sprites/audio/scripts/prefabs live in the bottom Project panel. Drag supported assets into the center Scene viewport. For animation, add Sprite Animation in the Inspector, then use the Animation editor window to create clips and import frames.
## Sprites
SpriteRenderer points at an asset key rather than embedding image data in the component. This keeps scene JSON lightweight and lets exported runtime assets remain separate.
## Animation
SpriteAnimation stores clips and current playback state. Scripts can call `this.animator.play("Run")`, stop playback and inspect current clip/frame information.
## Audio
AudioSource stores the asset key plus playback properties. 3D sources use `minDistance` for full volume and fade toward silence at `maxDistance`. AudioListener defines the hearing radius and sound enter/leave callbacks are available to scripts.
---
# Prefab workflow
> Create, place, edit, update, revert and unpack Realot Studio prefabs with the exact editor controls involved.
> **What a prefab is:** In Realot Studio a prefab is a reusable one-entity template. Instances keep a prefabId and track field-level overrides. Updating a prefab can propagate the canonical data to other instances.
## Create a prefab
Select an entity in the Scene viewport or Hierarchy. In the right Inspector, use the small prefab/box action next to the entity name. The engine creates a prefab from that entity and links the source entity to it.
## Place an instance
Use the bottom Project panel → Prefabs folder. Drag a prefab asset into the center Scene viewport. The editor instantiates the template and places the new instance in the scene.
## Edit an instance
Change component values normally in the Inspector. Realot Studio records changed fields as prefab overrides for that instance.
## Update the prefab
When an instance is selected, the Inspector shows a blue Prefab strip. Optional Update Transform checkboxes control whether Position, Rotation, and Scale should also propagate to other instances. Click Update Prefab to make this instance the new canonical template.
## Revert / Unpack
| Inspector control | Effect |
| --- | --- |
| `Revert Prefab` | Discard the instance’s overrides and re-sync its values from the prefab. |
| `Unpack Prefab` | Detach this instance while keeping its current values. Future prefab updates no longer reach it. |
## Delete a prefab asset
Bottom Project → Prefabs. Use the asset delete control. Existing objects keep their current data but are no longer linked to the deleted prefab.
## Important implementation fact
Prefab data is stored in the project’s `prefabs.json` catalogue and is included by Save Project/import/export flows.
---
# Physics authoring
> Configure rigid bodies, colliders, joints, layers and one-way platforms.
> **Exact control path:** Physics components are added from Inspector → Add Component (Rigidbody 2D, Collider 2D, Joint 2D, Movement Type). Global named physics layer slots are edited at Edit → Physics Layers… .
## Rigid bodies
| Body type | Typical responsibility |
| --- | --- |
| Dynamic | Physics solver controls movement; scripts apply forces/impulses or read/write velocity. |
| Kinematic | Scripts/controllers request movement; collision resolution produces contact state. |
| Static | Fixed world geometry; no dynamic motion. |
## Colliders
Collider2D supports Box, Circle, Capsule and Triangle shapes. You can enable triggers, one-way platforms, friction/restitution, density, offsets and 16-layer collision filtering.
## Collision layers
Each collider belongs to one layer (0-15) and exposes a 16-bit mask of layers it can interact with. A raycast can use `physics.layer(…)` to build the same mask model for query filtering.
## Joints
Joint2D supports Fixed, Revolute, Prismatic, Rope and Spring. Rope and Spring use multi-segment chains for visual/physical behavior and expose anchors, length, stiffness/damping and optional motors/limits.
## One-way platforms
> **Direction matters:** A one-way platform is a Collider2D with isOneWayPlatform = true . The physics system distinguishes pass-through movement from the blocking direction, so the behavior should be tested with the body moving from both sides.
---
# Navigation authoring
> Bake 2D navigation with NavWorld2D and configure NavAgent2D.
> **Exact control path:** Create the shared nav grid with GameObject → 2D Object → Nav World 2D . Then the top toolbar exposes U walkable, I blocked and O area paint tools. Brush −/+ controls sit directly beside those nav tools. Named areas are configured at Edit → Nav Areas… .
## NavWorld2D
A NavWorld2D defines world bounds, cell size and authored/baked cell data. It supports 16 navigation areas, per-area costs, optional diagonal traversal and optional dynamic rebuilding.
## Agents
NavAgent2D adds radius, speed, acceleration/deceleration, stopping distance, automatic repathing and avoidance. Vehicle-oriented settings are available for car-style navigation/steering.
## Script access
Scripts use the global `nav` module: `nav.findPath()`, `nav.isWalkable()` and `nav.bake()`. A NavAgent exposes its live `currentPath` and `currentPathIndex` as read-only script state.
## Pathfinding behavior
Path endpoints are snapped to the nearest walkable cell. Returned waypoints are world-space points with straight runs merged, but they are not geometrically smoothed.
---
# Lighting, audio & UI
> Build atmospheric scenes, sound behavior and responsive UI with Realot Studio components.
> **Exact control path:** Create lights from GameObject → Light or add Light/Audio/UI components through Inspector → Add Component . Screen-space UI entities can also be created directly from the top UI menu.
## Lighting
Lights support Directional, Point, Spot, Area, GodRays and Freeform types. LightingSettings controls scene-wide shadow quality, ambient darkness and visible glow strength. ShadowCaster controls per-entity shadow geometry and softness.
## Shadow quality
ShadowMode `quad` is the cheaper analytic mode. `raymarch` enables per-pixel ray-marched occlusion; `raymarchSteps` controls accuracy/cost and is clamped to 1-200.
## UI
TextRenderer can be screen-space, while SpeechBubble, ChatLog, TextInput and Joystick provide higher-level UI behaviors. TextInput exposes `justSubmitted`; Joystick exposes normalized x/y input and engagement state.
## Audio listeners
AudioSource can be 3D distance-attenuated. AudioListener receives hearing-area transitions that map to `onHearSound(source)` and `onLoseSound(source)`.
---
# Tilemaps & tilesets
> Author sparse tile grids and 16-role autotile tilesets.
> **Exact control path:** Create a reusable tileset via GameObject → 2D Object → Tileset and the tile grid via GameObject → 2D Object → Tilemap . Once present, T selects tile painting and Y selects erase. The Tileset Editor exposes the 4×4 role grid and import actions.
## Tileset authoring
The editor can take one image and auto-slice it into a 4×4 role grid, or accept up to 16 separate role images. The stored result is sixteen role-to-sprite-key mappings.
## The 16 roles
The canonical order is `cornerTL, edgeT, cornerTR, stubT, edgeL, center, edgeR, lineV, cornerBL, edgeB, cornerBR, stubB, stubL, lineH, stubR, single`.
## Tilemap data
A Tilemap references a Tileset by entity ID and stores a sparse set of filled cells keyed as `col,row`. The runtime computes the visual tile role from orthogonal neighbors; it does not store the final role per cell.
## Scripting
> **No direct Tilemap script module:** Tilemap/Tileset are editor/scene-data components. There is currently no documented this.tilemap runtime API.
---
# Components: complete workflow
> A complete guide to adding, configuring, testing, removing, and scripting components. This page complements each individual component reference; it does not replace the per-component settings tables.
## 1. Select the entity first
Click an entity in the **Hierarchy** on the left or select it in the Scene viewport. The selected entity's properties appear in the **Inspector** on the right.
## 2. Add a component
At the bottom of the Inspector click **Add Component**. A centered **Add Component** modal opens with a search field and a scrollable list. Type the component name, then click its row. The list excludes components the entity already has.
## 3. Configure the component
After adding it, scroll the Inspector to the new component section. Start with the component's mode/type field if it has one. Changing a mode can expose or hide related settings. Configure required references/assets before tuning numbers.
## 4. Understand values versus runtime state
Serialized authoring settings are saved with the scene. Runtime state fields can change while the game runs and are useful for debugging. Examples include Rigidbody2D velocity/ground state and CharacterController request/state values.
## 5. Test in Play mode
Run the game, observe the result, and inspect the component again when debugging. Change one setting at a time so you can identify which property caused the behavior.
## 6. Use the dedicated editor tools
| System | Where | What it does |
| --- | --- | --- |
| Sprite | Inspector SpriteRenderer section / asset picker | Assign the visual asset. |
| Animation | SpriteAnimation → Open Animation Window | Create and edit clips/frames. |
| Physics | Collider/Transform gizmos in Scene viewport | Visually inspect/edit geometry. |
| Navigation | NavWorld2D + navigation toolbar + Edit → Nav Areas… | Author areas, bake/debug navigation, then use NavAgent2D. |
| Tiles | Tileset/Tilemap panels | Create tile data and paint the map. |
| Stroke Path | Stroke Path viewport tool/gizmo | Edit path points and inspect serialized path settings. |
| Scripts | Script → Create New Script / Load Script… / Open Script Editor | Create, attach, edit, and enable scripts. |
| Lighting | Light/ShadowCaster gizmos + Inspector | Author light geometry and shadow participation. |
## 7. Component combinations that matter
- **Dynamic physics actor:** Rigidbody2D + Collider2D; add SpriteRenderer/ShapeRenderer for visuals.
- **Platformer controller:** Rigidbody2D + Collider2D + CharacterController; choose Platformer and configure its movement group.
- **Navigation agent:** NavWorld2D in the navigation world + NavAgent2D on the moving entity; bake/configure the world before testing agent movement.
- **Animated character:** SpriteRenderer + SpriteAnimation, optionally with Rigidbody2D/CharacterController.
- **Interactive UI:** the appropriate UI component (TextRenderer, TextInput, Joystick, SpeechBubble, ChatLog) plus Script when behavior is needed.
## 8. Where to go next
Use the component reference for the complete field table, defaults, API members, notes, and examples. Use [Navigation: Complete Setup](../scripting/navigation-complete.html) for multi-system navigation. Use [Script API Cookbook](../scripting/api-cookbook.html) for complete scripting recipes.
---
# Complete feature workflows
> Use these pages when you need to build an entire subsystem, not just understand one property. Each workflow starts with prerequisites and editor locations, then moves through configuration, scripting, testing and troubleshooting.
### [Navigation authoring](../editor/navigation.html)
Create Nav World 2D, configure bounds/cell size, define areas, paint or derive walkable space, add agents, bake/update navigation and debug the result.
### [Navigation from editor to script](../scripting/navigation-complete.html)
Complete path from scene setup through NavAgent2D, named area masks/costs, navMoveToward/navDriveToward and runtime troubleshooting.
### [Physics authoring](../editor/physics.html)
Build colliders, rigidbodies, joints and character controllers, then tune layers, masks, gravity, damping, slopes and one-way platforms.
### [Physics scripting](../scripting/physics.html)
Use Rigidbody2D, Collider2D, raycasts, forces/impulses, collision state and movement APIs from scripts.
### [Lighting, audio and UI](../editor/lighting-audio-ui.html)
Set up lights/shadows, audio sources/listeners, text and interactive UI components with their editor locations and runtime APIs.
### [Tilemaps and tilesets](../editor/tilemaps.html)
Create tileset data, attach it to a Tilemap, paint, edit tile data and understand the navigation/physics consequences of tile geometry.
### [Assets and animation](../editor/assets-animation.html)
Import/use sprites, build Sprite Animation clips, choose frames, set playback and connect animation state to scripts.
### [Prefabs](../editor/prefabs.html)
Create reusable entity templates, instantiate them, understand overrides, update/revert behavior and runtime spawning.
### [Web/PWA deployment](../export/web.html)
Understand the normal online workflow, standalone web export, PWA behavior and what a deployment must serve.
### [Android APK export](../export/android.html)
Configure the separate build-server workflow and understand what is sent from the browser editor.
## How to use these guides
1. Start with the prerequisites section.
2. Follow the exact editor path instead of guessing which panel contains a control.
3. Configure the minimum working setup first.
4. Only then add optional tuning such as costs, smoothing, avoidance, shadows, custom input or advanced physics.
5. Run the smallest test scene before integrating the subsystem into a large project.
6. If a result is wrong, use the troubleshooting section before changing unrelated settings.
---
# Lifecycle
> Complete Realot Studio script lifecycle and callback reference.
## Core lifecycle
| Callback | Semantics |
| --- | --- |
| onStart() | Once before first onUpdate(). |
| onClone() | Once for runtime clones, immediately before onStart(). |
| onUpdate(dt) | Every render frame. |
| onFixedUpdate(dt) | Fixed 60 Hz accumulator. |
| onDestroy() | Before entity removal / scene end. |
```
function onStart() {
this.hp = 100; // custom fields on this persist across the entity’s lifetime
debug.log("HP", this.hp);
}
function onUpdate() {
this.x += 50 * time.deltaTime; // frame-rate independent movement
}
function onFixedUpdate(dt) {
// runs at a fixed 60 Hz step — good for deterministic physics-adjacent logic
}
function onDestroy() {
debug.clear("HP");
}
```
## Pointer callbacks
`onClick()` is a frame pulse for mouse/finger presses targeting an entity with Collider2D. For continuous polling, use `this.isPointerOver`, `this.isClicked`, `this.isTouchOver` or `this.isTapped` where appropriate.
```
function onClick() {
this.destroy(); // pops this entity when clicked or tapped
}
```
## Collision callbacks
| Callback | Runs |
| --- | --- |
| onCollision(other) | Alias of collision-enter behavior. |
| onCollisionEnter(other) | Contact begins. |
| onCollisionStay(other) | Every physics step while still touching. |
| onCollisionExit(other) | Contact ends. |
| onTriggerEnter(other) | Trigger overlap begins. |
| onTriggerExit(other) | Trigger overlap ends. |
```
function onCollisionEnter(other) {
if (other.name === "Ground") this.isGrounded = true;
}
function onTriggerEnter(other) {
if (other.hasComponent("Rigidbody2D")) scene.load("Level2");
}
```
## State callbacks
When using `this.state.change(name)`, Realot Studio can call `onStateExit()`, `onStateEnter()` and `onStateUpdate(dt)` for state-specific logic.
```
function onUpdate() {
if (this.hp <= 0 && this.state.current !== "dead") {
this.state.change("dead");
}
}
function onStateEnter() {
if (this.state.current === "dead") this.sprite.opacity = 0.3;
}
```
## Error isolation
Lifecycle errors are caught and reported by the runtime. A one-time `onStart()` failure disables the script; recurring `onUpdate()` errors are isolated so the next frame can continue.
---
# Global scripting API
> Reference for every built-in global function and service object available inside Realot Studio scripts.
## Entity lookup
| Function | Returns / behavior |
| --- | --- |
| `findFirst(name)` | First entity with this name, or `null`. |
| `findAll(name)` | All entities with this name. |
| `findFirstWithTag(tag)` | First entity with this tag, or `null`. |
| `findAllWithTag(tag)` | All entities with this tag. |
| `findWithTag(tag)` | Alias for `findAllWithTag(tag)`. |
| `findById(id)` | Entity with this exact stable ID, or `null`. |
| `findInRadius(x, y, radius, opts?)` | Nearby entities, nearest first. Optional filters can narrow the search. |
## Scene (`scene`)
`scene` contains the same entity-lookup functions above, plus `load(sceneName)`, `restart()`, `pause()`, `resume()`, the read-only properties `current` and `isPaused`, and scene-wide `lighting`. `scene.pause()` freezes gameplay simulation while leaving the editor/Play window responsive; call `scene.resume()` to continue.
## Physics (`physics`)
`physics.raycast(x1, y1, x2, y2, opts?)` casts a ray against Rapier collider shapes and returns the closest hit or `null`. A hit contains the entity, world point, surface normal (when available) and distance. Pass `{ exclude: [this] }` to skip an entity, `{ debug: true }` to draw the ray for one frame, or `{ layerMask: physics.layer(0, 2) }` to filter by layer bits. `physics.layer(...indices)` creates the bitmask for slots 0–15.
```
function onUpdate() {
var hit = physics.raycast(this.x, this.y, this.x + 200, this.y, {
exclude: [this],
debug: true
});
if (hit) debug.log("Ray hit", hit.entity.name);
}
```
## Navigation (`nav`)
| Member | Purpose |
| --- | --- |
| `findPath(x1, y1, x2, y2, opts?)` | Returns world-space waypoints or `null` when no route is available. |
| `isWalkable(x, y)` | Tests whether a world point falls on a walkable navigation cell. |
| `bake()` | Rebuilds the scene NavWorld2D from current colliders; returns walkable/blocked counts or `null`. |
| `areaIndex(name)` | Resolves an area name to a slot index, or `-1`. |
| `areaMask(...names)` | Builds a bitmask from named areas. |
| `areaCosts(costsByName)` | Builds a 16-entry cost array from area names and positive costs. |
For moving entities every frame, use `this.navMoveToward()` or (for a Car controller) `this.navDriveToward()`. See [Pathfinding](navigation.html).
## Keyboard (`input`)
`input.keyDown(key)` is true while a key is held. `input.keyPressed(key)` is true only on the frame it is first pressed. Both accept `"Any"` to test whether any key is held or was pressed that frame. Use the [Input guide](input.html) for key naming and patterns.
## Mouse and pointer (`mouse`)
`mouse.x` and `mouse.y` are world coordinates. `screenX` and `screenY` are canvas pixels. `over` reports whether the pointer is over the game canvas. `down(button?)`, `pressed(button?)` and `released(button?)` read mouse buttons (0 left, 1 middle, 2 right; omitted means left). `isOver(entityOrName, opts?)` tests hover and `clickedOn(entityOrName, opts?, button?)` tests a click on a specific entity.
## Touch (`touch`)
`touch` is a live array of active touches. Each touch exposes `id`, world-space `x/y`, canvas-pixel `screenX/screenY`, start coordinates, displacement (`dx/dy`), `distance`, and one-frame `justStarted/justEnded` flags. The array also exposes `count`, `first`, `anyJustStarted` and `anyJustEnded`. Gesture helpers are `swipe.active/direction/dx/dy/distance` and `pinch.active/scale/delta/distance`. `touch.isOver(entityOrName, opts?)` checks a finger over an entity; `touch.tappedOn(entityOrName, opts?)` detects the initial tap. See [Input guide](input.html).
## Time (`time`)
`time.deltaTime` is scaled frame time, `time.unscaledDeltaTime` is frame time before time scaling, `time.elapsed` is elapsed game time, and `time.scale` controls game speed. A scale of 0 pauses time-driven simulation; 1 is normal speed. See [Time scale & game speed](time-scale.html).
## Random and math helpers
`random.int(min, max)` returns an inclusive random integer. `random.float(min, max)` returns a random float in the half-open range [min, max). `mathx` provides `lerp`, `smoothstep`, `clamp`, `moveToward`, `remap` and `approximately`. A bare `smoothstep(a, b, value)` global is also available. Native JavaScript `Math` is available as well.
## Shared in-memory state (`global`)
`global` is a shared key/value object visible to all scripts in the current running game. Read and write named properties directly, for example `global.score = 10`. It is memory-only; it does not survive reloading the game page. Use `save` for persistent data.
## Persistent save data (`save`)
`save` stores JSON-safe values in IndexedDB, separated into named save slots. Its full 13-member API is listed in [SaveAPI](../api/script-modules.html#saveapi). Common calls are `get`, `set`, `has`, `delete`, `keys` and `clear`. Use `await save.load("slot2")` to change slots, `await save.listSlots()` to list them, `await save.deleteSlot("slot2")` to remove a slot, and `await save.flushNow()` to wait for pending writes. See [Persistence](persistence.html).
## Debug HUD (`debug`)
`debug.show()` enables the gameplay HUD and system timing display in the Play window; `debug.show(false)` turns it off. `debug.showFps(false)` hides only its FPS line. `debug.log(label, value)` adds or updates a custom line; `debug.clear(label)` removes one line; `debug.clearAll()` removes all custom lines. This is separate from the editor Console.
## Object pools (`pool`)
`pool.create(name, options)` creates a named pool using a source prefab, scene entity or EntityContext. `pool.find(name)` retrieves a named pool, `pool.get(name, x, y)` gets an active object, and `pool.release(entity)` returns it for reuse. A pooled entity can call `this.releaseToPool(delay?)`. Pooled scripts can use `onEnable` and `onDisable` for work that should run each time an object is borrowed or returned.
## Spawn, timers, messages and tweens
| Function | Behavior |
| --- | --- |
| `spawn(nameOrTag, opts?)` | Clones an entity found by name, or by tag when `opts.byTag` is true. Returns an EntityContext or `null`. |
| `wait(seconds, callback)` | Runs once after game time passes; returns a timer ID. |
| `repeat(seconds, callback)` | Runs repeatedly at the interval; returns a timer ID. |
| `cancelWait(id)` / `cancelRepeat(id)` | Cancel the matching timer. Entity-owned timers also stop when their owner is destroyed or the scene changes. |
| `sendMessage(tagOrEntity, message, data?)` | Sends to all scripts matching a tag, or one exact entity context. |
| `broadcastMessage(message, data?)` | Sends to every script in the current scene. |
| `tween(target, properties, duration, easing?, onComplete?)` | Animates numeric properties over game time; returns an ID. |
| `cancelTween(id)` | Cancels a running tween. |
Read [Timers, state & messaging](timers-state.html), [Finding and spawning](finding-entities.html) and [Tween API](tween.html) for complete examples and option details. The [script module index](../api/script-modules.html) contains all 24 component/global API module allow-lists.
---
# Tween API
> Animate numeric properties smoothly with tween(), choose from 33 easing curves, and stop animations with cancelTween().
## Overview
`tween(target, properties, duration, easing, onComplete)` smoothly moves one or more numeric properties from their current value to a target value over a number of **game seconds**. It is a global function, available in every script with no import. It returns a numeric id you can pass to `cancelTween(id)`.
| Argument | Type | Meaning |
| --- | --- | --- |
| `target` | object | An entity context (`this`, or the result of `findFirst()` etc.) or a scripting component object such as `this.sprite`, `this.light` or `this.camera`. |
| `properties` | object | Map of property name to end value, for example `{ x: 420, y: 180 }`. Only finite numbers are accepted as end values. |
| `duration` | number | Length in game seconds. `0` (or an invalid value) completes on the next tween update. |
| `easing` | string | Optional. One of the [33 easing names](#easing-catalogue). Empty or omitted means `"linear"`. |
| `onComplete` | function | Optional. Called once when the tween finishes, with `this` bound to the entity that started the tween. |
```
function onStart() {
// Move, spin and resize over 0.8 game seconds
tween(this, { x: 420, y: 180, rotation: 90, scaleX: 1.2, scaleY: 1.2 }, 0.8, "easeOutCubic", function () {
// "this" is still the entity that started the tween
tween(this.sprite, { opacity: 0.25 }, 0.35, "easeInOutSine");
});
}
```
## What can be tweened
A property is tweened only if it **already exists on the target and currently holds a finite number**. Properties that are missing, non-numeric (colours are hex strings, `position` and `scale` are objects) or non-finite are skipped.
| Target | Typical tweenable properties |
| --- | --- |
| `this` (entity) | `x`, `y`, `rotation`, `scaleX`, `scaleY` |
| `this.sprite` | `opacity` |
| `this.shape` | `width`, `height`, `radius`, `opacity`, `outlineWidth` |
| `this.text` | `fontSize`, `opacity` |
| `this.light` | `intensity`, `radius`, `angle`, `shadowStrength` |
| `this.audio` | `volume`, `pitch` |
| `this.camera` | `zoom`, `offsetX`, `offsetY` |
| `this.strokePath` | `thickness`, `opacity`, `textureOffset` |
| `scene.lighting` | `ambientDarkness`, `glowStrength` |
Any numeric member listed on a component's Script API table can be a tween target. Each tween writes through the normal script API, so setter rules (clamping, validation) still apply.
## Cancelling
```
var id = tween(this, { x: 700 }, 2, "easeOutBounce");
// later
var wasActive = cancelTween(id); // true only if a tween with that id was still running
```
`cancelTween()` leaves the property at whatever value it had reached. `onComplete` is not called for a cancelled tween.
## Behavior and rules
- **Start tweens from lifecycle callbacks** such as `onStart()`, `onClick()` or a collision handler. Calling `tween()` outside script execution logs `[tween]` warning and returns `-1`. Avoid creating a new tween every frame in `onUpdate()`; start one and let it run.
- **Game time.** Tweens advance once per frame after `onUpdate` callbacks, using the scaled frame clock. [`time.scale`](time-scale.html) speeds them up or slows them down, and `scene.pause()` freezes them.
- **Exact finish.** When progress reaches 1 the property is set to the exact end value, so back/elastic overshoot never leaves a rounding error.
- **Several properties at once** in one call share the same duration and easing.
- **Automatic cleanup.** A tween ends silently if the entity that started it, or the entity it targets, is destroyed. Restarting or switching scenes clears all tweens.
- **Errors.** If an easing function or a property setter throws, that tween is removed and the error is reported in the Console with the owning entity name. A completion callback that throws is reported as `tween onComplete`.
- **Return value.** Invalid input (bad target, properties not an object, unknown easing, no numeric properties, non-function `onComplete`) returns `-1` and logs a `[tween]` warning that says what to fix. An unknown easing name is never silently treated as linear.
- **Easing names** are case-insensitive and ignore spaces, hyphens and underscores, so `"EASE-OUT-QUAD"` equals `"easeOutQuad"`.
> **Tweening physics bodies:** Assigning x or y on an entity that has a Dynamic or Kinematic Rigidbody2D teleports the body each frame. For moving physics objects use velocities or forces; use tween for transforms, opacity, UI, lights, cameras and Static or non-physics entities.
## Editor support
The Script Editor autocompletes `tween` and `cancelTween`, and offers the easing names inside the easing string (type `tween(this, { x: 100 }, 1, "easeOut` and the matching names appear). Both names are syntax-highlighted as engine globals.
## Easing catalogue
Every name below is a real engine easing. Each preview is drawn from the engine's own easing function: the horizontal axis is time (0 to 1) and the vertical axis is progress. The dashed lines mark the start value (bottom) and end value (top); curves that cross them overshoot on purpose. **In** starts slowly, **Out** ends slowly, **InOut** does both.
| Family | Names |
| --- | --- |
| Basic | `linear`, `smoothstep`, `smootherstep` |
| Quad | `easeInQuad`, `easeOutQuad`, `easeInOutQuad` |
| Cubic | `easeInCubic`, `easeOutCubic`, `easeInOutCubic` |
| Quart | `easeInQuart`, `easeOutQuart`, `easeInOutQuart` |
| Quint | `easeInQuint`, `easeOutQuint`, `easeInOutQuint` |
| Sine | `easeInSine`, `easeOutSine`, `easeInOutSine` |
| Expo | `easeInExpo`, `easeOutExpo`, `easeInOutExpo` |
| Circ | `easeInCirc`, `easeOutCirc`, `easeInOutCirc` |
| Back | `easeInBack`, `easeOutBack`, `easeInOutBack` |
| Elastic | `easeInElastic`, `easeOutElastic`, `easeInOutElastic` |
| Bounce | `easeInBounce`, `easeOutBounce`, `easeInOutBounce` |
### Basic
`linear`
`smoothstep`
`smootherstep`
### Quad
`easeInQuad`
`easeOutQuad`
`easeInOutQuad`
### Cubic
`easeInCubic`
`easeOutCubic`
`easeInOutCubic`
### Quart
`easeInQuart`
`easeOutQuart`
`easeInOutQuart`
### Quint
`easeInQuint`
`easeOutQuint`
`easeInOutQuint`
### Sine
`easeInSine`
`easeOutSine`
`easeInOutSine`
### Expo
`easeInExpo`
`easeOutExpo`
`easeInOutExpo`
### Circ
`easeInCirc`
`easeOutCirc`
`easeInOutCirc`
### Back
`easeInBack`
`easeOutBack`
`easeInOutBack`
### Elastic
`easeInElastic`
`easeOutElastic`
`easeInOutElastic`
### Bounce
`easeInBounce`
`easeOutBounce`
`easeInOutBounce`
## Recipes
### Fade out and destroy
```
function onClick() {
tween(this.sprite, { opacity: 0 }, 0.4, "easeInQuad", function () {
this.destroy();
});
}
```
### Pop-in UI
```
function onStart() {
this.scaleX = 0;
this.scaleY = 0;
tween(this, { scaleX: 1, scaleY: 1 }, 0.5, "easeOutBack");
}
```
### Light pulse that can be stopped
```
function onStart() {
this._pulse = tween(this.light, { intensity: 2 }, 0.6, "easeInOutSine", function () {
tween(this.light, { intensity: 0.5 }, 0.6, "easeInOutSine");
});
}
function onDestroy() { cancelTween(this._pulse); }
```
### Slow-motion hit stop with a tween that ignores nothing
```
function onCollisionEnter(other) {
time.scale = 0.2; // tweens and timers slow down too
wait(0.3, function () { time.scale = 1; });
}
```
---
# Time scale & game speed
> Slow motion, speed-up and freeze with time.scale, plus time.deltaTime, time.unscaledDeltaTime and time.elapsed.
## The time object
| Member | Type | Meaning |
| --- | --- | --- |
| `time.deltaTime` | number | Game seconds since the previous frame. Follows `time.scale`. |
| `time.unscaledDeltaTime` | number | Real seconds since the previous frame, ignoring `time.scale`. Use it for menus and UI that must keep animating while the game is slowed or frozen. |
| `time.elapsed` | number | Game seconds since the game started. Follows `time.scale`. |
| `time.scale` | number | Read/write game speed multiplier, from 0 to 100. Default `1`. |
## Using time.scale
`time.scale` changes how fast the whole game runs, like Unity's `Time.timeScale`.
```
function onClick() {
time.scale = 0.3; // slow motion
wait(1.5, function () { // 1.5 GAME seconds = 5 real seconds at 0.3
time.scale = 1;
});
}
```
| Value | Effect |
| --- | --- |
| `1` | Normal speed. |
| `0.5` | Slow motion (half speed). |
| `2` | Double speed. |
| `0` | Frozen. The world still updates with `dt = 0`, rendering continues, and scripts keep running so you can read input and show a pause menu. |
## What is and is not affected
- **Affected:** physics, animation, [`tween()`](tween.html), `wait()` and `repeat()`, `onFixedUpdate`, `time.deltaTime` and `time.elapsed`.
- **Not affected:** input, rendering and `time.unscaledDeltaTime`.
## Limits and gotchas
- Values must be numbers from 0 to 100. Anything else (negative, NaN, text) is ignored and a console warning says the previous value was kept. Values above 100 are clamped to 100.
- Each frame simulates at most half a second of game time, so on a 60 FPS screen speeds above roughly 30x will not go faster.
- A tab-out or long frame spike is clamped to 0.1 real seconds before the scale is applied.
- **It stays set** when you load or restart a scene. Set `time.scale = 1` yourself if the next scene should run at normal speed.
- Physics catch-up steps are capped, so extreme speeds trade accuracy for stability.
## Pause menu pattern
```
function onUpdate() {
if (input.keyPressed("Escape")) {
time.scale = time.scale === 0 ? 1 : 0;
}
// Menu animation that keeps running while frozen:
this.rotation += 90 * time.unscaledDeltaTime;
}
```
`scene.pause()` and `scene.resume()` are the other way to freeze gameplay; see [Global API](globals.html). Unlike `time.scale = 0` (where scripts keep running with `deltaTime = 0`), `scene.pause()` stops scripts including `onUpdate`, physics, animation and audio from the next frame until `scene.resume()`.
---
# Entity context
> Reference the `this` object and entity-aware shortcuts available in Realot Studio scripts.
## Core members
| Member | Meaning |
| --- | --- |
| x, y | World position; writes to physics position targets when a non-static Rigidbody2D exists. |
| position | Read/assign {x,y}. |
| rotation | Degrees. |
| scaleX, scaleY | Scale. |
| translate(dx,dy) | Move by a delta. |
| distanceTo(x,y) | Distance to a world point. |
| name | Read-only entity name. |
| tag | Read/write tag. |
| id | Stable unique ID. |
| visible | Show/hide entity. |
| enabled | Enable/disable the current script. |
| destroy() | Queue entity destruction. |
| destroyed | Read-only destruction state. |
| isClone | True for runtime-spawned clones. |
```
function onUpdate() {
this.translate(0, -50 * time.deltaTime); // move up
var target = findFirst("Target");
if (target && this.distanceTo(target.x, target.y) < 40) {
this.destroy();
}
}
```
## Component modules
Depending on attached components, `this` exposes modules including `transform`, `sprite`, `shape`, `text`, `speechBubble`, `chat`, `textInput`, `joystick`, `rigidbody`, `controller`, `animator`, `camera`, `audio`, `ear`, `collider`, `joint`, `navAgent`, `light`, `shadowCaster` and `strokePath`.
```
function onUpdate() {
if (this.hasComponent("Rigidbody2D")) {
this.rigidbody.addForce(0, -500);
}
this.sprite.opacity = this.isPointerOver ? 1 : 0.6;
}
```
## Timers belong to entities
Both `wait()` and `repeat()` are associated with the scheduling entity. When the entity is destroyed or a scene restarts/switches, its timers are automatically cancelled.
```
function onStart() {
this.wait(1.5, function () {
this.sprite.opacity = 1; // this is still the entity that scheduled the timer
});
}
```
## Pointer helpers
> **Collider requirement:** isPointerOver , isClicked , isTouchOver , isTapped and myTouch require Collider2D because hit testing uses the real collider shape.
---
# Entity shortcuts (this.x, this.transform)
> What this is inside a script, which properties are flat shortcuts, and which require a specific component.
## Flat shortcuts (always available)
Inside any lifecycle function, `this` is an EntityContext bound to the entity the script is attached to. A small set of properties are flat shortcuts directly onto the entity’s Transform, because Transform has only one shape. Everything else lives behind a sub-object gated by a specific component — see the full this reference for every sub-object.
| Shortcut | Meaning |
| --- | --- |
| this.x / this.y | Read/write live position. Writing immediately moves the entity, and correctly teleports the physics body too on a Dynamic or Kinematic Rigidbody2D rather than being silently overwritten by the next physics step. |
| this.position | {x, y}; assigning moves the entity. |
| this.translate(dx, dy) | Move by a delta this call. |
| this.rotation, this.scaleX, this.scaleY | Degrees and scale factors, matching the Inspector’s Transform fields. |
| this.visible, this.enabled | Show/hide and enable/disable the entity. |
```
function onUpdate() {
this.rotation += 90 * time.deltaTime; // spin
this.translate(0, -1); // drift upward one unit per frame
if (this.y < -50) this.visible = false;
}
```
## Identity & lifecycle helpers
| Helper | Meaning |
| --- | --- |
| this.destroy() | Queues the entity for removal (deferred, not instant). this.destroyed becomes true immediately even though removal has not happened yet. |
| this.hasComponent(key) | True if the entity currently has the named component. "Transform" always returns true. Works on any EntityContext, including one from find() or a collision callback’s other. |
| this.name, this.tag, this.id | Read-only name; read/write tag; stable unique ID. |
| this.isClone | True inside onClone()/onStart() for a runtime-spawned clone. |
```
function onUpdate() {
if (this.hp <= 0 && !this.destroyed) {
this.destroy();
}
}
function onStart() {
if (this.isClone) this.tag = "spawned"; // mark runtime clones differently
}
```
---
# Finding & spawning entities
> The find/findAll/findWithTag family, plus spawn() for runtime-instantiated clones.
## Finding entities
| API | Returns |
| --- | --- |
| findFirst(name) | First entity with this exact name, or null. |
| findAll(name) | Every entity with this name, as an array. |
| findFirstWithTag(tag) / findAllWithTag(tag) | Same pair, keyed by tag instead of name. |
| findById(id) | Never ambiguous — use the id from an earlier spawn() or find() call. |
| findInRadius(x, y, radius, opts) | Entities within radius world units of a point, nearest first. |
| entity.distanceTo(x, y) | Instance method on any EntityContext: distance from that entity to a point. |
## Spawning
`spawn(nameOrTag, opts)` spawns a runtime clone of an existing entity. Looks the source up by name by default:
```
spawn("Bullet");
spawn("Bullet", { x: this.x, y: this.y });
spawn("Enemy", { byTag: true, x: 200, y: 100 }); // look up by tag, clone the first match
```
Optionally rename the clone with `opts.name`. Returns an EntityContext for the new entity (same shape as `this`), or null if no source entity matches. The clone’s own `onClone()` then `onStart()` fire automatically on the next frame, with `this.isClone === true` inside them. Also available as an instance method, `this.spawn(nameOrTagOrEntity, opts)` — pass an EntityContext directly (e.g. `this.spawn(this)`) to clone that exact entity with zero name/tag ambiguity.
---
# Input
> Keyboard, mouse, touch, gestures and virtual joystick input in Realot Studio.
## Keyboard
`input.keyDown(code)` is true while a key is held. `input.keyPressed(code)` is a one-frame pulse. Browser-style codes include `ArrowLeft`, `ArrowRight`, `KeyA`, `Space` and the special code `Any`.
```
function onUpdate() {
var speed = 200 * time.deltaTime;
if (input.keyDown("ArrowRight") || input.keyDown("KeyD")) this.x += speed;
if (input.keyDown("ArrowLeft") || input.keyDown("KeyA")) this.x -= speed;
if (input.keyPressed("Space")) {
this.controller.simulateJump(); // one-frame pulse — fires once per press, not every frame held
}
}
```
## Mouse
| API | Semantics |
| --- | --- |
| mouse.x / mouse.y | World-space cursor position. |
| mouse.screenX / mouse.screenY | Raw canvas-pixel cursor position. |
| mouse.down(button) | Held button; 0 left, 1 middle, 2 right. |
| mouse.pressed(button) | Pressed this frame. |
| mouse.released(button) | Released this frame. |
| mouse.isOver(target) | Shape-accurate entity hit test. |
| mouse.clickedOn(target) | Hit test + pressed pulse. |
```
function onUpdate() {
if (mouse.clickedOn(this.name)) {
this.destroy(); // click this entity to pop it
}
// or, from inside the entity’s own script:
if (this.isClicked) {
this.sprite.opacity = 0.5;
}
}
```
## Touch
The global `touch` surface is array-like. Each active touch has `id`, world/screen coordinates, start coordinates, `dx`, `dy`, `distance`, `justStarted` and `justEnded`.
```
function onUpdate() {
for (var t of touch) {
if (t.justStarted) {
debug.log("Touch " + t.id, t.x + ", " + t.y);
}
}
if (touch.tappedOn(this.name)) {
this.spawn("Explosion", { x: this.x, y: this.y });
}
}
```
## Gestures
| Gesture | Properties |
| --- | --- |
| touch.swipe | active, direction, dx, dy, distance; active after >40 px movement. |
| touch.pinch | active, scale, delta, distance for two-finger gestures. |
```
function onUpdate() {
if (touch.swipe.active && touch.swipe.direction === "left") {
scene.load("NextLevel");
}
if (touch.pinch.active) {
this.camera.zoom *= touch.pinch.scale; // pinch-to-zoom
}
}
```
## Virtual joysticks
The Joystick component exposes normalized read-only `x`, `y`, `magnitude`, `angle` and `active` values. This works well with Car controllers and custom movement scripts.
```
// Script attached to an entity with a Joystick component:
function onUpdate() {
if (this.joystick.active) {
this.controller.simulateMove(this.joystick.x, this.joystick.y);
}
}
```
---
# Physics & navigation scripting
> Use Rigidbody2D, Collider2D, raycasts and NavWorld2D from game scripts.
## Physics raycasts
```
const hit = physics.raycast(this.x, this.y, target.x, target.y, {
exclude: [this],
layerMask: physics.layer(2, 3),
debug: true
});
if (hit) {
debug.log("Hit", hit.entity.name);
}
```
## Raycast results
A hit returns `{ entity, point, normal, distance }`. The entity is a live script context; point and normal are world-space vectors. Triggers are skipped by raycasts.
## Navigation
```
const path = nav.findPath(this.x, this.y, target.x, target.y, {
radius: this.navAgent.radius,
debug: true
});
```
## One-line agent steering
Entities with NavAgent2D gain `navMoveToward(targetX,targetY,speed,opts)`. Car + NavAgent entities additionally gain `navDriveToward()` for path-following, avoidance and car steering/drift behavior.
## Physics body choice
Choose the body type based on ownership of movement: Dynamic for solver-driven motion, Kinematic for script/controller-driven collision-resolved movement, Static for fixed geometry.
---
# Collisions & triggers
> onCollisionEnter/Stay/Exit, onTriggerEnter/Exit, the other parameter, and physics layers from script.
## Requirements
Collision and trigger callbacks need a Collider2D on the entity receiving the callback (a Rigidbody2D is not strictly required — a collider with no rigidbody is treated as static, matching how Unity handles a collider-only object).
## The other parameter
`other` in every collision/trigger callback is an EntityContext — the exact same shape as `this`. You can read `other.x`, `other.name`, call `other.hasComponent(...)`, or even `other.destroy()`.
## Enter vs. Stay vs. Exit
```
function onCollisionEnter(other) {
if (other.name === "Ground") this.isGrounded = true;
}
function onCollisionExit(other) {
if (other.name === "Ground") this.isGrounded = false;
}
```
`onCollisionStay(other)` fires every physics step the collider remains touching — from the step after Enter, up to (not including) the step Exit fires. Use Stay sparingly for continuous effects (e.g. damage-over-time while standing in a hazard); use Enter/Exit for one-shot state changes.
## Triggers
A collider with `isTrigger: true` detects overlap without physically blocking movement, and fires `onTriggerEnter`/`onTriggerExit` instead of the collision events:
```
function onTriggerEnter(other) {
if (other.hasComponent("Rigidbody2D")) {
scene.load("Level2");
}
}
```
## Physics layers
Collider2D’s `layer`/`mask` fields (16 named layers, same slot-based model as Unity) control which pairs of colliders physically interact and receive callbacks at all. Two colliders only interact if each one’s membership layer is included in the other’s mask — see Collider2D for the full bitmask reference and `physics.layer(...)` for building a mask from script.
---
# Pathfinding & NavWorld2D
> navMoveToward, nav.findPath, named areas and per-area cost, and multi-agent avoidance.
## What navigation is in Realot Studio
Realot Studio navigation is a shared 2D grid system. A scene normally contains one NavWorld2D, while NavAgent2D components query that world using agent-specific radius, area restrictions, costs, path refresh timing, and avoidance settings.
> **Need the whole workflow?:** Read Navigation: complete setup for the complete editor + scripting + tuning flow.
## Quickest working path
```
function onUpdate(dt) {
var target = findFirst("Target");
if (target) this.navMoveToward(target.x, target.y, 120);
}
```
This requires a NavWorld2D in the scene and, for useful per-agent clearance/settings, a NavAgent2D on the moving entity.
## Manual path query
```
var path = nav.findPath(this.x, this.y, 800, 300, {
radius: 16,
area: nav.areaMask("Ground", "Road"),
areaCosts: nav.areaCosts({ Mud: 4, Road: 1 }),
debug: true
});
```
The result is an array of world-space `{x,y}` waypoints or `null` when no route is available.
## Cars
For a Car-type CharacterController with NavAgent2D, use `this.navDriveToward(targetX, targetY, speed, opts)`. It adds vehicle-oriented braking, steering, lookahead, and recovery behavior rather than pretending a car is a walking agent.
## Area rules worth remembering
| Tool | Use it for |
| --- | --- |
| `nav.areaMask("Road", "Ground")` | Hard permission: route may only cross named areas in the mask. |
| `nav.areaCosts({ Road: 1, Mud: 4 })` | Soft preference: both areas remain legal, but Mud becomes more expensive. |
| `NavAgent2D.radius` | Per-agent clearance; larger agents can be blocked by corridors smaller agents can use. |
---
# Navigation: complete setup
> Build, paint, name, script, tune, debug, and ship a complete Realot Studio navigation setup without skipping the hard parts.
## The complete model: five pieces, one pipeline
Realot Studio navigation is easiest to understand as a pipeline rather than as one button. A scene normally has **one shared NavWorld2D**; the NavWorld stores the base walkability grid, each NavAgent2D supplies per-agent size/restrictions, and script movement consumes the resulting path.
Static Collider2D geometry→NavWorld2D bake / paint→Area mask + costs→Agent radius→A\* path→Agent steering / avoidance
> **Important distinction:** The navigation grid answers “which route is possible?” while avoidance answers “how should this agent steer around nearby agents/obstacles?” Do not try to solve both by constantly rebaking the world.
## End-to-end setup: from empty scene to moving NPC
### Goal: make one NPC walk around walls to the target
1
**Create the navigation world.** In the editor top menu, open GameObject → 2D Object → Nav World 2D. Select the new Nav World 2D entity in the Hierarchy; its fields appear in the right-side Inspector under **Nav World 2D**.
2
**Set the navigation rectangle.** In the Inspector, edit `Bounds X`, `Bounds Y`, `Bounds Width`, and `Bounds Height`. The bounds define the grid region; they do not move the entity's Transform by themselves.
3
**Choose Cell Size.** Smaller values give finer obstacle detail but create more cells. Start around `32` world units, then reduce it only when a corridor or obstacle genuinely needs more resolution.
4
**Make walls real navigation obstacles.** Give the walls a **Collider2D** and, for baked/static geometry, leave the Rigidbody absent or Static. Triggers and Dynamic/Kinematic rigidbodies are not treated as baked obstacles.
5
**Bake.** In the selected Nav World 2D Inspector use **Bake Nav World** after the static geometry is ready. The runtime API equivalent is `nav.bake()`. Most games bake in the editor once.
6
**Inspect the result.** When a Nav World exists, the top-center editor toolbar gains the navigation tools. Use the Bounds view to see the overall rectangle cheaply, then the Cells view for detailed walkability.
7
**Manually fix special cells.** Press U for the Walkable brush, I for the Blocked brush, and O for the Area brush. Normal click paints; **Alt+click** clears that override. The `−`/`+` brush buttons beside the nav display controls reduce/increase the brush radius.
8
**Add the agent.** Select the NPC in the Hierarchy and use Inspector → Add Component → Nav Agent 2D. Start with `Radius 16`, `Speed 120`, `Auto Repath ON`, and the default area mask.
9
**Attach the movement script.** On the NPC's Script component, use the following minimal loop:
```
function onUpdate(dt) {
var target = findFirst("Target");
if (!target) return;
this.navMoveToward(target.x, target.y, 120, {
repathInterval: 0.25,
finalArriveDist: 12,
debug: true
});
}
```
> **What should happen:** The NPC requests a path, advances through the returned waypoints, periodically rechecks the target, and stops inside the final arrival radius. The green debug path appears for a frame when debug:true is used and the debug overlay is visible.
## Every navigation editor control, in context
| Control | Where it appears | What it does | Increase / decrease behavior |
| --- | --- | --- | --- |
| `Nav World 2D` | GameObject → 2D Object → Nav World 2D | Adds the shared navigation grid component/entity. | One shared world per scene is the normal design. |
| `Bounds X / Y` | Right Inspector → Nav World 2D | Moves the grid rectangle relative to the Nav World entity. | Larger positive/negative values shift the grid rectangle; they do not resize it. |
| `Bounds W / H` | Right Inspector → Nav World 2D | Controls navigation coverage. | Larger = larger navigable region and more cells; smaller = less coverage. |
| `Cell Size` | Right Inspector → Nav World 2D | Controls grid resolution. | Smaller = more precise/narrower features represented, more cells/work. Larger = cheaper, but narrow geometry may disappear into one cell. |
| `Bake Nav World` | Right Inspector → Nav World 2D | Reads eligible Collider2D geometry and produces the base walkability grid. | Run after changing static obstacles unless Dynamic mode is being used. |
| `Dynamic` | Right Inspector → Nav World 2D | Enables automatic rebaking when bake-relevant static geometry changes. | ON = convenience for runtime-changing static-like geometry; OFF = avoid rebake work for mostly-static levels. |
| `Allow Diagonal` | Right Inspector → Nav World 2D | Controls whether A\* may use diagonal grid neighbors. | OFF = 4-neighbor grid; ON = diagonals become valid route steps. |
| `U` Walkable | Top editor toolbar; only after Nav World 2D exists | Paints an explicit walkable override. | Brush size is controlled by the nearby `−`/`+` buttons. |
| `I` Blocked | Top editor toolbar; only after Nav World 2D exists | Paints an explicit blocked override. | Same brush-size controls and Alt+click erase behavior. |
| `O` Area | Top editor toolbar; only after Nav World 2D exists | Paints the selected navigation area onto cells. | Area choice appears beside the brush only while Area mode is active. |
| `Edit → Nav Areas…` | Top editor menu Edit | Names the 16 navigation area slots. | Names are used later by `nav.areaMask()` and `nav.areaCosts()`. |
| `Bounds / Cells` view buttons | Top toolbar beside nav tools | Switches between cheap bounds visualization and detailed cell visualization. | Cells view is the one to use when diagnosing exact painted/baked coverage. |
## Named areas: hard restrictions vs soft preferences
Realot Studio exposes 16 navigation-area slots. Name them with Edit → Nav Areas…, then use the names in script instead of memorizing bit positions.
### Hard restriction: Area Mask
```
var allowed = nav.areaMask("Ground", "Road");
var path = nav.findPath(this.x, this.y, 800, 300, {
area: allowed,
radius: 16
});
```
An area omitted from the mask is **impassable for that query**. This is different from cost.
### Soft preference: Area Cost
```
var path = nav.findPath(this.x, this.y, 800, 300, {
area: nav.areaMask("Ground", "Road", "Mud"),
areaCosts: nav.areaCosts({
Road: 0.5,
Mud: 4
})
});
```
Cost changes route preference among allowed areas. A cost of `1` is neutral; a higher value makes that area more expensive; a lower positive value makes it more attractive. Cost does not turn an allowed area into a hard wall.
> **Common mistake:** Do not use areaCosts: { Water: 0 } to try to block water. Use nav.areaMask(...) and leave Water out of the mask.
## NavAgent2D tuning: what every major value actually changes
| Field | Increase it | Decrease it | Use it when… |
| --- | --- | --- | --- |
| `radius` | Agent needs wider clearance; narrow passages become unavailable sooner. | Agent can fit through tighter passages. | Different NPC sizes need to share the same NavWorld. |
| `speed` | Higher top movement speed. | Slower movement. | Simple traversal pacing. |
| `acceleration` | Reaches the requested speed faster. | Softer/slower speed changes. | Making movement feel snappy vs floaty. |
| `deceleration` | Stops more quickly. | Longer, softer stopping. | Preventing overshoot near goals. |
| `stoppingDistance` | Agent intentionally stops farther away. | Agent gets closer to target. | Enemies should keep melee/shooting distance. |
| `repathInterval` | Fewer route checks; cheaper. | More frequent route checks; more responsive and more expensive. | Balancing moving-target responsiveness vs CPU work. |
| `repathDistance` | Target must move farther before a re-path is triggered. | Target motion triggers re-path sooner. | Fast-moving targets. |
| `avoidancePriority` | Higher priority means the agent is treated as more important in avoidance decisions. | Lower priority makes it more willing to yield. | Mixed-priority crowds or special NPCs. |
| `area` | Add area bits to permit additional terrain categories. | Remove bits to forbid categories. | Making a route legally impossible through a terrain class. |
## Complete car / road navigation flow
Vehicle navigation is not simply “walk an NPC path with a car sprite.” Realot Studio exposes `this.navDriveToward()` specifically for Car-type CharacterController movement and the NavAgent2D vehicle tuning fields.
1
Make the road surface part of the NavWorld and name it, for example, `Road`. Use another area such as `Ground` for ordinary terrain.
2
Add **Nav Agent 2D** to the car. Set `collabEnabled` or avoidance only when you actually need those behaviors.
3
Use `nav.areaMask("Road")` when the car must stay on roads. Use a wider mask if road-only routing is too restrictive.
4
Drive toward the destination:
```
function onUpdate(dt) {
var target = findFirst("Destination");
if (!target) return;
this.navDriveToward(target.x, target.y, 220, {
repathInterval: 0.2,
arriveDist: 8,
finalArriveDist: 18,
debug: true
});
}
```
For road-vs-ground preference, allow both and use costs instead of a hard mask:
```
var path = nav.findPath(this.x, this.y, target.x, target.y, {
area: nav.areaMask("Road", "Ground"),
areaCosts: nav.areaCosts({ Ground: 3, Road: 1 })
});
```
> **Tuning order for vehicles:** First make the NavWorld route correct. Then tune agent radius. Then tune speed/acceleration/deceleration. Only after that adjust the vehicle lookahead/smoothing/braking fields. This separates route problems from steering problems.
## When to use Dynamic
Turn on **Dynamic** only when bake-relevant static geometry can actually change during play. The runtime checks a cheap collider signature and rebakes when the signature changes; it does not blindly rebake the entire world every frame. Dynamic navigation still has a real rebake cost when qualifying geometry changes.
```
// Procedural level example: after spawning a new static obstacle
var result = nav.bake();
if (result) debug.log("Nav rebuilt: " + result.walkable + " walkable, " + result.blocked + " blocked");
```
## Navigation debugging checklist
**1.** Is a Nav World 2D actually present in the scene?
**2.** Are the walls using Collider2D and eligible for baking?
**3.** Did you bake after editing static geometry?
**4.** Does Cells view show the corridor as walkable?
**5.** Is the agent radius too large for that corridor?
**6.** Is the Area Mask accidentally excluding the only available route?
**7.** Are you confusing area cost with a hard restriction?
**8.** Is your target inside the NavWorld bounds or at least near a walkable cell?
**9.** Is the script calling the correct method for the movement type (`navMoveToward` vs `navDriveToward`)?
**10.** Turn on `debug:true` and make the debug overlay visible to inspect the actual route.
## LLM/code-generation rule
When generating navigation code, preserve this dependency order: **NavWorld2D → walkability/bake → named areas → NavAgent2D → script movement → tuning**. Do not invent properties such as `destination`, `setDestination`, or a Unity/Godot class when Realot Studio's documented API is `this.navMoveToward()`, `nav.findPath()`, and `this.navAgent.*`.
---
# State & messaging
> Build lightweight state machines and decoupled entity communication.
## State machine
Every entity gets `this.state` without a dedicated component. `current` starts as `"default"`; `previous` is the state before the last transition. `change(name)` is a no-op when the name is already current.
## State callbacks
```
function onStateEnter() {
if (this.state.current === "chasing") {
this.animator.play("Run");
}
}
function onStateUpdate(dt) {
if (this.state.current === "chasing") {
// chase logic
}
}
```
## Messages
```
function onStart() {
sendMessage("Enemy", "takeDamage", { amount: 10 });
}
function onMessage(message, data) {
if (message === "takeDamage") {
this.hp -= data.amount;
}
}
```
## When to use messages
Messaging is useful when entities should react to an event without knowing another entity’s exact implementation. Use `findById`/`sendMessage(entity,...)` when you need one exact target; use a tag when you intentionally want a group.
---
# Timers, state & messaging
> wait()/repeat() timers, the built-in this.state machine, and sendMessage/broadcastMessage.
## Timers
Timers run on game time, so [`time.scale`](time-scale.html) speeds them up, slows them down or freezes them. To animate a property over time use [`tween()`](tween.html) instead of hand-written timers.
| API | Meaning |
| --- | --- |
| wait(seconds, callback) | Runs callback once after seconds of game time. this inside the callback is the same entity that called wait(). Returns a timer id for cancelWait(id). Also available as this.wait(...). |
| repeat(seconds, callback) | Runs callback every seconds, forever, until cancelled, the entity is destroyed, or the scene restarts/switches. The first call happens seconds from now, then every seconds after. |
| cancelWait(id) / cancelRepeat(id) | Stop a pending timer before it fires. Safe to call with an id that already fired or was already cancelled. |
> **Timers are entity-owned:** Timers are automatically cancelled if their entity is destroyed, or if the scene restarts/switches before they fire — a wait() never fires "late" against a scene that’s already gone.
## State machine
`this.state` needs no component — it works on every entity automatically. `this.state.current`/`this.state.previous` give the current/previous state name (current defaults to `"default"`). `this.state.change(name)` fires `onStateExit()` for the outgoing state, then `onStateEnter()` for the new one.
```
function onUpdate() {
if (this.isGrounded && this.state.current !== "idle") {
this.state.change("idle");
}
}
function onStateEnter() {
if (this.state.current === "idle") this.animator.play("Idle");
if (this.state.previous === "jump") debug.log("Landed!", "");
}
```
## Messaging
`sendMessage(tagOrEntity, message, data)` accepts either a tag string (messages every entity with that tag — a group broadcast) or an EntityContext directly (messages that one exact entity, unambiguous even if others share its name/tag). `broadcastMessage(message, data)` sends to every scene entity.
```
function onCollisionEnter(other) {
sendMessage("Enemy", "targetNearby", { x: this.x, y: this.y });
}
function onMessage(message, sender, data) {
if (message === "targetNearby") {
this.navMoveToward(data.x, data.y, 80);
}
}
```
---
# Persistence
> Use transient global state and durable IndexedDB saves.
## global vs save
| Surface | Lifetime |
| --- | --- |
| global | Transient cross-script state for the current play session/page. Refreshing the page clears it. |
| save | Persistent per-slot key/value storage backed by IndexedDB. Survives refresh/reopen when browser storage is available. |
## Basic save API
```
save.set("score", 1250);
const score = save.get("score");
if (!save.has("tutorialSeen")) {
save.set("tutorialSeen", true);
}
```
## Multiple save slots
```
await save.load("slot2");
const hp = save.get("targetHp");
const slots = await save.listSlots();
```
## Flush before a transition
```
async function onGameComplete() {
save.set("completed", true);
await save.flushNow();
scene.load("Credits");
}
```
## Storage errors
`save.set()` updates the in-memory value synchronously while IndexedDB writes happen in the background. Register `save.onError(fn)` to observe persistent-storage failures such as quota errors or unavailable IndexedDB implementations.
---
# Save data
> The save global: get/set/delete, save slots, and flushing writes.
## Overview
`save` is a global backed by IndexedDB — the way to make a game remember things across page refreshes and browser restarts, unlike `global` (see Timers, state & messaging), which resets on every reload.
## Basic reads and writes
```
save.set("highScore", 4200);
var best = save.get("highScore") ?? 0;
save.has("checkpoint");
save.delete("temporaryBuff");
save.keys(); // every key currently stored
save.clear(); // wipe the current slot
```
## Save slots
```
await save.load("slot2"); // switch to a different save file
save.slot; // the currently active slot name
save.listSlots();
save.deleteSlot("slot3");
```
## Flushing & readiness
`save.isReady` reflects whether the store has finished its initial load from IndexedDB. Writes are coalesced and flushed asynchronously; call `save.flushNow()` if you need a write to be durably committed before doing something else (e.g. right before `scene.load()` on a level transition). `save.onError(callback)` registers a handler for storage failures (e.g. a full or blocked IndexedDB).
## Example: persistent high score
```
function onDestroy() {
var best = save.get("highScore") ?? 0;
if (global.score > best) save.set("highScore", global.score);
}
```
---
# Errors & debugging
> How script errors are classified and reported, and the on-screen debug HUD.
## How errors are reported
A thrown error inside one lifecycle call is caught right there and reported to the editor Console — it does not disable the whole script (except `onStart`, which only ever runs once). Identical errors repeating every frame are throttled: reported immediately once, then suppressed and periodically summarized with a repeat count, so a bug in `onUpdate` doesn’t spam the console 60 times a second.
## Error kinds
Errors thrown by the scripting API are tagged with a machine-readable `kind` so the Console can show a specific, actionable message instead of a generic "X is not a function":
| Kind | Meaning | Example |
| --- | --- | --- |
| missing-component | Accessed this.rigidbody/.sprite/etc. but the entity does not have that component at all. | this.sprite.opacity on an entity with no Sprite Renderer |
| unsupported-body-type | Called a member that does not apply to this entity’s current body/controller type. | this.rigidbody.addForce() on a Kinematic or Static body |
| unknown-api | A property or method that does not exist at all — almost always a typo. | this.rigidbody.addFrce() |
| script-error | Anything without a kind — a plain script bug (null dereference, bad logic, etc). | — |
Every `unknown-api` error also lists the valid member names for that sub-object, so a typo is a one-line fix rather than a trip back to this documentation.
## The on-screen debug HUD
```
debug.show(); // turn the HUD on (visible in the Play window, not the editor console)
debug.showFps(false); // keep the HUD on but hide just the FPS line
debug.log("Target HP", this.hp);
debug.clear("Target HP");
debug.clearAll();
```
---
# Script API cookbook
> Concrete Realot Studio script examples with setup, placement, required components, options, expected behavior, and common mistakes.
## How to use the cookbook
Every example assumes a **Script** component exists on the entity that owns the code. In the editor, select the entity in the left Hierarchy, then use the right Inspector to open its **Script** component. Paste the example into the script's lifecycle function or adapt it to your existing script.
> **Read API reference + recipe together:** The API reference tells you what a function/property means. The recipes show when to call it, what object should own the script, and what other setup the feature needs.
## 1. Find an entity and move toward it
### Setup
Create an entity named `Target`. Put this script on the enemy.
### Code
```
function onUpdate(dt) {
var target = findFirst("Target");
if (!target) return;
this.navMoveToward(target.x, target.y, 140);
}
```
`findFirst(name)` returns one matching entity or `null`. `navMoveToward()` supplies the navigation movement behavior.
## 2. Spawn a runtime clone
Author a source entity in the scene first, for example an entity named `Bullet`. The script below can live on a target, weapon, or spawner.
```
var bullet = spawn("Bullet", {
x: this.x + 24,
y: this.y,
name: "Bullet_Instance"
});
if (bullet) {
bullet.velocityX = 500;
}
```
> **Why the source entity matters:** spawn() clones an existing authored entity. It is not a constructor that invents a new component set from scratch.
## 3. Raycast toward an entity
Put this on the entity performing the vision/sensor check.
```
function onUpdate(dt) {
var target = findFirst("Target");
if (!target) return;
var hit = physics.raycast(this.x, this.y, target.x, target.y, {
layerMask: 1 << 0,
exclude: [this],
debug: true
});
this.hasLineOfSight = !hit || hit.entity === target;
}
```
The result is either a hit object containing `entity`, `point`, `normal`, and `distance`, or a falsy result when nothing is hit.
## 4. Send an event without hard-coding the receiver's logic
```
// Sender
var enemy = findFirst("Enemy");
if (enemy) sendMessage(enemy, "takeDamage", { amount: 25 });
// Receiver
function onMessage(message, sender, data) {
if (message === "takeDamage") {
this.hp -= data.amount;
}
}
```
Use an EntityContext when you need exactly one receiver. Use a tag string when you intentionally want a group to receive the same message.
## 5. Keyboard movement with frame-independent speed
```
function onUpdate(dt) {
var dx = 0;
var dy = 0;
if (input.keyDown("ArrowLeft")) dx -= 1;
if (input.keyDown("ArrowRight")) dx += 1;
if (input.keyDown("ArrowUp")) dy -= 1;
if (input.keyDown("ArrowDown")) dy += 1;
var length = Math.hypot(dx, dy);
if (length > 0) {
dx /= length;
dy /= length;
this.x += dx * 220 * dt;
this.y += dy * 220 * dt;
}
}
```
This is useful for simple non-physics entities. Use Rigidbody2D/CharacterController APIs when movement is supposed to participate in physics/controller resolution.
## 6. Delay work without hand-written countdown variables
```
function onStart() {
this.wait(1.5, function () {
this.sprite.opacity = 0.4;
});
this.repeat(2, function () {
debug.log("heartbeat");
});
}
```
Entity-owned timers are automatically cancelled when the scheduling entity is destroyed or the scene changes.
## 7. Persistent save data
```
function onStart() {
this.hp = save.get("targetHp") ?? 100;
}
function onCheckpointReached() {
save.set("targetHp", this.hp);
save.set("checkpoint", { x: this.x, y: this.y });
}
async function onGameComplete() {
save.set("completed", true);
await save.flushNow();
scene.load("Credits");
}
```
> **Important:** save.set() updates the in-memory save immediately. Use await save.flushNow() when the next action must wait for durable storage before continuing.
## 8. Ask the navigation system for a path
```
var path = nav.findPath(this.x, this.y, goalX, goalY, {
radius: this.navAgent.radius,
area: nav.areaMask("Ground", "Road"),
areaCosts: nav.areaCosts({ Road: 1, Mud: 4 }),
debug: true
});
if (path) {
debug.log("Waypoints: " + path.length);
}
```
This example demonstrates four separate concepts: agent clearance, hard area permission, soft area preference, and debug visualization.
## 9. Change a NavAgent2D at runtime
Select the moving entity and add **Nav Agent 2D** in Inspector → Add Component → Nav Agent 2D. The exposed script properties are read/write.
```
this.navAgent.speed = 180;
this.navAgent.radius = 12;
this.navAgent.avoidanceEnabled = true;
this.navAgent.repathInterval = 0.2;
// Read-only current route state:
var path = this.navAgent.currentPath;
var index = this.navAgent.currentPathIndex;
```
> **Read-only fields:** currentPath and currentPathIndex are managed by navMoveToward() . Do not assign to them; call this.navMoveToward(newX,newY,...) to change the destination.
## 10. Use named navigation areas instead of raw bitmasks
First name the slots in Edit → Nav Areas…. For example: `Ground`, `Road`, `Mud`, `Water`.
```
var roadOnly = nav.areaMask("Road");
var mixed = nav.areaMask("Road", "Ground");
var waterSlot = nav.areaIndex("Water");
```
This keeps scripts readable and means you do not have to remember which slot number was assigned to each named area.
## 11. Camera follow
```
function onUpdate(dt) {
var target = findFirst("Target");
if (target) {
this.camera.follow(target, { smoothing: 0.1 });
}
}
```
Put the script on the entity that has the Camera component. The engine template also demonstrates this pattern.
## 12. Switch animations from gameplay state
```
function onUpdate(dt) {
if (!this.rigidbody) return;
if (!this.rigidbody.grounded) {
if (this.rigidbody.velocityY > 0) this.animator.play("fall");
else this.animator.play("Jump");
} else if (Math.abs(this.rigidbody.velocityX) > 5) {
this.animator.play("Run");
} else {
this.animator.play("Idle");
}
}
```
## 13. Touch / joystick control
For a Joystick component, select an entity, then use Inspector → Add Component → Joystick. The script can read normalized values:
```
function onUpdate(dt) {
if (!this.joystick || !this.joystick.active) return;
this.controller.simulateMove(this.joystick.x, this.joystick.y);
}
```
`x` and `y` are normalized joystick axes; `magnitude` tells you how far the thumb is displaced.
## 14. Trigger a scene change on overlap
Give the portal entity a **Collider2D** and enable its **Is Trigger** checkbox in the right Inspector.
```
function onTriggerEnter(other) {
if (other.name === "Target") {
scene.load("Level2");
}
}
```
Trigger callbacks depend on Collider2D overlap. A trigger does not behave like a solid blocking collider.
## 15. Build your own tiny diagnostic HUD
```
function onUpdate(dt) {
debug.log(
"pos=" + Math.round(this.x) + "," + Math.round(this.y) +
" speed=" + Math.round(this.navAgent ? this.navAgent.speed : 0)
);
}
```
Use this while developing, then remove or gate noisy logging before a final release.
## Patterns that scale well
| Need | Prefer | Avoid |
| --- | --- | --- |
| Exact entity | `findById()` or a known EntityContext | Assuming a shared name is unique when it is not. |
| Group communication | Tag + `sendMessage()` | Duplicating the same lookup in every receiver. |
| Persistent data | `save.*` | Using `global.*` for data that must survive reload. |
| Pathfinding | One NavWorld2D + NavAgent2D per mover | Creating a navigation world per NPC. |
| Physics movement | Rigidbody2D / CharacterController APIs | Directly changing `x/y` when you need collision resolution. |
| Frame-independent custom movement | Multiply speed by `dt` | Using a raw pixels-per-frame constant. |
## Where to go next
### Complete Navigation
[Full editor-to-runtime navigation setup, areas, costs, vehicles and debugging.](./navigation-complete.html)
### Option schemas
[Exact `opts` objects, defaults, types and override rules.](../api/options.html)
### Component reference
[Every component and its editor/runtime contract.](../api/index.html)
---
# API reference
> Complete Realot Studio component, script-module and runtime API reference.
> **Start with prerequisites:** The API requirements & complete usage map shows which components or scene systems must exist before an API can be used.
## Components
The editor's component system contains 25 documented component types. Each component page lists its public scene fields, defaults, field descriptions, and the script API members exposed when that component is attached.
[**Transform**Position, rotation and scale.](components/transform.html)
[**SpriteRenderer**Texture, color, flips and opacity.](components/spriterenderer.html)
[**ShapeRenderer**Procedural square, circle, capsule and triangle shapes.](components/shaperenderer.html)
[**TextRenderer**World-space and screen-space text.](components/textrenderer.html)
[**StrokePath**Editable variable-width lines and textured paths.](components/strokepath.html)
[**SpeechBubble**Entity-attached dialogue bubble.](components/speechbubble.html)
[**ChatLog**Scrollable message history.](components/chatlog.html)
[**TextInput**Interactive text entry.](components/textinput.html)
[**Joystick**Virtual touch joystick.](components/joystick.html)
[**Rigidbody2D**Static, Dynamic and Kinematic physics body.](components/rigidbody2d.html)
[**Collider2D**Collision shape, triggers and layer filters.](components/collider2d.html)
[**Joint2D**Fixed, Revolute, Prismatic, Rope and Spring joints.](components/joint2d.html)
[**CharacterController**Character, Platformer, Top-Down, Car, Follow, Patrol and Free movement modes.](components/charactercontroller.html)
[**SpriteAnimation**Sprite-sheet clips and animation state.](components/spriteanimation.html)
[**Camera**Reference resolution, scaling, follow, shake and pseudo-3D.](components/camera.html)
[**AudioSource**Playback, pitch, volume and spatial attenuation.](components/audiosource.html)
[**AudioListener**Hearing radius and audio detection.](components/audiolistener.html)
[**Light**Six 2D light modes.](components/light.html)
[**ShadowCaster**Shadow occlusion geometry and softness.](components/shadowcaster.html)
[**LightingSettings**Scene-wide ambient and shadow quality settings.](components/lightingsettings.html)
[**NavAgent2D**Pathfinding, area filters, avoidance and vehicle tuning.](components/navagent2d.html)
[**NavWorld2D**Shared painted or baked navigation grid.](components/navworld2d.html)
[**Tileset**Reusable 16-role autotile setup.](components/tileset.html)
[**Tilemap**Painted tile grid linked to a Tileset.](components/tilemap.html)
[**Script**Script name, source and enabled state.](components/script.html)
## Complete script-module index
The [Script module member index](script-modules.html) is generated from the engine's supported-member sets. It covers every member exposed by the `this.*` component modules, plus `this.state`, `this.myTouch`, `scene.lighting` and the global `save` API. Each entry includes its access type, context and source file.
## Global runtime API
Scripts also receive global functions and objects such as `findFirst()`, `scene`, `physics`, `nav`, `input`, `mouse`, `touch`, `time`, `random`, `mathx`, `save`, `debug` and `pool`. See [Runtime modules](runtime.html) and the practical [Global API guide](../scripting/globals.html).
## Option shapes and requirements
Optional arguments for raycasts, spawning, navigation, camera follow and other script calls are documented in [Option schemas (opts)](options.html). The [requirements map](requirements.html) identifies component prerequisites and always-available APIs.
## Machine-readable catalog
For code tools and AI assistants, fetch [`api/index.json`](../../api/index.json). It contains component field/default metadata, lifecycle callbacks, enum values, global API groups, all 24 script API modules and their supported member lists. The full manual is available from [`llms-full.txt`](../../llms-full.txt); the search index is [`search-index.json`](../../search-index.json).
---
# Runtime modules and global API
> Index of global functions and objects supplied to gameplay scripts in Realot Studio.
## Entity lookup functions
`findFirst(name)`, `findAll(name)`, `findFirstWithTag(tag)`, `findAllWithTag(tag)`, `findWithTag(tag)`, `findById(id)` and `findInRadius(x, y, radius, opts?)` locate entities in the current scene.
## Scene, physics and navigation
| Object | Exposed surface |
| --- | --- |
| `scene` | Entity lookup; `load`, `restart`, `pause`, `resume`; read-only `current` and `isPaused`; scene-wide `lighting`. |
| `physics` | `raycast(x1, y1, x2, y2, opts?)`, `layer(...indices)`. |
| `nav` | `findPath`, `isWalkable`, `bake`, `areaIndex`, `areaMask`, `areaCosts`. |
## Input, time and math
| Object | Exposed surface |
| --- | --- |
| `input` | `keyDown(key)`, `keyPressed(key)`. |
| `mouse` | World/screen coordinates, cursor state, button state, `isOver`, `clickedOn`. |
| `touch` | Active touch list, per-touch positions and state, swipe/pinch helpers, `isOver`, `tappedOn`. |
| `time` | `deltaTime`, `unscaledDeltaTime`, `elapsed`, `scale`. |
| `random` | `int(min, max)`, `float(min, max)`. |
| `mathx` | `lerp`, `smoothstep`, `clamp`, `moveToward`, `remap`, `approximately`. |
| `smoothstep(a, b, value)` | Global smoothstep helper also available without `mathx.`. |
## Game services
| Object / function | Purpose |
| --- | --- |
| `global` | Shared in-memory key/value state between scripts during the running game. |
| `save` | Persistent key/value data and named save slots backed by IndexedDB; exact members are in [SaveAPI](script-modules.html#saveapi). |
| `debug` | Play-window diagnostic HUD, FPS line and custom values. |
| `pool` | Named object pools for reusing entities. |
| `spawn(nameOrTag, opts?)` | Creates a runtime clone. |
| `wait`, `repeat`, `cancelWait`, `cancelRepeat` | Entity-owned one-shot and repeating timers. |
| `sendMessage`, `broadcastMessage` | Targeted, tag-group or scene-wide script messaging. |
| `tween`, `cancelTween` | Property animation over game time. |
## Detailed global API guide
The [Global scripting API](../scripting/globals.html) explains each object with examples. Use [Input](../scripting/input.html), [Persistence](../scripting/persistence.html), [Pathfinding](../scripting/navigation.html) and [Tween API](../scripting/tween.html) for focused guides.
## Per-entity component modules
Component modules such as `this.rigidbody`, `this.sprite`, `this.camera` and `this.text` depend on the components attached to the entity. The [complete script module index](script-modules.html) lists every supported member from all 24 script API modules, its access type and required context. The [`this` reference](this.html) explains EntityContext shortcuts and prerequisites.
## Fixed update
`onFixedUpdate(dt)` runs on the fixed physics cadence (60 steps per second in the supplied runtime). Use it for logic that should follow fixed-step physics timing; use `onUpdate(dt)` for frame-based presentation and input handling.
## Coordinate spaces
Entity positions, `mouse.x/y`, touch `x/y`, raycast points and navigation waypoints use world-space coordinates. Mouse/touch `screenX/screenY` values are raw game-canvas pixels. Camera reference resolution and world units are separate concepts.
---
# Complete script module member index
> Complete source-verified member list for every script API module exposed by Realot Studio, including global utility modules and entity component APIs.
This is the complete member-name index for the script modules exposed by the supplied engine source. The allow-list in each module is the authority: entries not listed here are not part of that module’s supported script surface. Use the matching component page for full field meanings and examples.
## AnimatorAPI
**Access:** `this.animator`. **Requirement:** SpriteAnimation component. **Source:** `project/runtime/scripting/components/AnimatorAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `currentClip` | Read-only property | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `currentFrame` | Read/write property | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `play(clipName)` | Method | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `playing` | Read-only property | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `speed` | Read/write property | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stop()` | Method | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `totalFrames` | Read-only property | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## AudioAPI
**Access:** `this.audio`. **Requirement:** AudioSource component. **Source:** `project/runtime/scripting/components/AudioAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `pitch` | Read/write property | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `play()` | Method | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `playOnce()` | Method | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `playing` | Read-only property | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stop()` | Method | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `volume` | Read/write property | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## AudioListenerAPI
**Access:** `this.ear`. **Requirement:** AudioListener component. **Source:** `project/runtime/scripting/components/AudioListenerAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `canHear(nameOrTag, opts)` | Method | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
| `enabled` | Read/write property | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
| `radius` | Read/write property | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
| `sourcesInRange` | Read-only property | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
## CameraAPI
**Access:** `this.camera`. **Requirement:** Camera component. **Source:** `project/runtime/scripting/components/CameraAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `allowStretching` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `aspectMode` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `aspectRatioLock` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `backgroundColor` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `barColor` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `customHeight` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `customWidth` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `enablePseudo3D` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `follow(entityTarget, opts)` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `integerScaling` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `keepHeight` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `landscapeHeight` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `landscapeWidth` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `letterboxing` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetX` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetY` | Read/write property | Follow/render Y offset. |
| `pillarboxing` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `portraitHeight` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `portraitWidth` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `renderToSprite(spriteEntity)` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `scalingMode` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `shake(intensity, duration)` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `squareSize` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stopFollow()` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `x` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `y` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `zoom` | Read/write property | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## ChatLogAPI
**Access:** `this.chat`. **Requirement:** ChatLog component. **Source:** `project/runtime/scripting/components/ChatLogAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `backgroundColor` | Read/write property | Background color. |
| `backgroundOpacity` | Read/write property | Background opacity. |
| `clear()` | Method | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `fontFamily` | Read/write property | Font family. |
| `fontSize` | Read/write property | Font size. |
| `lineHeight` | Read/write property | Line height. |
| `maxMessages` | Read/write property | Maximum retained messages. |
| `messageColor` | Read/write property | Message color. |
| `messages` | Read-only property | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `padding` | Read/write property | Padding. |
| `screenSpace` | Read/write property | Screen-space mode. |
| `send(sender, text, color)` | Method | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `senderColor` | Read/write property | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `showSender` | Read/write property | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `visible` | Read/write property | Visibility. |
| `visibleCount` | Read/write property | Number of visible rows. |
| `width` | Read/write property | Panel width. |
## ColliderAPI
**Access:** `this.collider`. **Requirement:** Collider2D component. **Source:** `project/runtime/scripting/components/ColliderAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `capsuleHalfHeight` | Read-only property | Capsule half-height. |
| `capsuleRadius` | Read-only property | Capsule radius. |
| `density` | Read-only property | Density. |
| `friction` | Read-only property | Friction. |
| `height` | Read-only property | Box height. |
| `isColliding(other)` | Method | The `this.collider` sub-object exposed to user scripts. |
| `isOneWayPlatform` | Read-only property | One-way platform flag. |
| `isTrigger` | Read/write property | Trigger-only collider. |
| `layer` | Read-only property | Layer index 0-15. |
| `mask` | Read-only property | 16-bit interaction mask. |
| `offset` | Read-only property | {x,y} collider offset. |
| `oneWayDirection` | Read/write property | The `this.collider` sub-object exposed to user scripts. |
| `radius` | Read-only property | Circle radius. |
| `restitution` | Read-only property | Restitution. |
| `rotation` | Read/write property | The `this.collider` sub-object exposed to user scripts. |
| `shape` | Read-only property | Box | Circle | Capsule | Triangle. |
| `width` | Read-only property | Box width. |
## ControllerAPI
**Access:** `this.controller`. **Requirement:** CharacterController component. This module combines members for several movement types; a member is available only when the component is set to a compatible type (Character, Platformer, Top-Down, Car, Follow or Patrol). Free mode exposes only its small common surface.. **Source:** `project/runtime/scripting/components/ControllerAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `acceleration` | Read/write property | Acceleration. |
| `airControl` | Read/write property | Air-control factor. |
| `brakeForce` | Read/write property | Car brake force. |
| `canJump` | Read/write property | Whether jumping is available. |
| `controllerType` | Read-only property | Read-only movement type. |
| `driftFactor` | Read/write property | Car drift factor. |
| `driveTowardArriveDistance` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `facingDirection` | Read-only property | Current patrol facing direction. |
| `flipDirection()` | Method | Reverse Patrol direction. |
| `followDistance` | Read/write property | Follow distance. |
| `followSpeed` | Read/write property | Follow speed. |
| `gravityScale` | Read/write property | Gravity scale. |
| `groundAngle` | Read-only property | Ground angle. |
| `isGrounded` | Read-only property | Ground state. |
| `isOnCeiling` | Read-only property | Ceiling contact. |
| `isOnSlope` | Read-only property | Slope contact. |
| `isOnWall` | Read-only property | Wall contact. |
| `jumpForce` | Read/write property | Jump force. |
| `maxJumps` | Read/write property | Maximum jumps. |
| `maxSpeed` | Read/write property | Car maximum speed. |
| `moveSpeed` | Read/write property | Movement speed. |
| `patrolAxis` | Read/write property | Horizontal | Vertical. |
| `patrolDistance` | Read/write property | Patrol distance. |
| `patrolMode` | Read/write property | Platformer | Top-Down. |
| `simulateDrive(throttle, steer)` | Method | Drive a Car controller by script. |
| `simulateDriveJoystick(x, y)` | Method | Drive using joystick-style vector input. |
| `simulateDriveToward(x, y)` | Method | Drive toward a world point. |
| `simulateJump()` | Method | Request a jump. |
| `simulateMove(x, y)` | Method | Drive movement by script. |
| `targetName` | Read/write property | Follow target name. |
| `turnSpeed` | Read/write property | Car turn speed. |
| `useDefaultInput` | Read/write property | Built-in input mapping. |
| `useGravity` | Read/write property | Gravity toggle. |
## JointAPI
**Access:** `this.joint`. **Requirement:** Joint2D component. **Source:** `project/runtime/scripting/components/JointAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `anchor1` | Read/write property | {x,y} local anchor on this body. |
| `anchor2` | Read/write property | {x,y} local anchor on connected body/world anchor. |
| `axis` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `breakForce` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `breakable` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `collideConnected` | Read/write property | Collision between connected bodies. |
| `connectedEntity` | Read/write property | Connected entity context, when one exists. |
| `damping` | Read/write property | Spring damping. |
| `disableConnectedCollision` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `enabled` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `flexibility` | Allow-listed but not implemented | The proxy allow-list contains this name, but the current JointAPI target has no getter or setter for it. Reads return undefined and writes do not update Joint2D.flexibility. Set Flexibility (%) in the Inspector instead. |
| `jointDrag` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `jointType` | Read/write property | Joint type. |
| `length` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `limitMax` | Read/write property | Maximum limit. |
| `limitMin` | Read/write property | Minimum limit. |
| `limitsEnabled` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `motorEnabled` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `motorMaxForce` | Read/write property | Maximum motor force. |
| `motorSpeed` | Read/write property | Motor speed. |
| `restStiffness` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `ropeMass` | Read/write property | Rope/spring segment mass. |
| `segmentCount` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stiffness` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureFlip` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureKey` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureMode` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureOffset` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureScale` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureTiling` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `useTexture` | Read/write property | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `visualColor` | Read/write property | Visual color. |
| `visualEnabled` | Read/write property | Visual enabled. |
| `visualThickness` | Read/write property | Visual thickness. |
## JoystickAPI
**Access:** `this.joystick`. **Requirement:** Joystick component. **Source:** `project/runtime/scripting/components/JoystickAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `active` | Read-only property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `angle` | Read-only property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `baseColor` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `baseOpacity` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `baseRadius` | Read/write property | Base radius. |
| `deadZone` | Read/write property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `hideWhenIdle` | Read/write property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `idleOpacityMultiplier` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `knobColor` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `knobOpacity` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `knobRadius` | Read/write property | Knob radius. |
| `magnitude` | Read-only property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineColor` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `outlineWidth` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `positionMode` | Read/write property | Joystick positioning mode. |
| `regionHeight` | Read/write property | Region height. |
| `regionWidth` | Read/write property | Region width. |
| `regionX` | Read/write property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `regionY` | Read/write property | Touch/pointer region Y. |
| `returnToCenter` | Read/write property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `x` | Read-only property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `y` | Read-only property | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## LightAPI
**Access:** `this.light`. **Requirement:** Light component. **Source:** `project/runtime/scripting/components/LightAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `angle` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `castShadows` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `castsOnWorld` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `color` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `coreSize` | Read/write property | Light core size. |
| `coreVisible` | Read/write property | Show light core. |
| `flicker` | Read/write property | Flicker toggle. |
| `flickerDuration` | Read/write property | Flicker duration. |
| `flickerSpeed` | Read/write property | Flicker speed. |
| `height` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `intensity` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `radius` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `shadowColor` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `shadowStrength` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `type` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `width` | Read/write property | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
## LightingSettingsAPI
**Access:** `scene.lighting`. **Requirement:** Scene lighting settings; exposed through the scene global. **Source:** `project/runtime/scripting/components/LightingSettingsAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `ambientDarkness` | Read/write property | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
| `glowStrength` | Read/write property | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
| `raymarchSteps` | Read/write property | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
| `shadowMode` | Read/write property | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
## NavAgentAPI
**Access:** `this.navAgent`. **Requirement:** NavAgent2D component. **Source:** `project/runtime/scripting/components/NavAgentAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `acceleration` | Read/write property | Acceleration. |
| `area` | Read/write property | Allowed area mask. |
| `areaCosts` | Read/write property | 16-entry area cost overrides. |
| `autoRepath` | Read/write property | Auto-repath. |
| `avoidanceEnabled` | Read/write property | Avoidance toggle. |
| `avoidancePriority` | Read/write property | Avoidance priority. |
| `collabEnabled` | Read/write property | Collaborative vehicle avoidance. |
| `collabGroupRadius` | Read/write property | Group radius. |
| `currentPath` | Read-only property | Read-only world-space waypoint array or null. |
| `currentPathIndex` | Read-only property | Read-only current waypoint index. |
| `deceleration` | Read/write property | Deceleration. |
| `radius` | Read/write property | Agent radius. |
| `repathDistance` | Read/write property | Target-move repath threshold. |
| `repathInterval` | Read/write property | Repath interval. |
| `speed` | Read/write property | Preferred speed. |
| `stoppingDistance` | Read/write property | Stopping distance. |
| `vehicleCornerLookahead` | Read/write property | Corner lookahead. |
| `vehicleCornerSlowdown` | Read/write property | Corner slowdown. |
| `vehicleLookahead` | Read/write property | Vehicle lookahead. |
| `vehicleObstacleBrake` | Read/write property | Obstacle brake factor. |
| `vehicleObstacleLookahead` | Read/write property | Obstacle lookahead. |
| `vehicleObstacleWidth` | Read/write property | Obstacle width. |
| `vehicleRecoveryReverseTime` | Read/write property | Reverse recovery time. |
| `vehicleRecoveryTime` | Read/write property | Recovery time. |
| `vehicleSpeedSmoothing` | Read/write property | Speed smoothing. |
| `vehicleSteerSmoothing` | Read/write property | Steering smoothing. |
## RigidbodyAPI
**Access:** `this.rigidbody`. **Requirement:** Rigidbody2D component. **Source:** `project/runtime/scripting/components/RigidbodyAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `addAngularImpulse(t)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addForce(x, y)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addForceAtPoint(x, y, pointX, pointY)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addImpulse(x, y)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addTorque(t)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `angularDamping` | Read/write property | Angular damping. |
| `gravityScale` | Read/write property | Gravity multiplier. |
| `groundAngle` | Read-only property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `groundAngleLimit` | Read/write property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `grounded` | Read-only property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isGrounded` | Read-only property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isOnCeiling` | Read-only property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isOnSlope` | Read-only property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isOnWall` | Read-only property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `linearDamping` | Read/write property | Linear damping. |
| `mass` | Read/write property | Dynamic mass. |
| `move(dx, dy)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `resolvedVelocity` | Read-only property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `slopeMinAngle` | Read/write property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `type` | Read/write property | Dynamic | Kinematic | Static; switching type is supported at runtime. |
| `velocity` | Read/write property | {x,y} velocity. |
| `velocityX` | Read/write property | Horizontal velocity. |
| `velocityY` | Read/write property | Vertical velocity. |
| `wallAngleLimit` | Read/write property | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## SaveAPI
**Access:** `save`. **Requirement:** Global save store; no entity component required. **Source:** `project/runtime/scripting/components/SaveAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `clear()` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `delete(key)` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `deleteSlot(slotName)` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `flushNow()` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `get(key)` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `has(key)` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `isReady` | Read-only property | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `keys()` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `listSlots()` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `load(slotName)` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `onError(callback)` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `set(key, value)` | Method | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
| `slot` | Read-only property | The `save` global exposed to user scripts (see scripting/ScriptAPI.js getGlobals()). |
## ShadowCasterAPI
**Access:** `this.shadowCaster`. **Requirement:** ShadowCaster component. **Source:** `project/runtime/scripting/components/ShadowCasterAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `enabled` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `height` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `length` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `offsetX` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `offsetY` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `opacity` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `softness` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `width` | Read/write property | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
## ShapeAPI
**Access:** `this.shape`. **Requirement:** ShapeRenderer component. **Source:** `project/runtime/scripting/components/ShapeAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `capsuleHalfHeight` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `capsuleRadius` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `fillColor` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `height` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `opacity` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineColor` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineEnabled` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineWidth` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `radius` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `shapeType` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `visualRotation` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `width` | Read/write property | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## SpeechBubbleAPI
**Access:** `this.speechBubble`. **Requirement:** SpeechBubble component. **Source:** `project/runtime/scripting/components/SpeechBubbleAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `backgroundColor` | Read/write property | Background color. |
| `borderColor` | Read/write property | Border color. |
| `borderWidth` | Read/write property | Border width. |
| `cornerRadius` | Read/write property | Corner radius. |
| `fontFamily` | Read/write property | Font family. |
| `fontSize` | Read/write property | Font size. |
| `hide()` | Method | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `maxWidth` | Read/write property | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetX` | Read/write property | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetY` | Read/write property | Vertical offset. |
| `padding` | Read/write property | Padding. |
| `show(text, duration)` | Method | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `tailDirection` | Read/write property | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `tailSize` | Read/write property | Tail size. |
| `text` | Read/write property | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textColor` | Read/write property | Text color. |
| `visible` | Read/write property | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## SpriteAPI
**Access:** `this.sprite`. **Requirement:** SpriteRenderer component. **Source:** `project/runtime/scripting/components/SpriteAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `color` | Read/write property | Hex tint color. |
| `flipX` | Read/write property | Horizontal mirror. |
| `flipY` | Read/write property | Vertical mirror. |
| `opacity` | Read/write property | The `this.sprite` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `texture` | Read/write property | Sprite asset key. |
| `visualRotation` | Read/write property | The `this.sprite` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## StateAPI
**Access:** `this.state`. **Requirement:** Available on every entity; no component required. **Source:** `project/runtime/scripting/components/StateAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `change(name)` | Method | The `this.state` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `current` | Read-only property | The `this.state` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `previous` | Read-only property | The `this.state` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## StrokePathAPI
**Access:** `this.strokePath`. **Requirement:** StrokePath component. **Source:** `project/runtime/scripting/components/StrokePathAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `addPoint(x, y)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `capMode` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `color` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `firstPoint` | Read-only property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `getLength()` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `getPoint(index)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `insertPoint(index, x, y)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `jointMode` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `lastPoint` | Read-only property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `localToWorld(localX, localY)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `opacity` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `pointCount` | Read-only property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `points` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `removePoint(index)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `setPoint(index, x, y)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureFlip` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureKey` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureMode` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureOffset` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureRotation` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureScale` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureTiling` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `thickness` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `useTexture` | Read/write property | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `worldToLocal(worldX, worldY)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
## TextAPI
**Access:** `this.text`. **Requirement:** TextRenderer component. **Source:** `project/runtime/scripting/components/TextAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `align` | Read/write property | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `anchorX` | Read/write property | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `anchorY` | Read/write property | Vertical anchor. |
| `bold` | Read/write property | Bold toggle. |
| `color` | Read/write property | Hex text color. |
| `fontFamily` | Read/write property | Font family. |
| `fontSize` | Read/write property | Font size. |
| `italic` | Read/write property | Italic toggle. |
| `opacity` | Read/write property | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `screenSpace` | Read/write property | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `value` | Read/write property | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `wordWrap` | Read/write property | Enable word wrapping. |
| `wrapWidth` | Read/write property | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## TextInputAPI
**Access:** `this.textInput`. **Requirement:** TextInput component. **Source:** `project/runtime/scripting/components/TextInputAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `backgroundColor` | Read/write property | Background color. |
| `borderColor` | Read/write property | Border color. |
| `borderWidth` | Read/write property | Border width. |
| `clear()` | Method | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `clearOnSubmit` | Read/write property | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `cornerRadius` | Read/write property | Corner radius. |
| `focused` | Read-only property | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `fontFamily` | Read/write property | Font family. |
| `fontSize` | Read/write property | Font size. |
| `height` | Read/write property | Control height. |
| `justSubmitted` | Read-only property | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `maxLength` | Read/write property | Character cap. |
| `padding` | Read/write property | Padding. |
| `placeholder` | Read/write property | Placeholder. |
| `placeholderColor` | Read/write property | Placeholder color. |
| `textColor` | Read/write property | Text color. |
| `value` | Read/write property | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `width` | Read/write property | Control width. |
## TouchTrackAPI
**Access:** `this.myTouch`. **Requirement:** Available on every entity; no component required. **Source:** `project/runtime/scripting/components/TouchTrackAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `active` | Read-only property | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `disable()` | Method | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `enable()` | Method | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `enabled` | Read-only property | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `startTracking()` | Method | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stopTracking()` | Method | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `x` | Read-only property | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `y` | Read-only property | The `this.myTouch` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## TransformAPI
**Access:** `this.transform`. **Requirement:** Available on every entity; no component required. **Source:** `project/runtime/scripting/components/TransformAPI.js`.
| Member | Access | Purpose |
| --- | --- | --- |
| `lookAt(x, y)` | Method | Point the entity toward a world-space point. |
| `position` | Read/write property | { x, y } world-space position; read or assign. |
| `rotation` | Read/write property | Rotation in degrees. |
| `scale` | Read/write property | Member name confirmed by the module allow-list. See the corresponding component or scripting guide for usage details. |
| `translate(dx, dy)` | Method | Move by a delta amount. |
## Global runtime objects and functions
The global runtime API is separate from per-entity component modules. The exact global members and common option shapes are described in [Runtime modules](runtime.html), [Global API](../scripting/globals.html), [Input](../scripting/input.html), and [Persistence](../scripting/persistence.html).
### Entity lookup functions
- `findFirst(name)`
- `findAll(name)`
- `findFirstWithTag(tag)`
- `findAllWithTag(tag)`
- `findWithTag(tag)`
- `findById(id)`
- `findInRadius(x, y, radius, opts)`
### Scene (`scene`)
- `findFirst(name)`
- `findAll(name)`
- `findFirstWithTag(tag)`
- `findAllWithTag(tag)`
- `findWithTag(tag)`
- `findById(id)`
- `load(sceneName)`
- `restart()`
- `pause()`
- `resume()`
- `isPaused (read-only)`
- `current (read-only)`
- `lighting`
### Physics (`physics`)
- `raycast(x1, y1, x2, y2, opts)`
- `layer(...indices)`
### Navigation (`nav`)
- `findPath(x1, y1, x2, y2, opts)`
- `isWalkable(x, y)`
- `bake()`
- `areaIndex(name)`
- `areaMask(...names)`
- `areaCosts(costsByName)`
### Input (`input`)
- `keyDown(key)`
- `keyPressed(key)`
### Mouse (`mouse`)
- `x, y (world-space)`
- `screenX, screenY (canvas pixels)`
- `over (read-only)`
- `down(button?)`
- `pressed(button?)`
- `released(button?)`
- `isOver(entityOrName, opts)`
- `clickedOn(entityOrName, opts, button?)`
### Touch (`touch`)
- `count, first, anyJustStarted, anyJustEnded`
- `per-touch: id, x, y, screenX, screenY, startX, startY, dx, dy, distance, justStarted, justEnded`
- `swipe: active, direction, dx, dy, distance`
- `pinch: active, scale, delta, distance`
- `isOver(entityOrName, opts)`
- `tappedOn(entityOrName, opts)`
### Time (`time`)
- `deltaTime`
- `unscaledDeltaTime`
- `elapsed`
- `scale`
### Random (`random`)
- `int(min, max)`
- `float(min, max)`
### Math helpers (`mathx`)
- `lerp(a, b, t)`
- `smoothstep(a, b, value)`
- `clamp(value, min, max)`
- `moveToward(current, target, maxDelta)`
- `remap(value, inMin, inMax, outMin, outMax)`
- `approximately(a, b, epsilon?)`
### Global state (`global`)
- `Read, write and test arbitrary named in-memory values shared by scripts; resets when the game page is reloaded.`
### Debug HUD (`debug`)
- `show(on?)`
- `showFps(on?)`
- `log(label, value)`
- `clear(label)`
- `clearAll()`
### Object pools (`pool`)
- `create(name, options)`
- `find(name)`
- `get(name, x, y)`
- `release(entity)`
### Global functions
- `spawn(nameOrTag, opts)`
- `wait(seconds, callback)`
- `cancelWait(timerId)`
- `repeat(seconds, callback)`
- `cancelRepeat(timerId)`
- `sendMessage(tagOrEntity, message, data)`
- `broadcastMessage(message, data)`
- `tween(target, properties, duration, easing?, onComplete?)`
- `cancelTween(tweenId)`
- `smoothstep(a, b, value)`
---
# this (EntityContext) reference
> Complete reference for the current entity context, all flat shortcuts, pointer/touch helpers, navigation methods and per-entity script modules.
## Transform shortcuts
Every entity has a Transform. These members read or write its live data; position values use world-space coordinates and rotation is in degrees.
| Member | Access | Meaning |
| --- | --- | --- |
| `x`, `y` | Read/write | World position coordinates. Writes also update the physics body's position target when a Rigidbody2D is attached. |
| `position` | Read/write | Gets or assigns an `{x, y}` object. |
| `rotation` | Read/write | Rotation in degrees. Kinematic bodies receive the script-set rotation target. |
| `scaleX`, `scaleY` | Read/write | Transform scale factors. |
| `translate(dx, dy)` | Method | Moves the entity by a relative world-space offset and synchronizes physics position targeting. |
| `distanceTo(x, y)` | Method | Returns straight-line distance from the entity to a world-space point. |
| `transform` | Sub-object | Always available; see [TransformAPI](script-modules.html#transformapi). |
## Identity, visibility and lifecycle members
| Member | Access | Meaning |
| --- | --- | --- |
| `name` | Read-only | Entity name. |
| `tag` | Read/write | Entity tag; can be changed while the game runs. |
| `id` | Read-only | Stable unique entity ID. Prefer this when you need to refer to one exact spawned instance. |
| `visible` | Read/write | Gets or sets the entity's active/visible state. |
| `enabled` | Read/write | Gets or sets the enabled state of the Script component attached to this entity. Without a Script component, reads as enabled. |
| `destroy()` | Method | Queues this entity for removal at the end of the current frame; it is not torn down in the middle of the callback. |
| `destroyed` | Read-only | True after destroy() is queued and before the entity is removed. |
| `hasComponent(componentKey)` | Method | Tests whether the entity currently has a component, for example `hasComponent("Rigidbody2D")`. Every entity has Transform. |
| `isClone` | Read-only | True for the context used by a script on an entity created by runtime `spawn()`. |
| `spawn(nameOrTagOrEntity, opts)` | Method | Creates a runtime clone. Accepts a name/tag lookup or an EntityContext. See [Finding and spawning](../scripting/finding-entities.html). |
| `wait(seconds, callback)`, `cancelWait(timerId)` | Methods | Start and cancel an entity-owned one-shot timer. |
| `repeat(seconds, callback)`, `cancelRepeat(timerId)` | Methods | Start and cancel an entity-owned repeating timer. |
| `releaseToPool(delay?)` | Method | Returns a pooled entity to its pool immediately or after an optional delay. |
| `isPooled` | Read-only | True when the entity was created and is managed by an object pool. |
## Pointer and touch helpers
These helpers test the current entity's actual Collider2D shape, not only its bounding rectangle. A **Collider2D is required**; without one these hit tests cannot match the pointer or a finger.
| Member | Meaning | Input |
| --- | --- | --- |
| `isPointerOver` | True while the mouse cursor is over this entity. | Mouse hover. |
| `isClicked` | True for the frame the left mouse button is pressed over this entity. | Mouse click. |
| `isTouchOver` | True while any active finger is over this entity. | Touch hover. |
| `isTapped` | True for the frame a finger first touches down over this entity. | Touch tap. |
| `myTouch` | Per-entity tracking for claiming and following one finger. The sub-object exists on every entity, but hit detection requires Collider2D. | See [TouchTrackAPI](script-modules.html#touchtrackapi). |
## Navigation movement methods
| Method | Requirements | Behavior |
| --- | --- | --- |
| `navMoveToward(targetX, targetY, speed?, opts?)` | NavWorld2D for pathfinding. NavAgent2D is optional but supplies radius, speed, repath, area and avoidance defaults. | Finds a path and advances the entity along it. It does not fall back to straight-line movement when no path exists. |
| `navDriveToward(targetX, targetY, speed?, opts?)` | Car-type CharacterController, NavWorld2D and NavAgent2D for the full vehicle tuning/agent behavior. | Follows a path using vehicle steering, lookahead, braking and recovery behavior. |
Use [Pathfinding](../scripting/navigation.html) and [Navigation: complete setup](../scripting/navigation-complete.html) for setup, options and examples.
## Component sub-objects
These modules are available only when the named component is attached to the same entity. Accessing a missing component module or misspelling a member produces a clear runtime API error. The generated [complete script-module index](script-modules.html) lists every exposed member and its read/write or method status.
| Script access | Required component | Reference |
| --- | --- | --- |
| `this.sprite` | SpriteRenderer | [SpriteRenderer](components/spriterenderer.html) |
| `this.shape` | ShapeRenderer | [ShapeRenderer](components/shaperenderer.html) |
| `this.text` | TextRenderer | [TextRenderer](components/textrenderer.html) |
| `this.strokePath` | StrokePath | [StrokePath](components/strokepath.html) |
| `this.speechBubble` | SpeechBubble | [SpeechBubble](components/speechbubble.html) |
| `this.chat` | ChatLog | [ChatLog](components/chatlog.html) |
| `this.textInput` | TextInput | [TextInput](components/textinput.html) |
| `this.joystick` | Joystick | [Joystick](components/joystick.html) |
| `this.rigidbody` | Rigidbody2D | [Rigidbody2D](components/rigidbody2d.html) |
| `this.collider` | Collider2D | [Collider2D](components/collider2d.html) |
| `this.joint` | Joint2D | [Joint2D](components/joint2d.html) |
| `this.controller` | CharacterController | [CharacterController](components/charactercontroller.html) |
| `this.animator` | SpriteAnimation | [SpriteAnimation](components/spriteanimation.html) |
| `this.camera` | Camera | [Camera](components/camera.html) |
| `this.audio` | AudioSource | [AudioSource](components/audiosource.html) |
| `this.ear` | AudioListener | [AudioListener](components/audiolistener.html) |
| `this.light` | Light | [Light](components/light.html) |
| `this.shadowCaster` | ShadowCaster | [ShadowCaster](components/shadowcaster.html) |
| `this.navAgent` | NavAgent2D | [NavAgent2D](components/navagent2d.html) |
## Always-available sub-objects
| Access | Availability | Reference |
| --- | --- | --- |
| `this.transform` | Every entity has Transform. | [TransformAPI](script-modules.html#transformapi) |
| `this.state` | Every entity; no Inspector component. Starts at state `default`. | [StateAPI](script-modules.html#stateapi) and [State & messaging](../scripting/state-messaging.html) |
| `this.myTouch` | Every entity; collider is needed for pointer/finger hit detection. | [TouchTrackAPI](script-modules.html#touchtrackapi) |
## Scene-level module
`scene.lighting` is not attached to `this`. It exposes scene-wide LightingSettings through the global `scene` object. When there is no LightingSettings component in the scene, reads use renderer defaults and writes have no effect. See [LightingSettingsAPI](script-modules.html#lightingsettingsapi) and [LightingSettings](components/lightingsettings.html).
---
# Option schemas & opts
> Exact option objects, types, defaults and semantics for the most important Realot Studio APIs, with machine-readable JSON for tooling and LLMs.
> **Need to know what must exist first?:** Use the API requirements & complete usage map to see prerequisites for every global and component API.
> **Hands-on examples:** See the Script API cookbook for complete scripts showing where each API lives and how the pieces fit together.
> **Authoritative option metadata:** Navigation option names are defined once in runtime/scripting/NavAPI.js and consumed by both runtime behavior and editor IntelliSense. The machine-readable api-options.json mirrors the documented public option groups.
## nav.findPath
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `debug` | boolean | False | Draw the current path as green debug segments for one frame. |
| `radius` | number | 0 | Agent clearance against the shared NavWorld2D. Larger radius can close narrow passages. |
| `area` | number | 65535 | 16-bit allowed-area mask. Default 0xffff allows every area. |
| `areaCosts` | number[]|null | None | Per-call 16-slot cost overrides; null entries use NavWorld2D defaults. |
## this.navMoveToward
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `repathInterval` | number | 0.35 | Seconds between re-path checks when autoRepath is enabled. |
| `arriveDist` | number | 4 | Distance at which an intermediate waypoint is considered reached. |
| `finalArriveDist` | number | 1 | Distance from final target considered arrived. |
| `targetChangeDistance` | number | 4 | Target movement that forces an immediate re-path; effective default is max(4, arriveDist). |
| `debug` | boolean | False | Draw the current path as green debug segments for one frame. |
## this.navDriveToward
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `repathInterval` | number | 0.35 | Seconds between re-path checks when autoRepath is enabled. |
| `arriveDist` | number | 4 | Distance at which an intermediate waypoint is considered reached. |
| `finalArriveDist` | number | 1 | Distance from final target considered arrived. |
| `targetChangeDistance` | number | 4 | Target movement that forces an immediate re-path; effective default is max(4, arriveDist). |
| `debug` | boolean | False | Draw the current path as green debug segments for one frame. |
## findInRadius
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `name` | string|undefined | None | Only return entities with this exact name. |
| `tag` | string|undefined | None | Only return entities with this exact tag when name is not provided. |
## spawn
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `x` | number|undefined | source x | Spawn position X override. |
| `y` | number|undefined | source y | Spawn position Y override. |
| `name` | string|undefined | source name | Rename the clone. |
| `byTag` | boolean | False | Interpret the first argument as a tag instead of a name. |
## physics.raycast
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `layerMask` | number|undefined | engine default | Restrict ray hits to collider layers included in the mask. |
| `debug` | boolean | False | Draw the ray debug line for one frame. |
| `exclude` | array|undefined | None | Exclude listed entity/entity-context targets from hit testing. |
## mouse.isOver / clickedOn
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `byTag` | boolean | False | Interpret the string target as a tag instead of an entity name. |
## touch.isOver / tappedOn
| Option | Type | Default | Effect |
| --- | --- | --- | --- |
| `byTag` | boolean | False | Interpret the string target as a tag instead of an entity name. |
| `justStarted` | boolean | False | Only match touches that began this frame. |
## Examples
```
this.navMoveToward(target.x, target.y, 160, {
repathInterval: 0.2,
arriveDist: 6,
finalArriveDist: 12,
debug: true,
});
const hits = physics.raycast(this.x, this.y, target.x, target.y, {
layerMask: 1 << 0,
exclude: [this],
debug: true,
});
```
## How `opts` overrides work
Realot Studio uses options in a few different ways. An explicit option normally wins for that call; otherwise the method uses the component/default value. This matters most for navigation and raycasts.
| Pattern | What it means |
| --- | --- |
| `this.navMoveToward(x,y,160)` | Explicit speed is used for this call; other behavior can come from the NavAgent2D component. |
| `this.navMoveToward(x,y,160,{ finalArriveDist: 12 })` | Only `finalArriveDist` changes for this call; unrelated options keep their defaults/component behavior. |
| `nav.findPath(...,{ radius: 24 })` | Manual query uses the supplied radius instead of assuming the caller's component radius. |
| `physics.raycast(...,{ exclude:[this] })` | The current entity is removed from the query results, preventing self-hits. |
> **Do not invent option names.:** Realot Studio is not drop-in Unity/Unreal/Godot API compatibility. Use the exact option names documented here and in the editor's IntelliSense.
## Navigation option recipes
### Hard route restriction
```
var route = nav.findPath(this.x, this.y, goalX, goalY, {
area: nav.areaMask("Road", "Ground")
});
```
Only named areas in the mask are legal. An omitted area is not a fallback route; it is forbidden.
### Soft route preference
```
var route = nav.findPath(this.x, this.y, goalX, goalY, {
area: nav.areaMask("Road", "Ground", "Mud"),
areaCosts: nav.areaCosts({ Road: 1, Ground: 2, Mud: 5 })
});
```
All three areas remain legal, but the pathfinder prefers cheaper traversals when route length is otherwise comparable.
### Per-agent runtime override
```
var costs = this.navAgent.areaCosts || [];
costs[2] = 4;
this.navAgent.areaCosts = costs;
```
`areaCosts` is an indexed 16-slot array on the component. Assign a new normalized array back to the property; mutating a previously-read temporary is not enough unless you reassign it.
## LLM usage rule
When generating Realot Studio code, prefer the documented option name and shape exactly as listed. Do not invent Unity/Unreal/Godot option names just because they sound familiar; Realot Studio’s runtime and IntelliSense contract is the authority.
---
# API requirements & complete usage map
> Complete prerequisites and usage map for Realot Studio scripting APIs.
> **Prerequisites matter.:** Realot Studio does not expose every component API on every entity. this.sprite , this.rigidbody , this.navAgent , and the other component sub-objects are created only when the corresponding component exists on that same entity. If the component is absent, the sub-object is undefined . Use this.hasComponent("...") when you need to guard optional behavior.
## Universal component-API workflow
1. Select the entity in the **Hierarchy**.
2. In the **Inspector** on the right, click **Add Component**.
3. Search for the required component and click it.
4. Configure its Inspector properties and any component-specific editor tool that appears.
5. Add a **Script** component to the same entity and open/edit its script.
6. Inside the script, access the matching sub-object, for example `this.rigidbody` or `this.sprite`.
7. Play the scene and inspect the Console if the component is missing or an API call is invalid.
```
// Example: Rigidbody2D is required for this API.
function onStart() {
if (!this.rigidbody) return;
this.rigidbody.velocity = { x: 100, y: 0 };
}
```
## Global APIs — no component required
These are injected into every running game script. They are not added through **Add Component**.
- `enabled`
- `showFps`
- `stats`
- `debugLines`
- `entity`
- `point`
- `normal`
- `distance`
- `findWithTag`
- `findFirst`
- `findAll`
- `findFirstWithTag`
- `findAllWithTag`
- `findById`
- `findInRadius`
- `scene`
- `physics`
- `nav`
- `sendMessage`
- `broadcastMessage`
- `spawn`
- `wait`
- `cancelWait`
- `repeat`
- `cancelRepeat`
- `input`
- `mouse`
- `touch`
- `time`
- `random`
- `smoothstep`
- `mathx`
- `global`
- `save`
- `debug`
| Global family | Required setup | Typical use |
| --- | --- | --- |
| `scene` | A running scene. | Load/restart/pause/resume scenes and access scene-level services. |
| `physics` | Physics runtime for physics queries. | Raycasts and collision-layer/mask operations. |
| `nav` | Configured Nav World 2D for meaningful pathfinding. | Find paths, test walkability, use named navigation areas/costs. |
| `input`, `mouse`, `touch` | Running game input; touch requires a touch-capable device for actual touch events. | Keyboard, mouse, touch, swipe and pinch controls. |
| `time`, `random`, `mathx` | None. | Frame timing, randomness and gameplay math. |
| `save` | Browser storage available to the deployment. | Persistent save slots. |
| `debug` | Running game/editor debug surface. | Debug messages and visual diagnostics. |
| `spawn`, `wait`, `repeat` | Running entity script/runtime. | Runtime clones and entity-owned timers. |
| `sendMessage`, `broadcastMessage` | Running scene with target entities when targeting by name/tag. | Script-to-script communication. |
## Component APIs — prerequisites and members
| API | Required setup | Public members found in the runtime API module |
| --- | --- | --- |
| `SpriteAnimation` | Add a Sprite Animation component to the same entity before using this.animator. | `reset, playing, currentClip, currentFrame, totalFrames, speed, it, trap, property, directly` |
| `AudioSource` | Add an Audio Source component to the same entity before using this.audio. | `volume, pitch, playing, to, trap, directly` |
| `AudioListener` | Add an Audio Listener component to the same entity before using this.ear. | `radius, enabled, sourcesInRange, check` |
| `Camera` | Add a Camera component to the same entity before using this.camera. | `zoom, backgroundColor, aspectMode, landscapeWidth, landscapeHeight, portraitWidth, portraitHeight, squareSize, customWidth, customHeight, enablePseudo3D, scalingMode, keepHeight, aspectRatioLock, allowStretching, letterboxing, pillarboxing, barColor, integerScaling, x, y, entity, center, each, offsetX, offsetY, applies, is, that, by, from, the, of` |
| `ChatLog` | Add a Chat Log component to the same entity before using this.chat. | `messages, maxMessages, visibleCount, width, lineHeight, fontSize, fontFamily, messageColor, senderColor, backgroundColor, backgroundOpacity, padding, showSender, screenSpace, visible, directly` |
| `Collider2D` | Add a Collider 2D component to the same entity before using this.collider. | `shape, width, height, radius, capsuleHalfHeight, capsuleRadius, offset, isTrigger, isOneWayPlatform, friction, restitution, density, layer, mask, isColliding, get, set` |
| `CharacterController` | Add a Character Controller component to the same entity before using this.controller. | `heading, directional, it, controllerType, moveSpeed, acceleration, airControl, useGravity, gravityScale, useDefaultInput, maxSpeed, brakeForce, turnSpeed, driftFactor, driveTowardArriveDistance, patrolDistance, patrolMode, patrolAxis, targetName, followSpeed, followDistance, of, every, directly, if` |
| `Joint2D` | Add a Joint 2D component to the same entity before using this.joint. | `jointType, connectedEntity, anchor1, anchor2, axis, length, stiffness, damping, segmentCount, ropeMass, visualEnabled, visualColor, visualThickness, useTexture, textureKey, textureMode, textureTiling, textureScale, textureOffset, textureFlip, limitsEnabled, limitMin, limitMax, motorEnabled, motorSpeed, motorMaxForce, collideConnected, enabled, key, get, set` |
| `Joystick` | Add a Joystick component to the same entity before using this.joystick. | `x, y, magnitude, angle, active, positionMode, regionX, regionY, regionWidth, regionHeight, baseRadius, knobRadius, baseColor, baseOpacity, knobColor, knobOpacity, outlineColor, outlineWidth, deadZone, returnToCenter, hideWhenIdle, idleOpacityMultiplier, directly` |
| `Light` | Add a Light component to the same entity before using this.light. | `type, color, intensity, radius, angle, width, height, castsOnWorld, castShadows, shadowColor, shadowStrength, flicker, flickerSpeed, flickerDuration, coreSize, coreVisible, for, on` |
| `LightingSettings` | Use the global scene.lighting surface; it is not an ordinary entity component API. | `shadowMode, raymarchSteps, ambientDarkness, glowStrength` |
| `NavAgent2D` | Add a Nav Agent 2D component to the same entity for this.navAgent. A Nav World 2D must also be configured for actual pathfinding. | `radius, speed, acceleration, deceleration, stoppingDistance, autoRepath, repathInterval, repathDistance, avoidanceEnabled, avoidancePriority, collabEnabled, collabGroupRadius, vehicleLookahead, vehicleCornerLookahead, vehicleObstacleLookahead, vehicleObstacleWidth, vehicleSteerSmoothing, vehicleSpeedSmoothing, vehicleCornerSlowdown, vehicleObstacleBrake, vehicleRecoveryTime, vehicleRecoveryReverseTime, area, areaCosts, currentPath, currentPathIndex, here, get, set` |
| `Rigidbody2D` | Add a Rigidbody 2D component to the same entity before using this.rigidbody. | `x, type, silently, velocity, velocityX, velocityY, mass, gravityScale, linearDamping, angularDamping, isGrounded, grounded, isOnCeiling, isOnWall, isOnSlope, groundAngle, resolvedVelocity, groundAngleLimit, wallAngleLimit, slopeMinAngle, it, property, directly, for, if` |
| `ShadowCaster` | Add a Shadow Caster component to the same entity before using this.shadowCaster. | `enabled, width, height, offsetX, offsetY, opacity, length, softness, its, from` |
| `ShapeRenderer` | Add a Shape Renderer component to the same entity before using this.shape. | `shapeType, width, height, radius, capsuleHalfHeight, capsuleRadius, fillColor, opacity, outlineEnabled, outlineColor, outlineWidth, trap, directly` |
| `SpeechBubble` | Add a Speech Bubble component to the same entity before using this.speechBubble. | `text, visible, backgroundColor, textColor, borderColor, borderWidth, fontSize, fontFamily, padding, cornerRadius, maxWidth, offsetX, offsetY, tailDirection, tailSize, from, directly` |
| `SpriteRenderer` | Add a Sprite Renderer component to the same entity before using this.sprite. | `texture, color, flipX, flipY, opacity, directly` |
| `State` | See complete reference. | `current, previous, to, at` |
| `StrokePath` | Add a Stroke Path component to the same entity before using this.strokePath. | `points, thickness, color, opacity, useTexture, textureKey, textureMode, textureTiling, textureScale, textureOffset, textureFlip, textureRotation, jointMode, capMode, pointCount, firstPoint, lastPoint, for, by, to, key, getLength, getPoint, setPoint, addPoint, insertPoint, removePoint, worldToLocal, localToWorld` |
| `TextRenderer` | Add a Text Renderer component to the same entity before using this.text. | `value, fontSize, color, fontFamily, bold, italic, align, anchorX, anchorY, opacity, screenSpace, wordWrap, wrapWidth, directly` |
| `TextInput` | Add a Text Input component to the same entity before using this.textInput. | `value, placeholder, maxLength, fontSize, fontFamily, textColor, placeholderColor, backgroundColor, borderColor, borderWidth, cornerRadius, width, height, padding, clearOnSubmit, focused, justSubmitted, directly` |
| `Transform` | Every entity has a Transform; this.transform is therefore available on normal entity scripts. | `position, doc, rotation, scale, trap` |
| `StateAPI` | Available as `this.state` on entity scripts; no separate component is required. | `current, previous` plus state-transition behavior documented in State & messaging. |
| `TouchTrackAPI` | Available as `this.myTouch` for the scripted entity; touch input must be enabled/available in the runtime. | `active, enabled, x, y` |
| `SaveAPI` | Available as global `save`; no entity component is required. Persistent storage depends on the browser/deployment environment. | `isReady, slot` |
## Entity context APIs
Inside lifecycle functions such as `onStart()` and `onUpdate(dt)`, `this` is the current entity context. Core transform shortcuts such as `this.x`, `this.y`, `this.position`, `this.rotation`, `this.scaleX` and `this.scaleY` are available without adding a separate Transform component.
Other capabilities are deliberately grouped under their component sub-object: `this.rigidbody`, `this.collider`, `this.joint`, `this.controller`, `this.sprite`, `this.animator`, `this.camera`, `this.audio`, `this.ear`, `this.navAgent`, `this.light`, `this.shadowCaster`, `this.strokePath`, and the UI APIs documented above.
## Guarding optional components
```
function onUpdate(dt) {{
if (this.hasComponent("Rigidbody2D")) {{
// Safe to use this.rigidbody here.
this.rigidbody.velocityX = 100;
}}
}}
```
Use the exact component name expected by the engine. For systems with additional world-level prerequisites—especially navigation—having the entity component is necessary but not sufficient.
## How to read opts
Whenever a function accepts an `opts` object, the reference must be read as a contract: each property has a type, default, allowed/meaningful range, and effect. Omitted properties use the documented default. Options that are explicitly per-call do not permanently rewrite the component or world setting unless the API says they do.
```
const path = nav.findPath(startX, startY, goalX, goalY, {{
radius: 18,
area: nav.areaMask("Ground", "Road"),
areaCosts: nav.areaCosts({{ Mud: 4 }}),
debug: true
}});
```
For navigation, configure the world and areas in the editor first, then use script options to select/override behavior for the particular query. See [Navigation: complete setup](../scripting/navigation-complete.html) for the complete editor-to-script workflow.
## Source-of-truth rule
This page and the individual API references describe the public game-script contract implemented by the supplied runtime source. Internal editor classes, renderer internals, and private helper functions are not presented as supported game APIs simply because they exist in the source tree.
---
# Export overview
> Choose a standalone web export or the built-in Android APK build workflow.
## Available export targets
| Target | Availability | What it creates |
| --- | --- | --- |
| HTML5 | Available | A standalone static game package with `index.html` and the required runtime/assets. |
| PWA | Available | The HTML5 game package plus a web manifest and service worker for installable/offline behavior. |
| Android APK | Available through the configured build service | A debug-signed APK generated remotely from the same standalone web package. |
| Desktop (Windows/Mac/Linux) | Coming soon / disabled | Not currently generated by the Export window. |
Open **File → Export…** or the toolbar's **Export** button. See [Export window reference](export-window.html) for the controls and [Android APK](android.html) for the service workflow.
## Standalone game package
The browser builds a standalone ZIP with `index.html` at its root, a game entry script, runtime files and referenced assets. It does not include the editor or Hub. The Android build flow consumes this same standalone export package rather than reconstructing a game from editor-only project data.
## Run a web export
Serve the exported folder through HTTP(S) or upload it to a static host. Do not double-click `index.html` from the file system: browser module and asset requests can fail under `file://`.
---
# HTML5 and PWA export
> Create a standalone HTML5 game or a PWA with a manifest and service worker.
## HTML5
HTML5 export produces a standalone static game package. The ZIP contains an `index.html` entry point, game code, the standalone runtime and the assets required by the project. It does not include the editor or Hub.
## PWA
PWA export adds a web app manifest and service worker to the same standalone game package. The browser can offer installation and offline caching when the deployment meets the browser's PWA requirements.
## Hosting checklist
- Extract the ZIP and keep the entry point, runtime and referenced assets together.
- Serve the package over HTTP(S); do not rely on opening `index.html` directly with `file://`.
- Use HTTPS on a public deployment when browser security rules or PWA installation require a secure origin.
- Test the exported game independently of the editor before sharing it.
---
# Export window reference
> Understand the game title, favicon, export formats, build progress and Android APK quota.
Open the Export window from **File → Export…** or the toolbar's **Export** button.
## Game details
| Field | Behavior |
| --- | --- |
| Game title | Up to 80 characters; defaults to the project name. Used for the exported page title and Android app name. |
| Favicon | Optional image selected in the Export window. It is used as the exported web game's icon and, where supported by the APK wrapper, the Android launcher icon. |
## Format cards
| Card | Status | Output |
| --- | --- | --- |
| HTML5 | Available | Standalone static game package. |
| PWA | Available | HTML5 package plus manifest and service worker. |
| Desktop (Windows/Mac/Linux) | Coming soon / disabled | Not generated by the current Export window. |
| Android APK | Available | A debug-signed APK built by the configured remote service. |
## Browser-side web packaging
- HTML5/PWA packaging runs in the browser.
- The exporter includes the game runtime and referenced assets, not the editor.
- When asset optimization is supported by the browser, images/audio may be re-encoded and checked before inclusion.
- The result is a downloadable ZIP. Use a local HTTP server or static host to run it; direct `file://` opening is not supported.
## Android APK workflow
The Android card uses the built-in service configured for this Realot deployment. The editor prepares the standalone game ZIP, requests or renews a temporary build token, uploads the ZIP, polls the job and downloads the APK. You do not add a custom build server or paste an API key into the Export window.
The card shows the service connection state and the remaining APK export allowance. The current client-side allowance is **3 accepted builds in a rolling 14-day window per browser**; the authoritative service may apply additional server-side limits.
## Progress and cancellation
While an APK is building, the Export window displays progress and offers **Cancel build**. The editor polls the job approximately every 2.5 seconds and uses a 10-minute client timeout. Cancelling or leaving the editor signals cancellation to the service when possible. HTML5 and PWA packaging occurs locally in the browser.
## Build an APK from a web export
After an HTML5 or PWA export, the result screen can offer **Build APK from this HTML5/PWA export**. This sends the exact web ZIP already created, so the game package does not need to be rebuilt.
---
# Export an Android APK
> Build an Android APK directly from the Realot Studio Export window. The current editor allows three APK exports in a rolling 14-day period.
> **One simple flow:** Click Export , choose Android APK , and let Realot build the file. There is no separate setup wizard or need to export HTML5 first.
## Steps
1. Open the game project in Realot Studio.
2. Click **Export** in the editor toolbar. You can also use **File → Export…**.
3. In the Export Game window, choose **Android APK**.
4. Wait for the build to finish. Realot downloads the finished `.apk` file to your device.
The game title is filled in from the project name and can be changed before exporting. Choosing a custom favicon is optional. Those are the only optional details shown in the export form; you do not need Android Studio, Gradle, the Android SDK or a separate web export.
## APK export limit
The current editor allows **3 APK exports in a rolling 14-day period**. The Export window shows how many of the three remain and explains when an export becomes available again. The window is rolling: an export becomes available again 14 days after the corresponding counted export, rather than all three resetting on one calendar date.
An export is counted after the build service accepts the job. A failed or cancelled build gives that export back. **HTML5 and PWA exports are not limited by the APK quota.**
> **Quota detail for support and AI tools:** The supplied browser client records the rolling quota in this browser's local storage. It is therefore a per-browser client allowance, not an account-based counter. The build service should enforce its own server-side usage limits; clearing browser data is not a supported way to manage exports.
## What the APK contains
The current Android option produces a **debug-signed APK** intended for testing and direct installation on an Android device. It is not a Play Store production-signed release. The Android build service is needed to create the APK; the downloaded game does not need to contact that service while it is running.
## When an export does not finish
Read the message shown in the Export window. If the service is waking up or temporarily unavailable, try again later. A failed or cancelled build returns the consumed export allowance. If the same error keeps happening, copy the message from the export window and include it when reporting the issue.
## Other export formats
- **HTML5:** creates a standalone web game you can host as a static site.
- **PWA:** creates the web game plus an installable manifest and service worker for offline use.
- **Desktop (Windows/Mac/Linux):** listed in the format picker as coming soon in the supplied engine build.
For the other formats, see [HTML5 and PWA export](web.html) or the [Export window reference](export-window.html).
---
# Tuning guide
> Practical “increase/decrease this” rules for movement, physics, navigation, lighting, UI and path authoring.
## How to tune movement
| Goal | Raise | Lower |
| --- | --- | --- |
| More responsive character movement | acceleration, airControl | acceleration, airControl |
| Longer/faster jump | jumpForce, maxJumps if desired | gravityScale / jumpForce |
| More stable vehicle | turn/brake smoothing, recovery settings | overly aggressive steering values |
| Faster NavAgent | speed, acceleration | stoppingDistance if you want it closer before stopping |
## How to tune physics
| Goal | Typical setting | Direction |
| --- | --- | --- |
| Make dynamic body fall faster | Rigidbody2D.gravityScale | Increase above 1. |
| Make body coast longer | linearDamping | Decrease toward 0. |
| Make body stop rotating sooner | angularDamping | Increase. |
| Make contact bouncier | Collider2D.restitution | Increase. |
| Reduce sliding | Collider2D.friction | Increase. |
| Make a platform one-way | Collider2D.isOneWayPlatform | Enable; contact filtering then only allows landing from the supported side. |
## How to tune navigation
| Setting | Increase means | Decrease means |
| --- | --- | --- |
| NavWorld2D.cellSize | coarser/faster grid, less geometric detail | finer grid, narrower detail but more work |
| NavAgent2D.radius | larger clearance requirement | smaller agent clearance |
| NavAgent2D.repathInterval | less frequent replanning | more responsive replanning |
| NavWorld2D.areaCosts slot | more expensive path cost through that area | closer to the cheapest route |
## How to tune lighting
| Setting | Increase means | Decrease means |
| --- | --- | --- |
| Light.intensity | brighter/stronger contribution | dimmer |
| Light.radius | larger influence region | tighter/localized light |
| ShadowCaster.length | longer shadow reach | shorter/contact shadow |
| ShadowCaster.softness | softer/wider penumbra | crisper edge |
| LightingSettings.raymarchSteps | more samples/detail, more GPU work | less GPU work, potentially less detail |
| LightingSettings.ambientDarkness | darker unlit regions | brighter ambient base |
> **Rule for numeric documentation:** Realot Studio documentation should state not only what a field is, but what increasing and decreasing it does, its units, default, and whether the value is clamped/validated. The API catalog in api-options.json follows this model for option objects.
---
# Scene JSON
> Reference the Realot Studio scene serialization format.
## Top-level shape
```
{
"sceneName": "Level1",
"hierarchyFolders": [],
"entities": []
}
```
## Entity shape
```
{
"id": "e12",
"name": "Target",
"tag": "Target",
"active": true,
"folderId": null,
"prefabId": null,
"prefabOverrides": {},
"components": {
"Transform": { "x": 0, "y": 0, "z": 0, "rotation": 0, "scaleX": 1, "scaleY": 1 }
}
}
```
## Component registry
SceneSerializer recognizes the runtime component types: Transform, Camera, SpriteRenderer, ShapeRenderer, StrokePath, TextRenderer, SpeechBubble, ChatLog, TextInput, Joystick, Rigidbody2D, Collider2D, Joint2D, Light, ShadowCaster, CharacterController, LightingSettings, SpriteAnimation, AudioSource, AudioListener, Tileset, Tilemap, NavWorld2D, NavAgent2D and Script.
## Authoring rules
Scene files are plain JSON and can be authored by the editor, generated by tools or hand-written. The serializer deep-copies folder/prefab override data so saved snapshots do not alias live state.
## Default camera
A fresh/default scene uses a **Main Camera** entity with tag `MainCamera`, active state enabled, Transform at 0,0 and a main Camera flag.
---
# Project format
> Understand the portable .realot archive and the difference between editable projects and standalone game exports.
## Current project file
**Save Project** downloads a `.realot` file. The extension identifies Realot's portable project file, which the editor reads as a complete project package.
## Archive contents
| Entry | Purpose |
| --- | --- |
| `manifest.json` | Project name, engine compatibility metadata and save information. |
| `scenes/index.json` | Scene list and active scene information. |
| `scenes/*.json` | Serialized scene entities and component data. |
| `assets/sprites.json`, `frames.json`, `audio.json` | Asset catalogues and references to binary asset files. |
| `assets/bin/` | Binary image/audio data referenced by the asset catalogues. |
| `scripts.json` | User-authored JavaScript source. |
| `prefabs.json` | Saved prefab definitions. |
| `layers.json`, `navAreas.json`, `tags.json` | Project-wide layer, navigation-area and tag names. |
## Open a project
Use the editor's **File → Load Project** command to open a saved `.realot` project. On a desktop browser that supports PWA file handling, you can also install Realot Hub and double-click a downloaded `.realot` file to open it in the editor.
## Project archive versus game export
A `.realot` archive is an editable project that can be loaded back into the editor. An HTML5/PWA export is a separate standalone game package with `index.html` at its root, containing the runtime and files needed to run the game. The Android build service consumes the standalone game export, not the editable project file.
## Compatibility metadata
The project manifest includes engine compatibility metadata. The loader compares it with the engine build and can warn when a project was saved by a newer engine. This metadata belongs to the project format; it is not a documentation version or a user-facing engine download version.
---
# Engine conventions (RULES.txt)
> The architectural rules that govern how Realot Studio’s own codebase is organized.
## Scope
This is the engine’s own internal contract for where code goes and how the three top-level folders relate. It applies to people extending Realot Studio itself; if you’re only writing game scripts, you don’t need it — see Scripting quickstart instead.
## 1. The core rule: runtime never depends on editor
`runtime/` is the actual game engine. `editor/` is the Unity-style level editor UI, a development tool only. `target/` is the standalone game shell, importing only from `runtime/`. No file under `runtime/` may ever import, reference, or depend on anything under `editor/` — not for debugging, not temporarily, not ever. You must be able to delete the `editor/` folder entirely and the game (`standalone runtime play entry point`) keeps working with zero changes. `editor/` may import from `runtime/` — that direction is allowed and expected, since the editor is built on top of the engine.
## 2. One feature = new file(s), not a growing old file
Adding a new component, system, editor panel, scripting API, or asset type creates a new file in the appropriate subfolder. Unrelated functionality is never appended into an existing file just because it’s nearby or already open. If a feature doesn’t fit any existing subfolder, a new subfolder is created (matching the existing lowercase, pluralized naming style) rather than dumping it into an unrelated folder.
| Adding… | Goes in… |
| --- | --- |
| A new gameplay component | runtime/components/YourComponent.js |
| A new gameplay/rendering/physics system | runtime/systems/YourSystem.js |
| A new editor panel | editor/panels/YourPanel.js |
| A new asset type | runtime/assets/YourManager.js |
| A new scripting capability | A method/property on the relevant file in runtime/scripting/components/, or a new file there |
## 3. Components stay plain data
Files under `runtime/components/` hold only plain serializable data (numbers, strings, booleans). No PixiJS objects, no DOM references, no behavior/update logic — behavior belongs in `runtime/systems/`. This is what keeps SceneSerializer.js able to save and load any component generically.
## 4. Rendering is centralized
`runtime/systems/RenderSystem.js` is the only place that creates or updates PixiJS display objects from entity data. Both the editor’s viewport and the standalone target use it, so visuals never drift between edit mode and play mode. Editor-only chrome (grid lines, selection gizmos) may be drawn in its own separate layer on top of the runtime’s render output — that chrome must never be visible in `/target`.
## 5. Scene data flows through the runtime’s public API only
The editor never invents its own scene format or its own copy of scene state. The single source of truth is the live World instance, and the single way to read/write its persisted form is `runtime/scene/SceneSerializer.js`. New scene-level functionality (undo, multi-scene, prefabs) extends the runtime’s `scene/` folder, not the editor’s `state/` folder.
## One API per capability (scripting)
`this.x`, `this.y`, `this.position`, `this.rotation`, `this.translate()`, and `this.visible` are flat shortcuts because Transform has only one shape. Everything else — velocity, physics forces, sprite properties, animation, camera, audio, movement-type tunables — is reached only through its sub-object (`this.rigidbody.*`, `this.sprite.*`, `this.controller.*`, etc). There is deliberately no flat-shortcut duplicate of any of these, because RigidbodyAPI exposes a different shape per body type and ControllerAPI exposes a different shape per controller type — a second flat copy would either duplicate that per-type logic or drift out of sync with it.
> **Source note:** These rules come from the engine repository’s RULES.txt . That file is not included in the client distribution ( project/ contains editor/ , player/ , runtime/ and vendor/ only), so it is documented here rather than linked.
---
# Debugging
> Diagnose common Realot Studio runtime and authoring problems.
## Use the Debug HUD
The `debug` module can show the HUD, FPS and logging. Performance/profiling displays are useful while diagnosing update and rendering behavior.
## Lifecycle failures
If a lifecycle callback throws, the runtime reports the error and isolates it. Look for the callback name and error classification in the runtime output.
## Physics checklist
- Confirm the entity has the expected Rigidbody2D body type.
- Confirm Collider2D shape, layer and mask settings.
- For one-way platforms, test motion from both sides.
- Use `physics.raycast(...,{debug:true})` to verify what the query actually sees.
## Navigation checklist
- Confirm a NavWorld2D exists in the scene.
- Confirm the queried point is inside walkable bounds.
- Check NavAgent2D radius/area settings.
- Use `nav.findPath(...,{debug:true})` to visualize the result.
## Common API mistake
> **Editor code is not game code:** If code is only found in project/editor/ , it is not automatically a supported game-script API. The public script surface is the documented this.\* context and global runtime modules.
---
# Security and play origin
> Understand the script trust boundary and why shared projects should run on a separate origin.
> **Game scripts are not a security sandbox:** Project scripts execute as ordinary JavaScript in the game page. Treat scripts inside imported projects as code from another person, not as inert project data.
## Script execution
Realot shadows selected browser globals inside its script environment as a guardrail against accidental access. This is not a hardened security boundary: scripts are compiled and run as page code. Do not open a project containing scripts unless you trust its source.
## Use a separate play origin for shared projects
For a deployment where people can open projects from others, configure the editor to launch Play on a separate hostname that serves the same Realot files. In `project/editor/index.html`, set the `realot-play-origin` meta tag to that HTTPS origin:
```
```
The editor sends the scene to the play page using `postMessage`. Because the two hostnames are different origins, browser same-origin policy keeps the play page's localStorage, IndexedDB and DOM separate from the editor's. Leave the meta content empty and Play uses the same origin; that is less isolated and is not recommended for untrusted projects.
## Offline behavior
If the configured play origin cannot be reached, such as while offline, the editor can fall back to same-origin Play and logs a warning. Data saved by the game on the play origin is separate from the editor origin's storage.
## Other protections
- Messages are accepted only from the corresponding editor/play window and expected origin.
- Console output and project-controlled names are escaped before display in the editor UI.
- Loading a project containing scripts asks for confirmation first.
- Exported games run on the origin where the developer hosts them; they are separate from the editor's Play-origin setting.
## APK build credentials
The APK service URL is public configuration. Permanent service credentials must not be placed in the static editor source because all shipped JavaScript can be inspected by visitors. The editor's intended managed flow requests a short-lived token from the service and renews it when needed. The service must still enforce appropriate quotas and access controls; a public token-issuance endpoint alone does not identify an approved user.
---
# Live updates
> How the hosted Realot Studio website and its documentation are updated in place.
## Browser delivery
Realot Studio is delivered as a web application. The hosted Hub, editor and runtime are loaded from the site's published files. Users do not need to download a new engine installer whenever the site owner publishes an update.
## The website address stays the same
Publishing a new engine build replaces the files served at the existing deployment URL. The same is true of the documentation: its unversioned topic URLs point to the current published documentation.
## Browser and PWA caching
A normal browser visit retrieves the published site files according to the deployment's cache headers. An installed PWA or a browser with the service worker may continue using cached files while offline. Reconnect and reload to allow the new published files to be fetched. A deployment should publish its files atomically and configure cache headers so the HTML entry points and service worker can update.
## Project compatibility is separate
Although the hosted engine is updated in place, saved project archives may contain engine compatibility metadata. When a project saved by a newer engine is opened in an older build, Realot may show a compatibility warning. That project metadata is not a documentation URL version.
---
# Source map & verification
> A source-grounded map of where Realot Studio’s public behavior and editor controls are actually implemented.
> **Verified source:** This documentation pass was checked against the supplied Realot Studio engine source, including runtime components, scripting API modules, editor panels/state, navigation, physics, scene serialization, and export code.
## Engine architecture map
| Area | Primary source locations | Purpose |
| --- | --- | --- |
| Public runtime entry | `project/runtime/index.js` | Wires World + systems + scripting and exposes createGame(). |
| Components | `project/runtime/components/` | Serializable component data used by scene entities. |
| Systems | `project/runtime/systems/` | Runtime behavior such as physics, rendering, animation, lighting, audio, navigation and scripting. |
| Scripting | `project/runtime/scripting/` | User-facing script surface, EntityContext and option metadata. |
| Physics | `project/runtime/physics/` | Rapier-backed collider/body/joint queries and contact behavior. |
| Navigation | `project/runtime/pathfinding/` | A\* grid bake, dynamic bake, area masks/costs and navigation support. |
| Editor UI | `project/editor/panels/` | Toolbar, Hierarchy, Inspector, Project/Console, animation, tileset, export and settings windows. |
| Editor state/events | `project/editor/state/` | Persistence, dirty state, layer/area registries and DOM event handling. |
| Scene serialization | `project/runtime/scene/SceneSerializer.js` | Serialized scene/entity component format. |
## Important source files for documentation truth
| Question | Verify here |
| --- | --- |
| What components exist? | `project/runtime/components/*.js` |
| What script members exist? | `project/runtime/scripting/components/*API.js` + `ScriptAPI.js` |
| What opts are accepted? | `project/runtime/scripting/NavAPI.js` and the relevant ScriptAPI doc comments |
| Where is a button? | `project/editor/panels/*.js` |
| What appears only conditionally? | `project/editor/panels/Toolbar.js` + `editor/state/EditorEvents.js` |
| How does an interaction actually behave? | Relevant runtime system + component + tests in the same area. |
---
# AI Bridge: connect an AI assistant
> Connect an MCP-compatible AI app to the open Realot Studio editor using the built-in shared relay, with optional self-hosting, read-only mode and a complete source-derived tool catalog.
> **Built in and ready to use:** Realot Studio includes a shared relay address. Most users do not need to install Node.js, configure a local server, create a Cloudflare account or deploy anything. Open AI Bridge, copy the private link into an AI app that supports remote MCP connectors, and press Connect in Realot.
## Connect your AI assistant
1. Open your project in Realot Studio and click **AI Bridge** in the editor.
2. Click **Copy link** in the panel.
3. In your AI app, open its connector or MCP-server settings. Add a **remote MCP server** or **custom connector**, paste the copied link, and name it **Realot**. The exact menu name depends on the AI app.
4. Return to Realot and click **Connect**. The panel should show **Connected**. Ask the AI to inspect the open project before asking it to make changes.
The copied link contains a private secret key. Treat it like a password: anyone who has the link may be able to use the tools exposed by your open editor. Do not post it in public messages or commit it to a project repository.
## AI Bridge panel options
| Option | What it does |
| --- | --- |
| **Copy link** | Copies the private remote MCP connector URL for this editor. |
| **Connect / Disconnect** | Starts or closes the editor's connection to the relay. The editor must remain open while the AI works on the live project. |
| **Read-only** | Blocks tools that change the project. The AI can inspect the editor but cannot perform supported edit operations while this is enabled. |
| **Connect automatically when the editor opens** | Remembers the preference and reconnects on a later editor launch when a private key is already configured. |
| **Make a new private link** | Creates a new secret key and invalidates the old link. Add the new link to your AI app; the old connector URL will no longer authenticate. |
| **Need more AI time? → click here to host it** | Opens Cloudflare's deployment flow for an optional personal copy of the relay. This is not needed for the built-in shared relay. |
| **Use it / Default** | *Use it* switches to the relay URL you supplied and refreshes the connector link. *Default* switches back to Realot's built-in shared relay. Re-copy the connector link after changing relay addresses. |
## Shared relay time allowance
The built-in shared relay includes **30 minutes of active AI work in each 24-hour usage window**. Time is counted while a tool call is running and for up to 20 seconds between calls. Being connected while the AI is idle does not use the allowance. The panel shows the remaining time and the reset countdown.
The usage record is kept in this browser's local storage. It is a client-side allowance display and should not be treated as an account-wide quota or a tamper-proof billing record. Hosting your own relay removes the shared-relay active-time limit; Cloudflare account usage and service terms may still apply.
## Optional: host a personal relay
Most users should stay on the built-in relay. Hosting your own is an advanced option for users who want to avoid the shared-relay time allowance or operate their own relay endpoint.
1. In the AI Bridge panel, select **click here to host it**. Realot opens the Cloudflare deployment page for the relay source repository.
2. Complete Cloudflare's deployment and copy the HTTPS address ending in `.workers.dev`.
3. Paste that address into the relay field in the AI Bridge panel and click **Use it**.
4. Click **Copy link** again and replace the old Realot connector URL in your AI app. Connect from the editor.
To return to the shared relay, click **Default**, copy the refreshed link, and update the connector in your AI app. A personal relay has no Realot active-AI-minutes cap, but you are responsible for its deployment, availability and Cloudflare account.
## What the AI can do
The built-in relay currently exposes **80 MCP tools**. They allow an AI app to inspect editor state, scenes and entities; create and modify entities and components; read, write and attach scripts; start or pause play mode; inspect the Console and capture a screenshot; manage assets and chunked uploads; edit animation clips and frames; manage tilesets and tilemaps; paint navigation cells and configure navigation and physics layers; manage tags, folders, prefabs and scenes; save or export project data; and control editor panels and tools.
The tables below list every hosted tool name and its input fields. Fields shown in bold are required. Full JSON input schemas—including exact types, constraints and additional properties—are published in the [machine-readable API catalog](../../api/index.json) under `aiBridge.sharedRelayTools`.
## Complete hosted MCP tool catalog
### Project and scene inspection
| Tool | What it does |
| --- | --- |
| `get_editor_state` Inputs: none | Overview of the open Realot editor: project name, whether the game is playing, selected entity ids, entity count, available component types. |
| `list_entities` Inputs: `limit`: integer | List every entity in the current scene (id, name, tag, active, component types, x/y position). |
| `get_entity` Inputs: **`id`: string (required)** | Full data of one entity: all components with every property. |
| `list_scenes` Inputs: none | List every scene in the project and which one is active. |
### Entities and components
| Tool | What it does |
| --- | --- |
| `create_entity` Inputs: **`name`: string (required)**; `x`: number; `y`: number; `tag`: string; `components`: object | Create an entity. 'components' maps a component type (e.g. SpriteRenderer, Collider2D, Rigidbody2D, Script) to its properties. A Transform is always added. Undoable with undo. Values are validated: wrong types, unknown properties, invalid enum values (e.g. Light.type), out-of-range numbers, bad hex colors and values the engine would silently clamp are rejected with a message listing every problem and the allowed values; nothing is changed on error. |
| `update_component` Inputs: **`id`: string (required)**; **`type`: string (required)**; **`props`: object (required)** | Change properties of an existing component on an entity (only properties the component already has). Use get\_entity first to see them. Values are validated: wrong types, unknown properties, invalid enum values (e.g. Light.type), out-of-range numbers, bad hex colors and values the engine would silently clamp are rejected with a message listing every problem and the allowed values; nothing is changed on error. |
| `add_component` Inputs: **`id`: string (required)**; **`type`: string (required)**; `props`: object | Add a component to an entity. Values are validated: wrong types, unknown properties, invalid enum values (e.g. Light.type), out-of-range numbers, bad hex colors and values the engine would silently clamp are rejected with a message listing every problem and the allowed values; nothing is changed on error. |
| `remove_component` Inputs: **`id`: string (required)**; **`type`: string (required)** | Remove a component (not Transform) from an entity. |
| `delete_entities` Inputs: **`ids`: array (required)** | Delete entities by id (same as pressing Delete in the editor). Undoable. |
| `select_entities` Inputs: **`ids`: array (required)** | Select entities in the editor so the user sees them in the Inspector. |
| `update_entity` Inputs: **`id`: string (required)**; **`patch`: object (required)** | Rename an entity or change its tag, active flag, or hierarchy folder. Use update\_component for Transform and other components. |
| `create_scene` Inputs: `name`: string; `switch`: boolean | Create a new scene (with a Main Camera). Switches to it unless switch=false. |
| `switch_scene` Inputs: **`scene_id`: string (required)** | Make another scene the active one in the editor. |
| `rename_scene` Inputs: **`scene_id`: string (required)**; **`name`: string (required)** | Rename a scene. |
| `delete_scene` Inputs: **`scene_id`: string (required)**; `confirm`: boolean | Delete a scene. Cannot be undone, so the first call only reports what would be deleted; repeat with confirm=true. A project must keep one scene. |
| `duplicate_scene` Inputs: **`scene_id`: string (required)** | Duplicate a scene (deep copy) and add it to the project. Does not switch to it. |
### Scripts, play mode and diagnostics
| Tool | What it does |
| --- | --- |
| `list_scripts` Inputs: none | Names of all scripts in the project. |
| `get_script` Inputs: **`name`: string (required)** | Source code of a script. |
| `write_script` Inputs: **`name`: string (required)**; **`source`: string (required)** | Create or overwrite a script's source code. Entities already using this script get the new code too. Reports syntax errors. |
| `attach_script` Inputs: **`id`: string (required)**; **`scriptName`: string (required)** | Attach an existing script to an entity (adds a Script component). |
| `set_playing` Inputs: **`playing`: boolean (required)** | Start or stop play mode (opens the game in the play window). |
| `get_console` Inputs: `limit`: integer | Recent editor/play console lines (logs, warnings, script errors). |
| `screenshot` Inputs: none | Image of the scene viewport as the user sees it. |
| `undo` Inputs: none | Undo the last editor change. |
| `redo` Inputs: none | Redo the last undone change. |
| `delete_script` Inputs: **`name`: string (required)**; `confirm`: boolean | Delete a script from the project and clear it from objects using it. Cannot be undone, so the first call reports usage; repeat with confirm=true. |
| `set_script_enabled` Inputs: **`id`: string (required)**; **`enabled`: boolean (required)** | Enable or disable the Script component on an entity without removing it. |
| `set_paused` Inputs: **`paused`: boolean (required)** | Pause or resume the running game. The game must be playing (see set\_playing). |
### Assets and uploads
| Tool | What it does |
| --- | --- |
| `list_assets` Inputs: `kind`: string [all, sprite, animation, frame, tile, audio]; `query`: string; `limit`: integer | List imported images and audio without returning binary data, grouped like the editor's Project folders: Sprites, Animation Clips (uploaded animation frames) and Tiles (tileset images), plus Audio. Use the keys in SpriteRenderer, AudioSource, animation clips, and tilesets. |
| `begin_asset_upload` Inputs: **`file_name`: string (required)**; **`mime_type`: string (required)**; **`size_bytes`: integer (required)**; **`purpose`: string [sprite, audio, animation-image, animation-zip, animation-gif, animation-sheet, tileset-sheet, tileset-tile, frame-asset, tile-asset, project-zip] (required)**; `entity_id`: string; `clip_id`: string; `tileset_entity_id`: string; `role`: string; `grid_cols`: integer; `grid_rows`: integer; `group`: string | Start uploading a custom asset: a sprite, audio file, animation source, tileset image, or a loose image for the Animation Clips folder (purpose 'frame-asset') or Tiles folder (purpose 'tile-asset'). Then send sequential base64 chunks with append\_asset\_upload\_chunk and finish with complete\_asset\_upload. The editor must be open and connected. Maximum 20 MiB per file. Purpose 'project-zip' (a .realot project, max 20 MiB) REPLACES the entire open project and asks the person at the editor to confirm. Animation uploads land in the Animation Clips folder; tileset uploads land in the Tiles folder. |
| `append_asset_upload_chunk` Inputs: **`upload_id`: string (required)**; **`chunk_index`: integer (required)**; **`chunk_base64`: string (required)** | Send one base64-encoded binary chunk for an active asset upload. Chunks must be independent base64 strings, sequential from index 0. Use the chunk size returned by begin\_asset\_upload; retrying the same index and data is safe. |
| `complete_asset_upload` Inputs: **`upload_id`: string (required)** | Validate and import all received bytes using the editor's native import pipeline. Call only after every chunk has been accepted. |
| `cancel_asset_upload` Inputs: **`upload_id`: string (required)** | Discard a staged upload before it is imported. |
| `rename_asset` Inputs: **`key`: string (required)**; **`kind`: string [sprite, frame, animation, tile, audio] (required)**; **`name`: string (required)** | Rename an imported sprite, animation frame, tile or audio asset while preserving its key and references. |
| `delete_asset` Inputs: **`key`: string (required)**; **`kind`: string [sprite, frame, animation, tile, audio] (required)**; `confirm`: boolean | Delete an imported asset. If the asset is referenced by scenes or prefabs, the first call reports those references; set confirm=true only when it is acceptable to leave them unresolved. |
| `slice_asset_into_tileset` Inputs: **`entity_id`: string (required)**; **`asset_key`: string (required)** | Cut one existing project image (for example an uploaded sprite) into a 4x4 grid and fill all 16 Tileset slots with the pieces. The pieces are saved in the Tiles folder under the tileset's name. Undoable. |
### Animation
| Tool | What it does |
| --- | --- |
| `list_animations` Inputs: none | List animation clips and ordered frame keys for every entity in the active scene. |
| `create_animation_clip` Inputs: **`entity_id`: string (required)**; `name`: string; `fps`: number; `loop`: boolean | Create an empty animation clip on an entity, adding SpriteAnimation if needed, and open it in the animation editor. |
| `update_animation_clip` Inputs: **`entity_id`: string (required)**; **`clip_id`: string (required)**; **`fields`: object (required)** | Change an animation clip name, frame rate, loop setting, or collider override. Set collider\_override to null to remove the override. |
| `delete_animation_clip` Inputs: **`entity_id`: string (required)**; **`clip_id`: string (required)** | Delete one animation clip from its entity. The remaining clips and frames are preserved. |
| `move_animation_frame` Inputs: **`entity_id`: string (required)**; **`clip_id`: string (required)**; **`from_index`: integer (required)**; **`to_index`: integer (required)** | Reorder an animation frame by moving it from one zero-based position to another. |
| `delete_animation_frame` Inputs: **`entity_id`: string (required)**; **`clip_id`: string (required)**; **`frame_index`: integer (required)** | Remove one zero-based frame position from an animation clip without deleting the underlying imported asset. |
| `add_animation_frames` Inputs: **`entity_id`: string (required)**; **`clip_id`: string (required)**; **`asset_keys`: array (required)**; `index`: integer | Add images that are already in the project (sprites, Animation Clips frames, or Tiles) to an animation clip as frames. Use list\_assets for keys and list\_animations for entity/clip ids. Optional index inserts at that position instead of appending. Undoable. |
### Tilesets and tilemaps
| Tool | What it does |
| --- | --- |
| `list_tilesets` Inputs: none | List tilesets, tile dimensions, and sprite keys assigned to each role. |
| `update_tileset` Inputs: **`entity_id`: string (required)**; **`patch`: object (required)** | Edit a tileset name, tile dimensions, or selected role-to-sprite assignments. Set a slot to null to clear it. |
| `set_tileset_slot` Inputs: **`entity_id`: string (required)**; **`role`: string (required)**; **`asset_key`: string|null (required)** | Put an existing project image (sprite, animation frame or tile) in one slot of a Tileset, or clear the slot with asset\_key null. Roles come from list\_tilesets. |
| `list_tilemaps` Inputs: none | List Tilemap entities, their assigned tileset entity, painted cell count, and up to 500 grid coordinates. |
| `paint_tilemap` Inputs: **`entity_id`: string (required)**; **`mode`: string [paint, erase] (required)**; **`cells`: array (required)** | Paint or erase grid cells on a Tilemap. Coordinates are integer cell columns and rows, not world coordinates. Undoable. |
### Navigation and physics
| Tool | What it does |
| --- | --- |
| `list_navigation_worlds` Inputs: none | List NavWorld2D entities with bounds, cell size, painted cell counts, and navigation settings. |
| `paint_navigation_cells` Inputs: **`entity_id`: string (required)**; **`mode`: string [walkable, blocked, erase\_walkability, area, clear\_area] (required)**; `area_index`: integer; **`cells`: array (required)** | Paint walkable or blocked navigation cells, restore baked walkability, or set/clear navigation area indices. Coordinates are integer grid columns and rows. Undoable. |
| `update_navigation_world` Inputs: **`entity_id`: string (required)**; **`patch`: object (required)** | Edit NavWorld2D bounds, cell size, obstacle threshold, diagonal movement, dynamic mode, or all 16 area costs. Cell changes invalidate the baked runtime cache. |
| `list_navigation_areas` Inputs: none | List the 16 named navigation area slots and their indices. |
| `set_navigation_area_name` Inputs: **`index`: integer (required)**; **`name`: string (required)** | Rename one navigation area slot. Slot 0 is the default Ground area and cannot be cleared. |
| `list_physics_layers` Inputs: none | List all 16 named physics layers and their indices. |
| `set_physics_layer_name` Inputs: **`index`: integer (required)**; **`name`: string (required)** | Rename one of the 16 physics layer slots. Slot 0 is the default layer and cannot be cleared. |
| `set_collider_layer_filter` Inputs: **`entity_id`: string (required)**; **`layer`: integer (required)**; **`collides_with`: array (required)** | Set a Collider2D's physics layer and the layer indices it collides with. Use list\_physics\_layers to map names to indices. |
| `bake_navworld` Inputs: **`id`: string (required)** | Bake a NavWorld2D from the scene's colliders (the editor's Bake button). Reports walkable and blocked cell counts. |
### Tags, folders and prefabs
| Tool | What it does |
| --- | --- |
| `list_tags` Inputs: none | List the project tag registry. |
| `add_tag` Inputs: **`tag`: string (required)** | Add a tag to the registry. |
| `delete_tag` Inputs: **`tag`: string (required)** | Remove a tag from the registry (Untagged cannot be removed). |
| `list_prefabs` Inputs: none | List prefabs in the project. |
| `create_prefab` Inputs: **`id`: string (required)**; `name`: string | Create a prefab from an entity and link that entity to it. |
| `instantiate_prefab` Inputs: **`prefab_id`: string (required)**; `name`: string; `x`: number; `y`: number | Place a new instance of a prefab in the active scene. |
| `rename_prefab` Inputs: **`prefab_id`: string (required)**; **`name`: string (required)** | Rename a prefab. |
| `delete_prefab` Inputs: **`prefab_id`: string (required)**; `confirm`: boolean | Delete a prefab from the catalogue; existing instances become unlinked. First call reports impact; repeat with confirm=true. |
| `list_folders` Inputs: none | List Hierarchy folders in the active scene (id, name, parentId). |
| `create_folder` Inputs: **`name`: string (required)**; `parent_id`: string | Create a Hierarchy folder, optionally nested in another. Put entities in it with update\_entity folderId. |
| `rename_folder` Inputs: **`folder_id`: string (required)**; **`name`: string (required)** | Rename a Hierarchy folder. |
| `move_folder` Inputs: **`folder_id`: string (required)**; `parent_id`: string | Nest a folder inside another folder, or move it to the top level (omit parent\_id). Cycles are refused. |
| `delete_folder` Inputs: **`folder_id`: string (required)** | Delete a folder. Its entities and sub-folders move up one level; nothing inside is deleted. |
| `update_prefab` Inputs: **`id`: string (required)**; `apply_position`: boolean; `apply_rotation`: boolean; `apply_scale`: boolean | Push an instance's current data to its prefab and to every non-overridden instance across all scenes (the editor's Update Prefab). |
| `revert_prefab` Inputs: **`id`: string (required)** | Reset a prefab instance to its prefab's data, discarding overrides. |
| `unpack_prefab` Inputs: **`id`: string (required)** | Unlink an instance from its prefab, keeping its current data. |
### Export and project files
| Tool | What it does |
| --- | --- |
| `save_project` Inputs: none | Save now (browser autosave slot, and the .realot file if one is being kept up to date). |
| `export_game` Inputs: **`format`: string [html, pwa] (required)**; `title`: string; `download`: boolean | Build the game as a standalone HTML5 or PWA ZIP. By default it also downloads the ZIP in the editor's browser; read the bytes with read\_export\_chunk. APK builds are not supported through MCP. |
| `read_export_chunk` Inputs: **`export_id`: string (required)**; **`chunk_index`: integer (required)** | Read one base64 chunk of the last export\_game ZIP. |
| `release_export` Inputs: **`export_id`: string (required)** | Free the memory held by the last export\_game result. |
| `download_project_zip` Inputs: `name`: string; `optimize_assets`: boolean | Save the whole project as a .realot ZIP, downloaded in the editor's browser (File > Save Project without a file handle). |
### Editor controls
| Tool | What it does |
| --- | --- |
| `open_editor_panel` Inputs: **`panel`: string [animation, tileset, physics\_layers, navigation\_areas] (required)**; `entity_id`: string; `clip_id`: string | Open the animation editor, tileset editor, physics-layer panel, or navigation-area panel. Animation and tileset panels need the matching entity\_id. |
| `set_editor_tool` Inputs: **`tool`: string [select, translate, rotate, scale, pan, tile, erase, nav, nav-block, nav-area, path] (required)**; `entity_id`: string | Choose a viewport tool and optionally select its Tilemap, NavWorld2D, or StrokePath entity so the user can continue painting in the editor. |
## Safe and reliable use
- Start with project inspection. Ask the AI to identify the active scene, selected objects and relevant components before it edits anything.
- Use **Read-only** when you only want explanations or an audit.
- Ask the AI to make a small change first, then inspect the result in the editor and test it in Play mode.
- Use undo for supported scene edits. Do not assume every operation—especially script writes, project-file operations or scene-list changes—can be reversed in the same way. Save a project backup before large edits.
- Review generated JavaScript. Project scripts execute as browser page code and are not an isolated security sandbox. Do not run untrusted scripts or import project archives from sources you do not trust.
- Tool results may contain project names, scenes, scripts, assets and Console output. These are sent to the connected AI app; use an AI provider you trust and avoid connecting projects containing secrets or private data.
- Disconnect when finished and keep the private connector URL secret. Use **Make a new private link** if you think the link has been exposed.
## About the included local MCP companion source
The engine archive also contains a Node.js stdio companion under `mcp-bridge/` and an editor integration module under `project/editor/mcp/EditorBridge.js`. In this supplied build, that editor integration's installer is not called by the editor startup path. The local companion is therefore not a supported, ready-to-connect alternative in the packaged editor. Use the built-in shared relay described above. Developers who want a local stdio integration must first wire and test the companion against the editor; its 23 local tool definitions are not the same interface as the 80 tools exposed by the live shared relay.
> **For AI clients and coding agents:** Start with For AI assistants & LLMs , then read the script-module reference and global runtime API when generating game scripts. AI Bridge tools edit the editor; script APIs run inside the game. They are different interfaces.
---
# AI assistants and documentation search
> How people and AI tools can find accurate Realot Studio documentation from the documentation URL alone.
> **One URL is enough to start:** Fetch llms.txt from the documentation root, then query api/search?q=your%20question . The search endpoint returns the closest matching guides and API pages with the correct relative URLs.
## Pages are directly readable
Each guide is static HTML with the full article text, headings, links, tables and code examples already in the page. JavaScript enhances navigation and search; it is not required to retrieve the documentation content. Every guide also has a Markdown twin at the same path with the `.md` suffix.
## Retrieval workflow
1. Start with the documentation URL you were given. Resolve the site's root, preserving a deployment prefix such as a GitHub Pages repository path.
2. Fetch `llms.txt` from that root. It is a compact map of the documentation sections and retrieval process.
3. Send the full question to `api/search?q=...` using URL encoding. The endpoint searches titles, descriptions, headings, keywords and page text, then ranks the closest matches.
4. Read the top results returned by the endpoint. Each result includes a relative `url`, title, section, relevance score and a useful text snippet. Resolve the returned URL against the documentation root; do not construct page paths yourself.
5. For broad questions, fetch `llms-full.txt`. If the endpoint is unavailable, fetch `search-index.json` and perform the same retrieval locally.
6. For exact engine API questions, fetch `api/index.json` and the human-readable [complete script module index](../api/script-modules.html). The JSON lists component scene fields/defaults, all lifecycle callbacks, enum values, all 24 script API modules and their supported member names, plus global API groups.
The [human search page](../../search.html) uses the same ranking behavior. The endpoint is a relevance-ranked documentation search, not a generative AI model: it returns the closest source pages for the assistant to read and use.
## Machine-readable files
| Path from docs root | Contents |
| --- | --- |
| `llms.txt` | Compact index with exact discovery and retrieval instructions. |
| `llms-full.txt` | Full documentation text in one Markdown file. |
| `api/search?q=...` | Question-based search endpoint. Returns the closest matching pages, snippets, relevance scores and relative URLs. |
| `search-index.json` | Complete page search records, including content text, headings and keywords; fallback for tools that cannot call the endpoint. |
| `api/index.json` | Source-derived component and script API catalog, including every supported module member name and component field/default. |
| `api/manifest.json` | Catalog metadata and counts. |
| `sitemap.xml` | Absolute page URLs when built with the public documentation origin. |
| `robots.txt` | Crawler access policy. |
## Editor automation
For an assistant that needs to operate the currently open editor, use the [AI Bridge and MCP reference](ai-bridge.html). The bridge tools modify live project data; they are distinct from the gameplay scripting API catalog.
## Use engine source as the ground truth
The component field catalog is extracted from the runtime component constructors. The script module member lists come from each API module's exported allow-list. Human explanations complement these lists but should not be treated as permission to call undocumented engine internals. If an API member is absent from the source-derived allow-list, do not recommend it as supported.
The documentation uses stable, unversioned URLs. Publishing an updated engine and documentation replaces the current reference at those same paths; users do not need a separate documentation version download.
## Publishing requirements
Build with the public documentation origin so canonical links and `sitemap.xml` contain absolute URLs. Keep `llms.txt`, `llms-full.txt`, `search-index.json`, `api/index.json`, the HTML guides and their Markdown copies together at the same site root. Deploy the included `functions/api/search.js` with Cloudflare Pages Functions to enable `/api/search`.
---
# Realot Studio reference for AI assistants
> Practical rules for AI assistants that explain, script, debug and extend Realot Studio projects accurately.
## What is Realot Studio?
Realot Studio is a browser-based 2D game engine with a visual editor, an entity/component runtime, JavaScript gameplay scripts, PixiJS rendering and Rapier2D physics. The Hub and editor run as web applications. The hosted build is updated by publishing web files; users do not install a separate engine executable.
## Retrieve the relevant reference first
Given only the documentation homepage URL, fetch `llms.txt` from its root, then send the user question to `api/search?q=...`. Read the closest returned pages; the endpoint supplies their paths, so do not guess URLs. For API questions, also fetch `api/index.json` and the [complete script module member index](../api/script-modules.html). The JSON catalog is generated from source facts and is the authoritative list of supported component fields, enum values and API module members. Read the linked guide for behavior, prerequisites and examples.
## AI Bridge and editor automation
When an MCP-connected assistant needs to inspect or edit the open project, use the [AI Bridge and MCP guide](ai-bridge.html). It lists the current tools, connection requirements and limits. Do not assume the hosted relay is deployed: it requires a Realot operator to configure it. The MCP tool schemas supplied by the live connection are authoritative for parameters.
## Gameplay script model
Inside a script callback, `this` refers to the entity that owns the script. Transform shortcuts such as `this.x` and `this.y` are always available. Component sub-objects such as `this.rigidbody`, `this.sprite` and `this.camera` require their matching components. `this.transform`, `this.state` and `this.myTouch` are available on every entity. Use the [`this` reference](../api/this.html) for the full context model.
## Source and runtime rules
- Use only documented member names in the module allow-lists; unknown member names raise a typed runtime API error. The member index also flags a known allow-list gap: `this.joint.flexibility` is listed but has no working script accessor in the supplied source; set it in the Inspector.
- Check component requirements before suggesting a component-backed API.
- Use `onUpdate(dt)` for frame-time behavior and `onFixedUpdate(dt)` for fixed-step logic.
- Use entity/world coordinates for Transform, mouse/touch world positions, physics hits and navigation waypoints. Screen coordinates are canvas pixels.
- Do not reach into editor implementation files from gameplay scripts. Keep editor-only code and runtime code separate.
- Project scripts execute as page code; imported scripts should be treated as executable content, not as a secure sandbox.
## Editor settings and components
The editor has no single general Settings dialog. Project/backup choices are in File, layer and navigation-area names are in Edit, panel visibility is in Window, and component fields are in the Inspector. The [Editor settings guide](../editor/settings.html) lists all current menu options and stored performance defaults. The [API index](../api/index.html) links all 25 components and their settings.
## Export behavior
- **HTML5:** downloads a standalone web game package.
- **PWA:** adds a manifest and service worker for installation/offline support.
- **Android APK:** the user clicks Export, chooses Android APK, and downloads the built APK when the remote service finishes. The current editor allowance is 3 APK exports in a rolling 14-day period. A failed or cancelled job returns its count. The output is debug-signed, not Play Store production-signed.
- **Desktop:** shown as coming soon in the supplied Export window.
## Project files
The official portable project file uses the `.realot` extension. Users can install Realot Hub as a PWA on a supported desktop browser, then double-click a downloaded `.realot` file to open that project in the editor. Realot can request permission to save changes back to the same file. If PWA file handling is unavailable, users can open the editor and choose **File → Load Project**.
---
# Transform
> Realot Studio Transform component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Transform component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector (right side) → Transform component, automatically present on every GameObject. Use W/E/R toolbar tools for scene manipulation.
## What it does
Position, rotation and scale. Every spatial entity uses a Transform.
> **Component setup & editor tools:** Transform is automatically present on entities. Select an entity in the Hierarchy; its Transform section appears in the Inspector.
## How to add and use Transform
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Transform** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select an entity in the Hierarchy; edit Transform fields in the Inspector. Use the Scene viewport transform gizmo to move/rotate/scale visually.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `x` | number | World position X. | `0` |
| `y` | number | World position Y. | `0` |
| `z` | number | Pseudo-3D depth; affects sprite scale only when Camera.enablePseudo3D is enabled. | `0` |
| `rotation` | number | Rotation in degrees around Z. | `0` |
| `scaleX` | number | Horizontal scale multiplier. | `1` |
| `scaleY` | number | Vertical scale multiplier. | `1` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `x / y` | World position. Increasing X moves right; increasing Y moves down in the engine’s 2D world convention. |
| `rotation` | Degrees clockwise visually in the screen coordinate convention; 0 points along +X for directional/spot light orientation. |
| `scaleX / scaleY` | 1 is native scale; >1 enlarges; 0.5 halves size; negative values mirror the corresponding axis. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `lookAt(x, y)` | Method | Point the entity toward a world-space point. |
| `position` | Property (read/write) | { x, y } world-space position; read or assign. |
| `rotation` | Property (read/write) | Rotation in degrees. |
| `scale` | Property (read/write) | Exposed by this script module. |
| `translate(dx, dy)` | Method | Move by a delta amount. |
## Examples
```
this.position = { x: 200, y: 120 };
```
```
this.rotation = 45;
```
```
this.translate(50 * time.deltaTime, 0);
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# SpriteRenderer
> Realot Studio SpriteRenderer component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the SpriteRenderer component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Sprite Renderer; choose or import sprites from bottom Project → Sprites, then assign the Sprite Renderer sprite.
## What it does
Draw a 2D texture sprite for an entity.
> **Component setup & editor tools:** In the Inspector, use the SpriteRenderer section to choose the sprite, then use its visual fields and the Scene viewport to verify the result.
## How to add and use SpriteRenderer
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **SpriteRenderer** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Inspector → SpriteRenderer → sprite field: choose the sprite asset. Use the viewport to see the result. FlipX/FlipY are visual orientation controls; color/opacity change appearance without changing the source asset.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `spriteKey` | nullable value | Asset key for the sprite texture. | `null` |
| `color` | hex color string | Tint color. | `#ffffff` |
| `opacity` | number | Opacity multiplier. | `1` |
| `flipX` | boolean | Mirror horizontally. | `false` |
| `flipY` | boolean | Mirror vertically. | `false` |
| `visualRotation` | number | Visual-only rotation in degrees, added to Transform.rotation when drawing. | `0` |
| `referenceWidth` | nullable value | Optional reference width used by rendering/layout. | `null` |
| `referenceHeight` | nullable value | Optional reference height used by rendering/layout. | `null` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `opacity` | 0 is invisible; 1 is fully opaque; values between are translucent. |
| `flipX / flipY` | Boolean mirror. Flip X changes left/right without changing the Transform position. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `color` | Property (read/write) | Hex tint color. |
| `flipX` | Property (read/write) | Horizontal mirror. |
| `flipY` | Property (read/write) | Vertical mirror. |
| `opacity` | Property (read/write) | The `this.sprite` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `texture` | Property (read/write) | Sprite asset key. |
| `visualRotation` | Property (read/write) | The `this.sprite` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
this.sprite.texture = "target";
```
```
this.sprite.flipX = input.keyDown("ArrowLeft");
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# ShapeRenderer
> Realot Studio ShapeRenderer component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the ShapeRenderer component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Create directly from top GameObject → Shape → Square/Circle/Capsule/Triangle, or Inspector → Add Component → Shape Renderer.
## What it does
Draw a procedural 2D shape without requiring a sprite asset.
> **Component setup & editor tools:** Use ShapeRenderer when you want a procedural shape without importing an image.
## How to add and use ShapeRenderer
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **ShapeRenderer** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Inspector → ShapeRenderer: choose the shape type and edit its dimensions. For triangle/freeform shapes, the corresponding viewport gizmo is used when available.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `shapeType` | ShapeType enum: Square | Circle | Triangle | Capsule | Square, Circle, Triangle or Capsule. | `Square` |
| `width` | number | Square | `100` |
| `height` | number | Square height. | `100` |
| `radius` | number | Circle | `50` |
| `capsuleHalfHeight` | number | Capsule: a "stadium" shape (rectangle with semicircle caps), same halfHeight/radius convention as Collider2D's capsule so the two stay easy to eyeball-match if a user wants a visual capsule over a capsule collider. | `50` |
| `capsuleRadius` | number | Capsule cap radius. | `30` |
| `trianglePoints` | array | Triangle: 3 points in the entity's LOCAL space (same space Collider2D.trianglePoints uses), user-editable via draggable gizmo handles in the Scene view. | `[{x:-50,y:50}, {x:50,y:50}, {x:0,y:-50}]` |
| `fillColor` | hex color string | Fill color. | `#3a8ede` |
| `visualRotation` | number | Visual-only rotation in degrees, added to Transform.rotation when drawing. | `0` |
| `opacity` | number | Opacity. | `1` |
| `outlineEnabled` | boolean | Enable outline. | `false` |
| `outlineColor` | hex color string | Outline color. | `#ffffff` |
| `outlineWidth` | number | Outline width. | `2` |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `capsuleHalfHeight` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `capsuleRadius` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `fillColor` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `height` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `opacity` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineColor` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineEnabled` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineWidth` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `radius` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `shapeType` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `visualRotation` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `width` | Property (read/write) | The `this.shape` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
this.shape.fillColor = "#22c55e";
```
```
this.shape.shapeType = "Circle";
```
```
this.shape.radius = 32;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# TextRenderer
> Realot Studio TextRenderer component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the TextRenderer component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top UI menu → Text, or Inspector → Add Component → Text; screen-space text is authored from the same Inspector component.
## What it does
Render text either in world space or as screen-space UI.
> **Component setup & editor tools:** TextRenderer displays text as a screen/world-space rendering component depending on the entity/camera context.
## How to add and use TextRenderer
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **TextRenderer** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Inspector → TextRenderer: edit the text and presentation properties. For runtime changes, use the documented this.text API.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `value` | string | Displayed text. | `Text` |
| `fontSize` | number | Font size. | `32` |
| `color` | hex color string | Text color. | `#ffffff` |
| `fontFamily` | string | Font family name. | `Arial` |
| `bold` | boolean | Bold text. | `false` |
| `italic` | boolean | Italic text. | `false` |
| `align` | string | "left" | "center" | "right" — multi-line text alignment | `left` |
| `anchorX` | number | 0–1, this text's own pivot point (0.5,0.5 = centered on Transform.x/y, matching a sprite's default anchor) | `0.5` |
| `anchorY` | number | Vertical anchor from 0 to 1. | `0.5` |
| `opacity` | number | Opacity. | `1` |
| `screenSpace` | boolean | see file header — true = fixed UI overlay, false = world-space | `true` |
| `wordWrap` | boolean | Enable wrapping. | `false` |
| `wrapWidth` | number | px — only used while wordWrap is true | `300` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `fontSize` | Higher = larger text. |
| `anchorX / anchorY` | 0 = top/left pivot, 0.5 = center, 1 = bottom/right pivot for the text block. |
| `wrapWidth` | Only used when wordWrap is enabled; larger width permits longer lines before wrapping. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `align` | Property (read/write) | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `anchorX` | Property (read/write) | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `anchorY` | Property (read/write) | Vertical anchor. |
| `bold` | Property (read/write) | Bold toggle. |
| `color` | Property (read/write) | Hex text color. |
| `fontFamily` | Property (read/write) | Font family. |
| `fontSize` | Property (read/write) | Font size. |
| `italic` | Property (read/write) | Italic toggle. |
| `opacity` | Property (read/write) | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `screenSpace` | Property (read/write) | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `value` | Property (read/write) | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `wordWrap` | Property (read/write) | Enable word wrapping. |
| `wrapWidth` | Property (read/write) | The `this.text` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
this.text.value = "Score: " + score;
```
```
this.text.screenSpace = true;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# StrokePath
> Realot Studio StrokePath component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the StrokePath component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top GameObject → 2D Object → Stroke Path. After a Stroke Path exists, the toolbar exposes Path (P); click empty space to append, drag points, and click segments to insert.
## What it does
A variable-thickness strip along placed points — rivers, cables, roads, conveyor belts or walls — with flat color or textured fill.
> **Component setup & editor tools:** StrokePath creates a drawable strip/path; its editing is performed with the Stroke Path viewport tool/gizmo.
## How to add and use StrokePath
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **StrokePath** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select an entity with StrokePath → use the Stroke Path viewport tool/gizmo to edit path points. Keep the Inspector open for serialized path/material settings.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `points` | array | Two default points (a minimal, visibly-a-path starting shape) rather than one or zero — a single point has no strip to draw at all, so a StrokePath freshly added via the GameObject menu or Add Component window shows \*something\* immediately instead of an invisible/degenerate result the user has to fix before they can… | `[{x:-100,y:0}, {x:100,y:0}]` |
| `thickness` | number | Strip thickness. | `40` |
| `color` | hex color string | Flat fill color, used when useTexture is false. | `#8a8a8a` |
| `opacity` | number | Opacity. | `1` |
| `useTexture` | boolean | Use an image texture along the path instead of a flat fill. | `false` |
| `textureKey` | nullable value | Logical sprite key, resolved to a PIXI.Texture the same way SpriteRenderer.spriteKey is (see runtime/assets/AssetManager.js resolveTexture) — components never hold PIXI objects directly, for the same "stay serializable" reason SpriteRenderer doesn't. | `null` |
| `textureMode` | StrokePathTextureMode enum: stretch | tile | See StrokePathTextureMode above — STRETCH (fit the whole image to the path, may distort) or TILE (repeat at native size, never stretched). | `stretch` |
| `textureTiling` | number | TILE mode only: how many world units of path length one full texture tile covers lengthwise — e.g. | `100` |
| `textureScale` | number | How many times the texture repeats ACROSS the strip's own thickness (perpendicular to the direction of travel) — kept separate from textureTiling (the lengthwise axis) since a texture like a road stripe or brick run almost always needs a different repeat rate across its width than along its length. | `1` |
| `textureOffset` | number | Slides the texture lengthwise along the path without moving any point — e.g. | `0` |
| `textureFlip` | boolean | Mirrors the texture across the path's own centerline (flips which side is "up") without needing a second, mirrored copy of the source image — handy for a texture that's only authored for one direction of travel. | `false` |
| `textureRotation` | number | Rotates the texture, in degrees, around the center of each tile — independent of every other texture setting above, and applied in TEXTURE space (not world space), so it stays a fixed "printed at an angle on the image" look rather than a rotation that would need to track the path's own direction as it turns. | `0` |
| `jointMode` | StrokePathJointMode enum: sharp | bevel | round | See StrokePathJointMode above — SHARP (hard corner), BEVEL (flat chamfer), or ROUND (filled arc). | `round` |
| `capMode` | StrokePathCapMode enum: none | box | round | See StrokePathCapMode above — NONE (flat stop), BOX (flat, but extended slightly past the tip), or ROUND (half-circle cap). | `round` |
| `smoothing` | number | 0-1. Runs the authored `points` through a Catmull-Rom spline resample BEFORE tessellation, turning the raw straight-segment polyline into a smooth curve — same idea as a spline/curve tool in a 3D package, applied to this 2D strip. | `0` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `thickness` | Larger values make the strip wider. |
| `textureTiling` | In TILE mode, larger values make each repeated texture cover more path length, so the image repeats less often. |
| `textureScale` | Higher scales the texture; lower makes it smaller/repeated more densely. |
| `textureOffset` | Changing this over time scrolls the texture along the path. |
| `opacity` | 0 invisible, 1 opaque. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `addPoint(x, y)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `capMode` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `color` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `firstPoint` | Property (read-only) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `getLength()` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `getPoint(index)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `insertPoint(index, x, y)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `jointMode` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `lastPoint` | Property (read-only) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `localToWorld(localX, localY)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `opacity` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `pointCount` | Property (read-only) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `points` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `removePoint(index)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `setPoint(index, x, y)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureFlip` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureKey` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureMode` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureOffset` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureRotation` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureScale` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `textureTiling` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `thickness` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `useTexture` | Property (read/write) | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
| `worldToLocal(worldX, worldY)` | Method | The `this.strokePath` sub-object exposed to user scripts on any entity that has a StrokePath component. |
## Notes & behavior
- Points are placed with the Path tool in the Scene viewport, then adjusted by dragging a point or clicking a segment to insert a new one between two existing points.
- An open polyline (A to B), not a closed loop.
- Reads/writes on this.strokePath.points always operate on a copy, so mutating a returned array can never silently corrupt the live component; assign it back (or use the point methods) to apply a change.
## Examples
```
this.strokePath.addPoint(this.x, this.y);
```
```
this.strokePath.textureOffset += 20 * time.deltaTime; // flowing river/conveyor look
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# SpeechBubble
> Realot Studio SpeechBubble component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the SpeechBubble component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top UI → Speech Bubble, or Inspector → Add Component → Speech Bubble.
## What it does
Speech bubble UI attached to an entity, useful for dialogue and NPC callouts.
> **Component setup & editor tools:** SpeechBubble provides an in-scene speech presentation attached to an entity.
## How to add and use SpeechBubble
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **SpeechBubble** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Inspector → SpeechBubble: configure its display properties; use the documented SpeechBubble API to change content at runtime.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `text` | string | Current bubble text. | `Hello!` |
| `visible` | boolean | Whether visible. | `false` |
| `backgroundColor` | hex color string | Bubble background. | `#ffffff` |
| `textColor` | hex color string | Text color. | `#111111` |
| `borderColor` | hex color string | Border color. | `#111111` |
| `borderWidth` | number | Border width. | `2` |
| `fontSize` | number | Font size. | `20` |
| `fontFamily` | string | Font family. | `Arial` |
| `padding` | number | px between the text and the bubble's edge | `12` |
| `cornerRadius` | number | Corner radius. | `10` |
| `maxWidth` | number | px — text wraps at this width | `220` |
| `offsetX` | number | px offset from this entity's own position | `0` |
| `offsetY` | number | negative = above the entity's head (typical) | `-60` |
| `tailDirection` | string | "down" | "up" | "left" | "right" | "none" — which edge the pointer triangle sits on, pointing back at the entity | `down` |
| `tailSize` | number | Tail size. | `14` |
| `hideTimer` | number | Auto-hide countdown in seconds, ticked down by SpeechBubbleSystem while visible; 0 or less means "stays visible until hidden manually" (see this.speechBubble.hide()). | `0` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `maxWidth` | Higher lets a line run longer before wrapping. |
| `offsetY` | Negative values move the bubble upward from the entity in the default screen convention. |
| `padding` | Higher creates more interior space around text. |
| `cornerRadius` | Higher makes corners rounder. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `backgroundColor` | Property (read/write) | Background color. |
| `borderColor` | Property (read/write) | Border color. |
| `borderWidth` | Property (read/write) | Border width. |
| `cornerRadius` | Property (read/write) | Corner radius. |
| `fontFamily` | Property (read/write) | Font family. |
| `fontSize` | Property (read/write) | Font size. |
| `hide()` | Method | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `maxWidth` | Property (read/write) | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetX` | Property (read/write) | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetY` | Property (read/write) | Vertical offset. |
| `padding` | Property (read/write) | Padding. |
| `show(text, duration)` | Method | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `tailDirection` | Property (read/write) | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `tailSize` | Property (read/write) | Tail size. |
| `text` | Property (read/write) | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textColor` | Property (read/write) | Text color. |
| `visible` | Property (read/write) | The `this.speechBubble` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
this.speechBubble.show("Hello!", 2);
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# ChatLog
> Realot Studio ChatLog component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the ChatLog component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top UI → Chat Log, or Inspector → Add Component → Chat Log.
## What it does
Scrollable-style conversation log component for UI dialogue.
> **Component setup & editor tools:** ChatLog provides a dialogue/log display component intended for scripted text updates.
## How to add and use ChatLog
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **ChatLog** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Inspector → ChatLog: configure the log; use its script-facing API for runtime messages/entries.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `messages` | array | [{ sender, text, senderColor }], oldest first | `[]` |
| `maxMessages` | number | total history kept — oldest dropped once exceeded | `50` |
| `visibleCount` | number | how many of the most recent messages are shown at once | `6` |
| `width` | number | Log width. | `320` |
| `lineHeight` | number | Line height. | `26` |
| `fontSize` | number | Font size. | `16` |
| `fontFamily` | string | Font family. | `Arial` |
| `messageColor` | hex color string | Message color. | `#ffffff` |
| `senderColor` | hex color string | default sender-name color if a message doesn't specify its own | `#ffd700` |
| `backgroundColor` | hex color string | Background. | `#000000` |
| `backgroundOpacity` | number | semi-transparent panel behind the text, typical chat-overlay look | `0.5` |
| `padding` | number | Padding. | `10` |
| `showSender` | boolean | false = just the message text, no "Name: " prefix (good for narration logs) | `true` |
| `screenSpace` | boolean | see TextRenderer.js's file header for the exact meaning — true = fixed UI overlay, false = world-space (e.g. | `true` |
| `visible` | boolean | Visibility. | `true` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `maxMessages` | Total retained history before oldest messages are dropped. |
| `visibleCount` | How many recent messages are shown at once. |
| `backgroundOpacity` | 0 transparent, 1 opaque. |
| `lineHeight` | Higher creates more vertical spacing between messages. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `backgroundColor` | Property (read/write) | Background color. |
| `backgroundOpacity` | Property (read/write) | Background opacity. |
| `clear()` | Method | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `fontFamily` | Property (read/write) | Font family. |
| `fontSize` | Property (read/write) | Font size. |
| `lineHeight` | Property (read/write) | Line height. |
| `maxMessages` | Property (read/write) | Maximum retained messages. |
| `messageColor` | Property (read/write) | Message color. |
| `messages` | Property (read-only) | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `padding` | Property (read/write) | Padding. |
| `screenSpace` | Property (read/write) | Screen-space mode. |
| `send(sender, text, color)` | Method | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `senderColor` | Property (read/write) | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `showSender` | Property (read/write) | The `this.chat` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `visible` | Property (read/write) | Visibility. |
| `visibleCount` | Property (read/write) | Number of visible rows. |
| `width` | Property (read/write) | Panel width. |
## Examples
```
this.chat.send("Guard", "Halt!", "#ef4444");
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# TextInput
> Realot Studio TextInput component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the TextInput component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top UI → Message Input, or Inspector → Add Component → Text Input.
## What it does
Interactive text input control driven by the runtime UI system.
> **Component setup & editor tools:** TextInput creates an editable text-entry control and is typically created from GameObject → UI or the Inspector Add Component picker.
## How to add and use TextInput
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **TextInput** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- GameObject → UI → Message Input creates a TextInput entity. You can also select an entity → Inspector → Add Component → Text Input.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `value` | string | Current text. | |
| `placeholder` | string | Placeholder text. | `Type a message...` |
| `maxLength` | number | Maximum characters. | `200` |
| `fontSize` | number | Font size. | `18` |
| `fontFamily` | string | Font family. | `Arial` |
| `textColor` | hex color string | Text color. | `#111111` |
| `placeholderColor` | hex color string | Placeholder color. | `#999999` |
| `backgroundColor` | hex color string | Background. | `#ffffff` |
| `borderColor` | hex color string | Border. | `#888888` |
| `borderWidth` | number | Border width. | `2` |
| `cornerRadius` | number | Corner radius. | `8` |
| `width` | number | Control width. | `260` |
| `height` | number | Control height. | `40` |
| `padding` | number | Horizontal/vertical padding. | `10` |
| `clearOnSubmit` | boolean | empty the field automatically after Enter — typical chat-box behavior | `true` |
| `focused` | boolean | Live state — see the file header for why these live here rather than in TextInputSystem's private state. | `false` |
| `justSubmitted` | boolean | one-frame pulse: true for exactly one frame after Enter is pressed | `false` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `maxLength` | Hard cap on typed characters. |
| `width / height` | Changes the visual input box size. |
| `borderWidth` | Higher = thicker border. |
| `padding` | Higher moves the text farther from the box edge. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `backgroundColor` | Property (read/write) | Background color. |
| `borderColor` | Property (read/write) | Border color. |
| `borderWidth` | Property (read/write) | Border width. |
| `clear()` | Method | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `clearOnSubmit` | Property (read/write) | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `cornerRadius` | Property (read/write) | Corner radius. |
| `focused` | Property (read-only) | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `fontFamily` | Property (read/write) | Font family. |
| `fontSize` | Property (read/write) | Font size. |
| `height` | Property (read/write) | Control height. |
| `justSubmitted` | Property (read-only) | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `maxLength` | Property (read/write) | Character cap. |
| `padding` | Property (read/write) | Padding. |
| `placeholder` | Property (read/write) | Placeholder. |
| `placeholderColor` | Property (read/write) | Placeholder color. |
| `textColor` | Property (read/write) | Text color. |
| `value` | Property (read/write) | The `this.textInput` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `width` | Property (read/write) | Control width. |
## Examples
```
if (this.textInput.justSubmitted) {
sendMessage("Chat", "message", this.textInput.value);
this.textInput.clear();
}
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Joystick
> Realot Studio Joystick component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Joystick component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top UI → Joystick, or Inspector → Add Component → Joystick.
## What it does
Virtual touch joystick for mobile and pointer-driven control schemes.
> **Component setup & editor tools:** Joystick provides a touch/drag virtual control for mobile-oriented input.
## How to add and use Joystick
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Joystick** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- GameObject → UI → Joystick creates a joystick entity. You can also select an entity → Inspector → Add Component → Joystick.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `positionMode` | JoystickPositionMode enum: Fixed | Dynamic | Fixed or pointer-positioned joystick. | `Fixed` |
| `regionX` | number | Dynamic-mode touch region — the screen-space rectangle (in the same pixel convention Transform.x/y already use for screen-space UI, see TextInput.js's file header) that a press must land inside to claim this joystick. | `0` |
| `regionY` | number | Region Y. | `0` |
| `regionWidth` | number | Region width. | `640` |
| `regionHeight` | number | Region height. | `720` |
| `baseRadius` | number | Visuals | `60` |
| `knobRadius` | number | Knob radius. | `28` |
| `baseColor` | hex color string | Base color. | `#ffffff` |
| `baseOpacity` | number | Base opacity. | `0.25` |
| `knobColor` | hex color string | Knob color. | `#ffffff` |
| `knobOpacity` | number | Knob opacity. | `0.6` |
| `outlineColor` | hex color string | Outline color. | `#ffffff` |
| `outlineWidth` | number | Outline width. | `2` |
| `deadZone` | number | Behavior 0-1: fraction of baseRadius the knob must move before x/y leaves 0 | `0.1` |
| `returnToCenter` | boolean | true = knob snaps back to center on release; false = holds last position | `true` |
| `hideWhenIdle` | boolean | true = invisible until actively being dragged (works in both position modes) | `false` |
| `idleOpacityMultiplier` | number | when hideWhenIdle is false, how much to dim the whole stick while not in use (1 = no dimming) | `0.35` |
| `x` | number | Live state — see the file header for why these live here rather than in JoystickSystem's private state. | `0` |
| `y` | number | -1..1, vertical knob offset (down = positive), after dead zone | `0` |
| `magnitude` | number | 0..1, distance of the knob from center after dead zone | `0` |
| `angle` | number | degrees, 0 = right, 90 = down (screen-space convention, matches Transform.rotation's clockwise-positive sense) | `0` |
| `active` | boolean | true while a finger/pointer is currently dragging this joystick | `false` |
| `baseScreenX` | number | current drawn base center, in screen px — equals Transform.x/y in Fixed mode, or the recentered touch point in Dynamic mode | `0` |
| `baseScreenY` | number | Inspector field stored on this component. | `0` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `deadZone` | 0 means even tiny stick displacement is reported; increasing it keeps small movements at zero until the knob moves farther. |
| `baseRadius / knobRadius` | Larger values make the on-screen joystick physically larger. |
| `idleOpacityMultiplier` | Lower makes an idle joystick more transparent when hideWhenIdle is false. |
| `returnToCenter` | True snaps back on release; false preserves the last knob position. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `active` | Property (read-only) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `angle` | Property (read-only) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `baseColor` | Property (read/write) | Exposed by this script module. |
| `baseOpacity` | Property (read/write) | Exposed by this script module. |
| `baseRadius` | Property (read/write) | Base radius. |
| `deadZone` | Property (read/write) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `hideWhenIdle` | Property (read/write) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `idleOpacityMultiplier` | Property (read/write) | Exposed by this script module. |
| `knobColor` | Property (read/write) | Exposed by this script module. |
| `knobOpacity` | Property (read/write) | Exposed by this script module. |
| `knobRadius` | Property (read/write) | Knob radius. |
| `magnitude` | Property (read-only) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `outlineColor` | Property (read/write) | Exposed by this script module. |
| `outlineWidth` | Property (read/write) | Exposed by this script module. |
| `positionMode` | Property (read/write) | Joystick positioning mode. |
| `regionHeight` | Property (read/write) | Region height. |
| `regionWidth` | Property (read/write) | Region width. |
| `regionX` | Property (read/write) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `regionY` | Property (read/write) | Touch/pointer region Y. |
| `returnToCenter` | Property (read/write) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `x` | Property (read-only) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `y` | Property (read-only) | The `this.joystick` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
this.rigidbody.velocityX = this.joystick.x * 250;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Rigidbody2D
> Realot Studio Rigidbody2D component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Rigidbody2D component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector (right) → Add Component → Rigidbody 2D. Pair with Collider 2D for a colliding body. Edit → Physics Layers… controls named layer slots.
## What it does
2D physics body backed by the engine physics runtime. Dynamic, Kinematic and Static bodies have different script controls.
> **Component setup & editor tools:** Rigidbody2D gives an entity a Rapier 2D body. Collider2D is normally paired with it when physical contact is required.
## How to add and use Rigidbody2D
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Rigidbody2D** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Rigidbody 2D. After adding it, the Rigidbody2D section exposes body type, gravity/damping, velocity/drive values, rotation locking, and controller/ground state fields.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `bodyType` | BodyType enum: Dynamic | Kinematic | Static | Dynamic | Kinematic | Static. | `Dynamic` |
| `simulated` | boolean | Whether the body participates in physics simulation. | `true` |
| `mass` | number | Dynamic-only | `1` |
| `autoMass` | boolean | Inspector field stored on this component. | `true` |
| `gravityScale` | number | Gravity multiplier. | `1` |
| `linearDamping` | number | Linear damping. | `0` |
| `angularDamping` | number | Angular damping. | `0` |
| `lockRotation` | boolean | Dynamic + Kinematic | `false` |
| `velocityX` | number | working velocity — for Dynamic this is read back FROM Rapier each frame (unless driveVelocityX below is set by a controller this same frame); for Kinematic this is the velocity the caller/script sets to drive the body (consumed by PhysicsWorld as a kinematic move). | `0` |
| `velocityY` | number | Y velocity. | `0` |
| `angularVelocity` | number | Angular velocity. | `0` |
| `driveVelocityX` | nullable value | Set (transiently, one frame at a time) by runtime/systems/ControllerSystem.js to drive a DYNAMIC body's horizontal speed via Rapier's setLinvel while leaving the Y axis (and therefore Rapier's own gravity/impulse integration) alone. | `null` |
| `driveVelocityY` | nullable value | Set (transiently, one frame) by ControllerSystem to override a DYNAMIC body's Y velocity this physics step — used both for a one-shot jump kick (Character Controller/Platformer) and for continuous Y drive (Top-Down, which has no gravity to preserve). | `null` |
| `driveAngularVelocity` | nullable value | Set (transiently, one frame) by ControllerSystem to drive a DYNAMIC body's angular velocity (e.g. | `null` |
| `grounded` | boolean | Read-only contact state: written every physics step from Rapier contact manifolds. | `false` |
| `resolvedVelocityX` | number | KINEMATIC-only, read-only: written every physics step with the ACTUAL movement that the kinematic target-motion query resolved after blocking/sliding against obstacles. | `0` |
| `resolvedVelocityY` | number | Inspector field stored on this component. | `0` |
| `pendingForceX` | number | DYNAMIC-only force/impulse queue: pushed by the scripting API's DynamicRigidbodyAPI (see scripting/components/RigidbodyAPI.js) via .addForce()/.addImpulse()/.addTorque() and drained by PhysicsWorld.\_syncEntity every physics step, exactly like driveVelocityX/Y above — plain, serializable data (RULES.txt section 4)… | `0` |
| `pendingForceY` | number | Inspector field stored on this component. | `0` |
| `pendingImpulseX` | number | Inspector field stored on this component. | `0` |
| `pendingImpulseY` | number | Inspector field stored on this component. | `0` |
| `pendingTorque` | number | Inspector field stored on this component. | `0` |
| `pendingAngularImpulse` | number | Inspector field stored on this component. | `0` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `mass` | Higher mass makes the body harder to accelerate from the same force/impulse. It does not make gravity itself stronger. |
| `gravityScale` | 1 is the normal engine gravity response for Dynamic bodies; 2 doubles it; 0 disables gravity contribution. |
| `linearDamping` | Higher values remove linear velocity faster; 0 leaves the body with no linear damping. |
| `angularDamping` | Higher values remove rotational velocity faster. |
## Automatic mass and force at a point
- `autoMass` (default `true`): a Dynamic body computes its mass from the attached collider geometry and density. Uncheck it in the Inspector to use the `mass` value instead.
- `angularDamping`: resistance to spinning, separate from linear damping.
- `addForceAtPoint(...)` in the script API pushes the body at a world point, so it also creates torque.
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `addAngularImpulse(t)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addForce(x, y)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addForceAtPoint(x, y, pointX, pointY)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addImpulse(x, y)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `addTorque(t)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `angularDamping` | Property (read/write) | Angular damping. |
| `gravityScale` | Property (read/write) | Gravity multiplier. |
| `groundAngle` | Property (read-only) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `groundAngleLimit` | Property (read/write) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `grounded` | Property (read-only) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isGrounded` | Property (read-only) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isOnCeiling` | Property (read-only) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isOnSlope` | Property (read-only) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `isOnWall` | Property (read-only) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `linearDamping` | Property (read/write) | Linear damping. |
| `mass` | Property (read/write) | Dynamic mass. |
| `move(dx, dy)` | Method | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `resolvedVelocity` | Property (read-only) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `slopeMinAngle` | Property (read/write) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `type` | Property (read/write) | Dynamic | Kinematic | Static; switching type is supported at runtime. |
| `velocity` | Property (read/write) | {x,y} velocity. |
| `velocityX` | Property (read/write) | Horizontal velocity. |
| `velocityY` | Property (read/write) | Vertical velocity. |
| `wallAngleLimit` | Property (read/write) | The `this.rigidbody` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Notes & behavior
- Kinematic-only methods are meaningful for Kinematic bodies; Dynamic-only force methods apply to Dynamic bodies.
- Position assignment through this.x/this.y is treated as a physics teleport target for non-static bodies.
## Examples
```
this.rigidbody.addImpulse(0, -350);
```
```
this.rigidbody.velocityX = 200;
```
```
this.rigidbody.move(100 * time.deltaTime, 0);
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Collider2D
> Realot Studio Collider2D component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Collider2D component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Collider 2D. One-way platform, trigger, shape, friction, restitution, density, layer and mask settings live here.
## What it does
Physics collision shape and contact filtering. A Collider2D is also required for accurate pointer/touch hit tests.
> **Component setup & editor tools:** Collider2D defines the collision/trigger shape used by the physics system.
## How to add and use Collider2D
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Collider2D** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Collider 2D. After adding it, edit Shape, dimensions, Offset, Trigger, Friction, Restitution, Density, Layer, and Mask in the Collider2D section. The viewport Collider gizmo shows the collision shape.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `shape` | ColliderShape enum: Box | Circle | Capsule | Triangle | Box | Circle | Capsule | Triangle. | `Box` |
| `width` | number | Box width. | `1` |
| `height` | number | Box height. | `1` |
| `radius` | number | Circle radius. | `0.5` |
| `capsuleHalfHeight` | number | Capsule: a "stadium" shape (rectangle with semicircle caps) — matches Rapier's ColliderDesc.capsule(halfHeight, radius), whose principal axis is Y (i.e. | `0.5` |
| `capsuleRadius` | number | Capsule radius. | `0.3` |
| `trianglePoints` | array | Triangle: 3 points in the entity's LOCAL space (same space as offsetX/offsetY), user-editable via 3 draggable gizmo handles. | `[{x:-0.5,y:0.5}, {x:0.5,y:0.5}, {x:0,y:-0.5}]` |
| `offsetX` | number | Local X offset. | `0` |
| `offsetY` | number | Local Y offset. | `0` |
| `rotation` | number | Collider-only rotation, in degrees, applied on top of the entity's own Transform.rotation. | `0` |
| `isTrigger` | boolean | Trigger-only collider. | `false` |
| `isOneWayPlatform` | boolean | One-way platform: solid only when the other body is landing on it from above; a body approaching from below or the side passes straight through, like a Mario/Metroidvania jump-through platform. | `false` |
| `oneWayDirection` | OneWayDirection enum: Up | Down | Inspector field stored on this component. | `Up` |
| `friction` | number | Surface friction. | `0.5` |
| `restitution` | number | Bounciness. | `0` |
| `density` | number | Density. | `1` |
| `layer` | number | Collision layer/mask — inspired by Unity's physics layer matrix. | `0` |
| `mask` | value | Layers this collider can interact with. | `0xFFFF` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `restitution` | 0 behaves as non-bouncy; increasing it produces more bounce. Keep in a physically sensible range for predictable results. |
| `friction` | Higher values resist sliding more strongly. Lower values let contacts slide more easily. |
| `density` | Affects mass/inertia when the physics world builds the body from colliders; it is not a direct “heaviness” multiplier on gravity. |
| `offsetX / offsetY` | Moves the collider relative to the entity’s pivot; positive X/right and positive Y/down in world-space convention. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `capsuleHalfHeight` | Property (read-only) | Capsule half-height. |
| `capsuleRadius` | Property (read-only) | Capsule radius. |
| `density` | Property (read-only) | Density. |
| `friction` | Property (read-only) | Friction. |
| `height` | Property (read-only) | Box height. |
| `isColliding(other)` | Method | The `this.collider` sub-object exposed to user scripts. |
| `isOneWayPlatform` | Property (read-only) | One-way platform flag. |
| `isTrigger` | Property (read/write) | Trigger-only collider. |
| `layer` | Property (read-only) | Layer index 0-15. |
| `mask` | Property (read-only) | 16-bit interaction mask. |
| `offset` | Property (read-only) | {x,y} collider offset. |
| `oneWayDirection` | Property (read/write) | The `this.collider` sub-object exposed to user scripts. |
| `radius` | Property (read-only) | Circle radius. |
| `restitution` | Property (read-only) | Restitution. |
| `rotation` | Property (read/write) | The `this.collider` sub-object exposed to user scripts. |
| `shape` | Property (read-only) | Box | Circle | Capsule | Triangle. |
| `width` | Property (read-only) | Box width. |
## Notes & behavior
- Collision layers use 16 membership layers (0-15). The mask determines which layers the collider can interact with.
- One-way platforms are intended to block from one side while allowing traversal from the non-blocking side.
## Examples
```
this.collider.isTrigger = true;
```
```
this.collider.layer = 2;
```
```
this.collider.mask = 0xFFFF;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Joint2D
> Realot Studio Joint2D component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Joint2D component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Joint 2D; choose Fixed/Revolute/Prismatic/Rope/Spring and configure anchors/limits/motor.
## What it does
Connect physics bodies with Fixed, Revolute, Prismatic, Rope or Spring constraints.
> **Component setup & editor tools:** Joint2D constrains one physics body relative to another and requires compatible Rigidbody2D setup.
## How to add and use Joint2D
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Joint2D** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Joint 2D. Configure the joint from its Inspector section and make sure the connected physics bodies satisfy the joint’s requirements.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `jointType` | JointType2D enum: Fixed | Revolute | Prismatic | Rope | Spring | Fixed | Revolute | Prismatic | Rope | Spring. | `Revolute` |
| `connectedEntityId` | nullable value | null = jointed to a fixed point in the world instead of another body. | `null` |
| `anchor1X` | number | Local-space anchor points, in pixels — see class doc comment. | `0` |
| `anchor1Y` | number | Local anchor Y on this entity. | `0` |
| `anchor2X` | number | Local anchor X on the connected body/world anchor. | `0` |
| `anchor2Y` | number | Local anchor Y on the connected body/world anchor. | `0` |
| `axisX` | number | Prismatic only: slide axis, local to body1. | `1` |
| `axisY` | number | Prismatic axis Y. | `0` |
| `length` | number | Rope: total physical link-path length of the rope. | `100` |
| `stiffness` | number | Spring only. Note these are NOT the small "intuitive" values a spring might use in an SI/meters engine — Rapier computes spring force from anchor distance in METERS (via World.lengthUnit, see PhysicsWorld.js's LENGTH\_UNIT\_PX\_PER\_METER = 100), so at this engine's pixel scale a rest-length-50px displacement is only… | `6000` |
| `damping` | number | Spring damping. | `18` |
| `flexibility` | number | Revolute only: how freely the connected body may rotate. | `100` |
| `segmentCount` | number | Flexible Rope/Spring physical structure. | `18` |
| `ropeMass` | number | Mass per rope/spring segment. | `0.5` |
| `visualEnabled` | boolean | Runtime rope/string visualization. | `true` |
| `visualColor` | hex color string | Joint/rope visual color. | `#c8a66a` |
| `visualThickness` | number | Visual thickness. | `3` |
| `useTexture` | boolean | Optional image texture running along the rope/string instead of a flat color line — same texture/mode vocabulary as StrokePath (see runtime/components/StrokePath.js), so anyone who has textured a StrokePath already recognizes these fields. | `false` |
| `textureKey` | nullable value | Texture asset key. | `null` |
| `textureMode` | string | "stretch": the whole image is squeezed/stretched to fit the rope's current length end-to-end — warps as the rope swings and its chord length changes. | `stretch` |
| `textureTiling` | number | Tiling length. | `32` |
| `textureScale` | number | Texture scale. | `1` |
| `textureOffset` | number | Texture offset. | `0` |
| `textureFlip` | boolean | Flip texture. | `false` |
| `limitsEnabled` | boolean | Revolute + Prismatic: optional min/max limit on the joint's one free coordinate (degrees for Revolute, pixels for Prismatic). | `false` |
| `limitMin` | number | Minimum limit. | `-45` |
| `limitMax` | number | Maximum limit. | `45` |
| `motorEnabled` | boolean | Revolute + Prismatic: optional motor driving that same free coordinate. | `false` |
| `motorSpeed` | number | Motor target speed. | `0` |
| `motorMaxForce` | number | Maximum motor force. | `0` |
| `jointDrag` | number | Revolute-only passive rotational response. | `0` |
| `restStiffness` | number | Inspector field stored on this component. | `0` |
| `breakable` | boolean | Revolute-only structural failure. | `false` |
| `breakForce` | number | Inspector field stored on this component. | `10000` |
| `disableConnectedCollision` | boolean | When enabled, only this joint's two connected entities stop generating contact pairs with one another. | `false` |
| `collideConnected` | value | Legacy scene/script field. | `undefined` |
| `enabled` | boolean | Editor/gizmo convenience only — never read by PhysicsWorld. | `true` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `length` | For Rope/Spring, higher length increases the rest/maximum link distance depending on the joint type. |
| `stiffness` | For Spring, higher values pull toward the rest length more strongly. |
| `damping` | Higher damping reduces oscillation faster. |
| `segmentCount` | Rope visual/solver subdivision count; higher can look smoother but costs more. |
## Breakable joints and drag
- `breakable` / `breakForce` (Revolute only): when the joint load exceeds `breakForce` the joint snaps apart. Script `joint.breakable` and `joint.breakForce`.
- `jointDrag` and `restStiffness` (Revolute only): drag/damping and the springiness that pulls the joint back to its rest pose.
- `disableConnectedCollision`: stop the two connected bodies from colliding with each other. It replaces the old `collideConnected` field, which is kept only for loading older projects.
> **Script API note::** JointAPI currently lists flexibility in its proxy allow-list, but the script object has no getter or setter for it. Reading it returns undefined , and writing it does not change the component. Set Flexibility (%) in the Inspector.
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `anchor1` | Property (read/write) | {x,y} local anchor on this body. |
| `anchor2` | Property (read/write) | {x,y} local anchor on connected body/world anchor. |
| `axis` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `breakForce` | Property (read/write) | Exposed by this script module. |
| `breakable` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `collideConnected` | Property (read/write) | Collision between connected bodies. |
| `connectedEntity` | Property (read/write) | Connected entity context, when one exists. |
| `damping` | Property (read/write) | Spring damping. |
| `disableConnectedCollision` | Property (read/write) | Exposed by this script module. |
| `enabled` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `flexibility` | Allow-listed but not implemented | The JointAPI allow-list contains this name, but no getter or setter is implemented. Reads return undefined and writes do not update Joint2D.flexibility. Set Flexibility (%) in the Inspector instead. |
| `jointDrag` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `jointType` | Property (read/write) | Joint type. |
| `length` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `limitMax` | Property (read/write) | Maximum limit. |
| `limitMin` | Property (read/write) | Minimum limit. |
| `limitsEnabled` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `motorEnabled` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `motorMaxForce` | Property (read/write) | Maximum motor force. |
| `motorSpeed` | Property (read/write) | Motor speed. |
| `restStiffness` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `ropeMass` | Property (read/write) | Rope/spring segment mass. |
| `segmentCount` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stiffness` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureFlip` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureKey` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureMode` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureOffset` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureScale` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `textureTiling` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `useTexture` | Property (read/write) | The `this.joint` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `visualColor` | Property (read/write) | Visual color. |
| `visualEnabled` | Property (read/write) | Visual enabled. |
| `visualThickness` | Property (read/write) | Visual thickness. |
## Examples
```
this.joint.connectedEntity = findFirst("Target");
```
```
this.joint.jointType = "Spring";
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# CharacterController
> Realot Studio CharacterController component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the CharacterController component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Movement Type. Pick Character Controller, Platformer, Top-Down, Car, Follow or Patrol; fields in the Inspector change with the selected mode.
## What it does
High-level movement modes: Character Controller, Platformer, Top-Down, Car, Follow, Patrol and Free.
> **Component setup & editor tools:** CharacterController provides the higher-level movement behaviors such as Platformer, Car, Follow, or Patrol when configured with the required physics components.
## How to add and use CharacterController
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **CharacterController** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Movement Type (CharacterController). Choose the controller type first; the Inspector then exposes the relevant movement fields. Platformer/Car/Follow/Patrol fields are not interchangeable—configure only the group belonging to the selected controller type.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `controllerType` | ControllerType enum: Character Controller | Platformer | Top-Down | Car | Follow | Patrol | Free | Character Controller | Platformer | Top-Down | Car | Follow | Patrol | Free. | `Character Controller` |
| `moveSpeed` | number | Movement (Character / Platformer / Top-Down) px/s | `200` |
| `acceleration` | number | how fast velocity approaches target (higher = snappier) | `20` |
| `airControl` | number | 0-1 multiplier on acceleration while airborne (Platformer only) | `0.5` |
| `canJump` | boolean | Jump (Character Controller + Platformer) | `true` |
| `jumpForce` | number | px/s upward velocity applied on jump | `420` |
| `maxJumps` | number | 1 = no double jump, 2 = double jump, etc. | `1` |
| `useGravity` | boolean | Gravity (Character Controller can toggle it off for e.g. | `true` |
| `gravityScale` | number | Multiplier on gravity's strength for Character Controller/Platformer (same name/semantics as Rigidbody2D.gravityScale on a Dynamic body — 1 = normal, 2 = falls twice as fast, 0.5 = floaty/moon-gravity, 0 = no downward pull at all while still respecting useGravity's on/off switch). | `1` |
| `useDefaultInput` | boolean | Input. For Character/Platformer/Top-Down and Car, this controls the built-in keyboard while script APIs can contribute in the same frame. | `true` |
| `maxSpeed` | number | Car-specific (Car controller only) top forward speed in px/s | `350` |
| `carAcceleration` | number | how fast the car speeds up (px/s^2) | `200` |
| `brakeForce` | number | how fast it brakes / goes into reverse (px/s^2) | `400` |
| `turnSpeed` | number | max turn rate in deg/s (at full speed; scales down at lower speeds) | `150` |
| `driftFactor` | number | 0-1: how much lateral velocity is retained (higher = more slide) | `0.92` |
| `driveTowardArriveDistance` | number | px from the target that counts as "arrived" for | `12` |
| `targetName` | string | Follow-specific (Follow controller only) name of the entity to pursue | |
| `followSpeed` | number | pursuit speed in px/s | `150` |
| `followDistance` | number | stop when within this many pixels of the target | `5` |
| `patrolDistance` | number | Patrol-specific (Patrol controller only). | `150` |
| `patrolMode` | PatrolMode enum: Platformer | Top-Down | Patrol's own movement scheme — see PatrolMode above. | `Platformer` |
| `patrolAxis` | PatrolAxis enum: Horizontal | Vertical | Which axis a TopDown-mode Patrol walks along — see PatrolAxis above. | `Horizontal` |
| `requestJump` | boolean | Set (transiently, for one ControllerSystem update) by this.controller.simulateJump() (see scripting/components/ ControllerAPI.js) to trigger a jump from script logic — consumed and reset to false by ControllerSystem.js right after reading it, the same one-shot request pattern Rigidbody2D's pendingForceX/Y uses. | `false` |
| `requestMoveX` | nullable value | Set (transiently, for one ControllerSystem update) by this.controller.simulateMove(x, y) (see scripting/components/ ControllerAPI.js) as a script/joystick movement contribution. | `null` |
| `requestMoveY` | nullable value | Inspector field stored on this component. | `null` |
| `requestThrottle` | nullable value | Set (transiently, for one ControllerSystem update) by this.controller.simulateDrive(throttle, steer) (see scripting/ components/ControllerAPI.js), Car-only. | `null` |
| `requestSteer` | nullable value | Inspector field stored on this component. | `null` |
| `requestJoystickX` | nullable value | Set (transiently, for one ControllerSystem update) by this.controller.simulateDriveJoystick(x, y) (see scripting/ components/ControllerAPI.js), Car-only. | `null` |
| `requestJoystickY` | nullable value | Inspector field stored on this component. | `null` |
| `requestDriveTowardX` | nullable value | Set (transiently, for one ControllerSystem update) by this.controller.simulateDriveToward(x, y) (see scripting/ components/ControllerAPI.js), Car-only. | `null` |
| `requestDriveTowardY` | nullable value | Inspector field stored on this component. | `null` |
| `requestFlip` | boolean | Set (transiently, for one ControllerSystem update) by this.controller.flipDirection() (see scripting/components/ ControllerAPI.js), Patrol-only. | `false` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `moveSpeed` | Higher = faster target movement. |
| `acceleration` | Higher = reaches the requested speed faster; lower = softer/slower ramp. |
| `airControl` | For Platformer, 0 removes horizontal air steering; 1 gives full ground-like acceleration in air. |
| `jumpForce` | Higher = stronger/faster upward launch; lower = shorter jump. |
| `gravityScale` | 1 = normal controller gravity, 0 = no controller gravity; higher magnifies the pull. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `acceleration` | Property (read/write) | Acceleration. |
| `airControl` | Property (read/write) | Air-control factor. |
| `brakeForce` | Property (read/write) | Car brake force. |
| `canJump` | Property (read/write) | Whether jumping is available. |
| `controllerType` | Property (read-only) | Read-only movement type. |
| `driftFactor` | Property (read/write) | Car drift factor. |
| `driveTowardArriveDistance` | Property (read/write) | Exposed by this script module. |
| `facingDirection` | Property (read-only) | Current patrol facing direction. |
| `flipDirection()` | Method | Reverse Patrol direction. |
| `followDistance` | Property (read/write) | Follow distance. |
| `followSpeed` | Property (read/write) | Follow speed. |
| `gravityScale` | Property (read/write) | Gravity scale. |
| `groundAngle` | Property (read-only) | Ground angle. |
| `isGrounded` | Property (read-only) | Ground state. |
| `isOnCeiling` | Property (read-only) | Ceiling contact. |
| `isOnSlope` | Property (read-only) | Slope contact. |
| `isOnWall` | Property (read-only) | Wall contact. |
| `jumpForce` | Property (read/write) | Jump force. |
| `maxJumps` | Property (read/write) | Maximum jumps. |
| `maxSpeed` | Property (read/write) | Car maximum speed. |
| `moveSpeed` | Property (read/write) | Movement speed. |
| `patrolAxis` | Property (read/write) | Horizontal | Vertical. |
| `patrolDistance` | Property (read/write) | Patrol distance. |
| `patrolMode` | Property (read/write) | Platformer | Top-Down. |
| `simulateDrive(throttle, steer)` | Method | Drive a Car controller by script. |
| `simulateDriveJoystick(x, y)` | Method | Drive using joystick-style vector input. |
| `simulateDriveToward(x, y)` | Method | Drive toward a world point. |
| `simulateJump()` | Method | Request a jump. |
| `simulateMove(x, y)` | Method | Drive movement by script. |
| `targetName` | Property (read/write) | Follow target name. |
| `turnSpeed` | Property (read/write) | Car turn speed. |
| `useDefaultInput` | Property (read/write) | Built-in input mapping. |
| `useGravity` | Property (read/write) | Gravity toggle. |
## Notes & behavior
- Car-only fields/actions are meaningful for the Car controller. Patrol has its own patrolMode and patrolAxis. Free is script-driven with no built-in input mapping.
## Examples
```
this.controller.simulateMove(input.keyDown("ArrowRight") ? 1 : 0, 0);
```
```
this.controller.simulateJump();
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# SpriteAnimation
> Realot Studio SpriteAnimation component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the SpriteAnimation component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Sprite Animation, then use the Animation editor window to create clips/import frames. The Animation editor is an editor window/modal, not the bottom Project panel.
## What it does
Sprite-sheet/clip animation state on a SpriteRenderer.
> **Component setup & editor tools:** SpriteAnimation stores clips and frames and is edited through the Animation Window.
## How to add and use SpriteAnimation
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **SpriteAnimation** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → SpriteAnimation → Open Animation Window. Create/edit clips, frames, FPS, looping, and playback there; use the Inspector for component-level playback state.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `clips` | array | @type {AnimationClip[]} | `[]` |
| `currentClipId` | nullable value | @type {string|null} which clip.id is currently selected/playing | `null` |
| `playing` | boolean | whether playback advances automatically every frame (vs. | `true` |
| `speed` | number | playback speed multiplier — 1 = clip's own fps, 2 = double speed, etc. | `1` |
| `currentFrameIndex` | number | --- Simulation state (still plain numbers/strings, not objects — this is per-entity playback progress, same category of field as Rigidbody2D.velocityX: it changes every frame at runtime, but it's still serializable plain data, not a PIXI/Rapier handle). | `0` |
| `frameElapsed` | number | seconds accumulated since the last frame advance | `0` |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `currentClip` | Property (read-only) | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `currentFrame` | Property (read/write) | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `play(clipName)` | Method | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `playing` | Property (read-only) | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `speed` | Property (read/write) | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stop()` | Method | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `totalFrames` | Property (read-only) | The `this.animator` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
this.animator.play("Run");
```
```
this.animator.speed = 1.5;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Camera
> Realot Studio Camera component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Camera component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Camera. Main camera and scaling/presentation settings are edited in the Inspector; Play/Export use the same runtime camera path.
## What it does
Orthographic 2D camera with reference resolutions, responsive scaling, follow, shake and optional pseudo-3D sprite depth scaling.
> **Component setup & editor tools:** Camera controls the 2D view and rendering/scaling behavior. The Scene viewport exposes a camera gizmo when a Camera entity is selected.
## How to add and use Camera
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Camera** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select the Camera entity → Inspector → Camera. The Camera gizmo appears in the Scene viewport. Mark the intended camera as Main and configure projection/scaling/aspect settings in the Inspector.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `backgroundColor` | hex color string | Background color. | `#314D79` |
| `projection` | string | Projection mode. | `Orthographic` |
| `size` | number | Orthographic camera size. | `5` |
| `nearClip` | number | Near clip. | `0.3` |
| `farClip` | number | Far clip. | `1000` |
| `isMain` | boolean | Whether this is the main camera. | `false` |
| `aspectMode` | CameraAspectMode enum: Landscape | Portrait | Square | Custom | Landscape | Portrait | Square | Custom. | `Landscape` |
| `landscapeWidth` | number | Landscape reference width. | `960` |
| `landscapeHeight` | number | Landscape reference height. | `540` |
| `portraitWidth` | number | Portrait reference width. | `540` |
| `portraitHeight` | number | Portrait reference height. | `960` |
| `squareSize` | number | Square reference size. | `720` |
| `customWidth` | number | Custom width. | `800` |
| `customHeight` | number | Custom height. | `600` |
| `enablePseudo3D` | boolean | Use Transform.z for sprite depth scaling. | `false` |
| `renderToSpriteEntityId` | nullable value | Inspector field stored on this component. | `null` |
| `scalingMode` | ScalingMode enum: Expand | Fit | Fill | Stretch | ── Screen scaling (device-fit) settings ────────────────────── See the ScalingMode doc comment above and computeScreenFit() in CameraUtils.js for the full picture. | `Fit` |
| `keepHeight` | boolean | EXPAND-only. true = the reference HEIGHT is what's kept exact (matches Unity's Canvas Scaler "Match: Height" — width is the axis that expands/contracts to reveal more or less of the world). | `true` |
| `aspectRatioLock` | boolean | Safety override for EXPAND specifically: Expand's whole purpose is to let the effective aspect ratio drift to match the device (showing more/less world). | `true` |
| `allowStretching` | boolean | Safety override for STRETCH specifically: false (default) downgrades Stretch to behave like Fit instead, so a scalingMode accidentally left on "Stretch" can never actually distort the picture. | `false` |
| `letterboxing` | string | Horizontal bars (top/bottom) — shown when Fit (or a mode downgraded to Fit above) leaves vertical space unused. | `Auto` |
| `pillarboxing` | string | Same as letterboxing but for vertical bars (left/right), shown when horizontal space is left over. | `Auto` |
| `barColor` | hex color string | Color painted into letterbox/pillarbox bars when they're shown. | `#000000` |
| `integerScaling` | boolean | Rounds the computed scale down to the nearest whole integer (never below 1x) before applying it — keeps pixel-art crisp instead of blurry/uneven at fractional scales. | `false` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `size / zoom` | For this 2D camera, larger effective view size shows more world; increasing zoom makes the scene appear smaller/farther, while reducing it magnifies the world. |
| `scalingMode` | FIT preserves the reference aspect and uses bars when necessary; FILL crops to fill; STRETCH changes aspect; EXPAND keeps the reference height and reveals more/less horizontal world. |
| `integerScaling` | When enabled, device-fit scale is constrained toward integer multiples to keep pixel-art rendering crisp. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `allowStretching` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `aspectMode` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `aspectRatioLock` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `backgroundColor` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `barColor` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `customHeight` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `customWidth` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `enablePseudo3D` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `follow(entityTarget, opts)` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `integerScaling` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `keepHeight` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `landscapeHeight` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `landscapeWidth` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `letterboxing` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetX` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `offsetY` | Property (read/write) | Follow/render Y offset. |
| `pillarboxing` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `portraitHeight` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `portraitWidth` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `renderToSprite(spriteEntity)` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `scalingMode` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `shake(intensity, duration)` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `squareSize` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stopFollow()` | Method | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `x` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `y` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `zoom` | Property (read/write) | The `this.camera` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
var cam = findFirst("Main Camera");
```
```
cam.camera.follow(findFirst("Target"), { smoothing: 0.1 });
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# AudioSource
> Realot Studio AudioSource component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the AudioSource component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Audio Source; audio assets are under bottom Project → Audio and can be assigned to Audio Source.
## What it does
Play a local audio asset, optionally with distance-based 3D attenuation.
> **Component setup & editor tools:** AudioSource plays an imported audio asset from an entity.
## How to add and use AudioSource
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **AudioSource** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Audio Source. Assign an imported audio asset in the AudioSource section and use the script API for playback/state control.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `audioKey` | nullable value | Audio asset key. | `null` |
| `is3D` | boolean | Enable distance attenuation. | `false` |
| `volume` | number | Volume 0-1. | `1` |
| `pitch` | number | Pitch multiplier; runtime API clamps to 0.25-4. | `1` |
| `loop` | boolean | Loop playback. | `true` |
| `autoplay` | boolean | Play automatically. | `true` |
| `minDistance` | number | Full-volume distance for 3D audio. | `100` |
| `maxDistance` | number | Silent distance for 3D audio. | `600` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `volume` | 0 silent; 1 the base configured level. |
| `pitch` | 1 normal playback speed; >1 faster/higher; <1 slower/lower. |
| `minDistance` | 3D only: inside this radius the source remains at full base volume. |
| `maxDistance` | 3D only: beyond this radius the source is silent. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `pitch` | Property (read/write) | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `play()` | Method | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `playOnce()` | Method | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `playing` | Property (read-only) | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `stop()` | Method | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
| `volume` | Property (read/write) | The `this.audio` sub-object exposed to user scripts (see scripting/ScriptAPI.js). |
## Examples
```
this.audio.playOnce();
```
```
this.audio.volume = 0.5;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# AudioListener
> Realot Studio AudioListener component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the AudioListener component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Audio Listener. Usually keep one active listener in a scene for 3D hearing queries.
## What it does
Defines the hearing area for 3D audio and drives audio enter/leave callbacks.
> **Component setup & editor tools:** AudioListener defines the listening point used by positional audio behavior.
## How to add and use AudioListener
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **AudioListener** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Audio Listener. Use one intended listener for the active view; its radius/enabled settings control listening behavior.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `radius` | number | Hearing radius. | `300` |
| `enabled` | boolean | Inspector field stored on this component. | `true` |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `canHear(nameOrTag, opts)` | Method | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
| `enabled` | Property (read/write) | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
| `radius` | Property (read/write) | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
| `sourcesInRange` | Property (read-only) | The `this.ear` sub-object exposed to user scripts (see scripting/ScriptAPI.js) — the query surface for the AudioListener component (see components/AudioListener.js). |
## Notes & behavior
- With an AudioListener present, scripts can receive onHearSound(source) and onLoseSound(source) transitions.
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Light
> Realot Studio Light component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Light component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top GameObject → Light → Directional/Point/Spot/Area/God Rays/Freeform. Existing lights expose their settings in the Inspector.
## What it does
2D light source supporting Directional, Point, Spot, Area, GodRays and Freeform light shapes.
> **Component setup & editor tools:** Light adds the engine’s 2D lighting source and exposes a viewport gizmo for spatial editing.
## How to add and use Light
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Light** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Light. The Light gizmo appears in the Scene viewport; use it to position/edit freeform geometry where supported.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `type` | LightType enum: Directional | Point | Spot | Area | GodRays | Freeform | Directional | Point | Spot | Area | GodRays | Freeform. | `Point` |
| `color` | hex color string | Light color. | `#ffffff` |
| `intensity` | number | Light intensity. | `1` |
| `radius` | number | Reach for Point/Spot/GodRays. | `200` |
| `angle` | number | Cone angle for Spot/GodRays. | `45` |
| `width` | number | Area-light width. | `200` |
| `height` | number | Area-light height. | `200` |
| `castsOnWorld` | boolean | Light the world. | `true` |
| `castShadows` | boolean | Cast shadows. | `false` |
| `shadowColor` | hex color string | Shadow color. | `#000000` |
| `shadowStrength` | number | Shadow strength. | `1` |
| `flicker` | boolean | Flicker enabled. | `false` |
| `flickerSpeed` | number | Flicker speed. | `8` |
| `flickerDuration` | number | Flicker duration. | `0` |
| `coreSize` | number | Visible light-core size. | `0.22` |
| `coreVisible` | boolean | Show visible light core. | `true` |
| `points` | nullable value | Freeform local polygon points. | `null` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `intensity` | 0 is off; 1 is the normal baseline; >1 produces stronger/brighter illumination. |
| `radius` | Larger values extend point/spot/area reach. Smaller values concentrate the light. |
| `angle` | For Spot/God Rays, larger values widen the cone; 0 is very narrow. |
| `shadowStrength` | 0 removes visible shadow contribution; 1 gives full light-side shadow strength. |
| `flickerSpeed` | Higher = faster flicker cycles. |
| `flickerDuration` | 0 = indefinite flicker when enabled; positive values stop the flicker after that many seconds. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `angle` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `castShadows` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `castsOnWorld` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `color` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `coreSize` | Property (read/write) | Light core size. |
| `coreVisible` | Property (read/write) | Show light core. |
| `flicker` | Property (read/write) | Flicker toggle. |
| `flickerDuration` | Property (read/write) | Flicker duration. |
| `flickerSpeed` | Property (read/write) | Flicker speed. |
| `height` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `intensity` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `radius` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `shadowColor` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `shadowStrength` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `type` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
| `width` | Property (read/write) | The `this.light` sub-object exposed to user scripts on any entity that has a Light component. |
## Examples
```
this.light.intensity = 1.5;
```
```
this.light.castShadows = true;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# ShadowCaster
> Realot Studio ShadowCaster component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the ShadowCaster component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Shadow Caster. Enable it on objects that should occlude light; pair with a Light whose Cast Shadows is enabled.
## What it does
Marks an entity as a shadow occluder for the lighting system.
> **Component setup & editor tools:** ShadowCaster defines geometry that participates in the lighting/shadow system.
## How to add and use ShadowCaster
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **ShadowCaster** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Shadow Caster. Configure its serialized geometry in the Inspector and verify shadows in the viewport/game preview with a Light configured to cast shadows.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `enabled` | boolean | Enable shadow casting. | `true` |
| `width` | nullable value | Shadow source width; null can derive from visual bounds. | `null` |
| `height` | nullable value | Shadow source height; null can derive from visual bounds. | `null` |
| `offsetX` | number | Shadow offset X. | `0` |
| `offsetY` | number | Shadow offset Y. | `0` |
| `opacity` | number | Shadow opacity. | `1` |
| `length` | number | Shadow length multiplier. | `1` |
| `softness` | number | Shadow softness. | `0` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `opacity` | 0 contributes no visible shadow; 1 is full caster contribution. |
| `length` | 1 uses the light’s natural reach; 0.5 makes a shorter shadow; 2 makes it reach twice as far. |
| `softness` | 0 is a crisp edge; increasing it broadens the penumbra. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `enabled` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `height` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `length` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `offsetX` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `offsetY` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `opacity` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `softness` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
| `width` | Property (read/write) | The `this.shadowCaster` sub-object exposed to user scripts on any entity that has a ShadowCaster component (see components/ShadowCaster.js). |
## Examples
```
this.shadowCaster.length = 2;
```
```
this.shadowCaster.softness = 0.25;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# LightingSettings
> Realot Studio LightingSettings component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the LightingSettings component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Lighting Settings. This is scene-wide; one entity carrying the component supplies quality/mood values to the LightingSystem.
## What it does
Scene-wide lighting quality and mood controls. Attach to one entity; the lighting system reads it scene-wide.
> **Component setup & editor tools:** LightingSettings configures scene/entity lighting quality and ambient/shadow parameters used by the lighting system.
## How to add and use LightingSettings
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **LightingSettings** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Add Component → Lighting Settings. Adjust quality/ambient/shadow parameters and verify changes with an active Light/ShadowCaster setup.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `shadowMode` | ShadowMode enum: quad | raymarch | quad | raymarch. | `quad` |
| `raymarchSteps` | number | 1-200 raymarch steps; only used in raymarch mode. | `24` |
| `ambientDarkness` | number | 0-1 darkness in unlit areas. | `0.65` |
| `glowStrength` | number | Visible light glow strength. | `1` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `ambientDarkness` | 0 leaves the unlit world bright; increasing toward 1 makes unlit areas darker. |
| `glowStrength` | Higher makes open-air light glow more strongly; 0 removes visible glow. |
| `raymarchSteps` | Higher improves raymarch shadow sampling but costs more GPU work; lower is cheaper but less detailed. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `ambientDarkness` | Property (read/write) | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
| `glowStrength` | Property (read/write) | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
| `raymarchSteps` | Property (read/write) | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
| `shadowMode` | Property (read/write) | The `scene.lighting` sub-object exposed to user scripts (see scripting/ScriptAPI.js's getGlobals()) — lets scripts tune scene-wide lighting/shadow realism settings at runtime (see components/LightingSettings.js for the full field guide), e.g. |
## Examples
```
scene.lighting.shadowMode = "raymarch";
```
```
scene.lighting.raymarchSteps = 48;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# NavAgent2D
> Realot Studio NavAgent2D component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the NavAgent2D component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Nav Agent 2D. For radius and area painting, use the Nav toolbar after a Nav World 2D exists; Match Collider is in the Nav Agent inspector section.
## What it does
Per-agent navigation settings and current path state for NavWorld2D pathfinding.
> **Component setup & editor tools:** NavAgent2D is the moving-agent side of Realot Studio navigation. It works with NavWorld2D and the navigation API.
## How to add and use NavAgent2D
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **NavAgent2D** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select the agent → Inspector → Add Component → Nav Agent 2D. Configure agent parameters, then use the NavWorld2D + navigation workflow before expecting paths. Runtime movement is driven by the NavAgent2D API.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `radius` | number | Agent px clearance this agent needs from obstacles/other geometry. | `16` |
| `speed` | number | Movement px/s top move speed | `120` |
| `acceleration` | number | px/s^2 — how fast the agent speeds up toward `speed` | `800` |
| `deceleration` | number | px/s^2 — how fast the agent slows when arriving/stopping | `1000` |
| `stoppingDistance` | number | px from the final target that counts as arrived | `1` |
| `autoRepath` | boolean | Pathfinding if true, the agent re-checks its path on a timer/on | `true` |
| `repathInterval` | number | target movement automatically (see repathInterval/ repathDistance below). | `0.35` |
| `repathDistance` | number | world units a moving target must shift before an | `4` |
| `avoidanceEnabled` | boolean | Avoidance — separate from pathfinding (see NavWorldSystem.js header: "Pathfinding answers how do I get there, avoidance answers how do I avoid this NPC directly in front of me"). | `true` |
| `avoidancePriority` | number | 0-100. Higher-priority agents yield less to | `50` |
| `collabEnabled` | boolean | Collaboration — separate from both pathfinding AND avoidance (see #5 above: "how do I get there" vs "how do I avoid the NPC in front of me"). | `false` |
| `collabGroupRadius` | number | scripts behave exactly as before. | `96` |
| `vehicleLookahead` | number | Car + NavAgent2D local vehicle planner. | `72` |
| `vehicleCornerLookahead` | number | Corner lookahead. | `110` |
| `vehicleObstacleLookahead` | number | Obstacle lookahead. | `120` |
| `vehicleObstacleWidth` | number | Obstacle width estimate. | `28` |
| `vehicleSteerSmoothing` | number | Steering smoothing. | `7` |
| `vehicleSpeedSmoothing` | number | Speed smoothing. | `5` |
| `vehicleCornerSlowdown` | number | Corner slowdown multiplier. | `0.72` |
| `vehicleObstacleBrake` | number | Obstacle braking factor. | `0.9` |
| `vehicleRecoveryTime` | number | seconds of being stuck (pushing into | `1.35` |
| `vehicleRecoveryReverseTime` | number | something with little progress, drifting off the planned lane, or on a collision course with something dead ahead) before the car commits to a recovery maneuver. | `0.9` |
| `area` | value | Navigation — same model as Unity's NavMeshAgent.areaMask: a bitmask of which NavWorld2D cell areas (Ground, Water, Mud, ...) this agent is ALLOWED to path through at all — a route can never cross a bit that's off here, no matter how short a shortcut it would be. | `0xffff` |
| `areaCosts` | nullable value | Per-agent override of NavWorld2D.areaCosts, index-aligned with the same 16 area slots (see editor/state/NavAreas.js for the name registry both arrays share). | `null` |
| `currentPath` | nullable value | Set (transiently, for one movement step) by NavWorldSystem/ScriptAPI path-following helpers to hand a fresh path to this agent without NavAgent2D reaching back into the system itself — plain data, one- shot per repath, same pattern as CharacterController's requestJump. | `null` |
| `currentPathIndex` | number | Inspector field stored on this component. | `0` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `radius` | The clearance needed around this agent. Larger radius makes narrow passages become non-walkable for this agent. |
| `speed` | Top travel speed in world units/second. |
| `acceleration / deceleration` | Higher values make movement and stopping snappier; lower values make it softer. |
| `stoppingDistance` | Larger values let the agent stop farther from the final target. |
| `repathInterval` | Lower reacts faster to changing routes/targets but costs more path queries. |
| `area` | Hard allowed-area mask; excluding an area prevents the route from crossing it. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `acceleration` | Property (read/write) | Acceleration. |
| `area` | Property (read/write) | Allowed area mask. |
| `areaCosts` | Property (read/write) | 16-entry area cost overrides. |
| `autoRepath` | Property (read/write) | Auto-repath. |
| `avoidanceEnabled` | Property (read/write) | Avoidance toggle. |
| `avoidancePriority` | Property (read/write) | Avoidance priority. |
| `collabEnabled` | Property (read/write) | Collaborative vehicle avoidance. |
| `collabGroupRadius` | Property (read/write) | Group radius. |
| `currentPath` | Property (read-only) | Read-only world-space waypoint array or null. |
| `currentPathIndex` | Property (read-only) | Read-only current waypoint index. |
| `deceleration` | Property (read/write) | Deceleration. |
| `radius` | Property (read/write) | Agent radius. |
| `repathDistance` | Property (read/write) | Target-move repath threshold. |
| `repathInterval` | Property (read/write) | Repath interval. |
| `speed` | Property (read/write) | Preferred speed. |
| `stoppingDistance` | Property (read/write) | Stopping distance. |
| `vehicleCornerLookahead` | Property (read/write) | Corner lookahead. |
| `vehicleCornerSlowdown` | Property (read/write) | Corner slowdown. |
| `vehicleLookahead` | Property (read/write) | Vehicle lookahead. |
| `vehicleObstacleBrake` | Property (read/write) | Obstacle brake factor. |
| `vehicleObstacleLookahead` | Property (read/write) | Obstacle lookahead. |
| `vehicleObstacleWidth` | Property (read/write) | Obstacle width. |
| `vehicleRecoveryReverseTime` | Property (read/write) | Reverse recovery time. |
| `vehicleRecoveryTime` | Property (read/write) | Recovery time. |
| `vehicleSpeedSmoothing` | Property (read/write) | Speed smoothing. |
| `vehicleSteerSmoothing` | Property (read/write) | Steering smoothing. |
## Examples
```
this.navAgent.speed = 180;
```
```
this.navAgent.autoRepath = true;
```
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# NavWorld2D
> Realot Studio NavWorld2D component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the NavWorld2D component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top GameObject → 2D Object → Nav World 2D. Once present, toolbar U/I/O brushes and Bounds/Cells view controls appear. Configure named areas with Edit → Nav Areas….
## What it does
Shared navigation world for baked or dynamic 2D pathfinding, with 16 navigation areas.
> **Component setup & editor tools:** NavWorld2D owns the navigation world/bake configuration used by NavAgent2D and the navigation API.
## How to add and use NavWorld2D
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **NavWorld2D** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select/create an entity → Inspector → Add Component → Nav World 2D. Use the Navigation toolbar and Edit → Nav Areas… controls to define/bake the navigation world; then connect agents to it through the documented navigation workflow.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `boundsX` | number | World-space bounds X. | `-400` |
| `boundsY` | number | World-space bounds Y. | `-400` |
| `boundsWidth` | number | Bounds width. | `800` |
| `boundsHeight` | number | Bounds height. | `800` |
| `cellSize` | number | Navigation cell size. | `32` |
| `cells` | object | Authored filled cells. | `{}` |
| `bakedCells` | nullable value | Derived baked representation. | `null` |
| `paintOverrides` | object | Explicit walkability overrides. | `{}` |
| `cellAreas` | object | Per-cell navigation area bitmask (one bit per NAV\_AREA\_COUNT slot). | `{}` |
| `areaCosts` | nullable value | Per-area traversal cost multiplier, index-aligned with the 16 area slots (see editor/state/NavAreas.js) — same role as Unity's NavMeshAgent.SetAreaCost(): a SOFT preference, not a hard block. | `null` |
| `allowDiagonal` | boolean | Allow diagonal A\* connections. | `false` |
| `dynamic` | boolean | Rebuild from dynamic scene obstacles. | `false` |
| `minObstacleFootprint` | number | Smallest obstacle footprint (world units, along its narrower axis) that is still allowed to block a cell during bakeNavWorld(). | `0` |
## Tuning behavior
These are the practical direction-of-change rules for the most important controls on this component.
| Setting | What changing it does |
| --- | --- |
| `cellSize` | Smaller cells give a finer grid and can represent narrower corridors, but increase navigation work/memory. |
| `allowDiagonal` | Off means 4-neighbor movement; on adds diagonal connections. |
| `dynamic` | When enabled, navigation can be rebuilt dynamically from current geometry; use only when runtime rebaking is actually needed. |
| `areaCosts` | 1 means neutral cost; 3 makes an allowed area approximately three times as expensive to traverse. Cost is preference, not a hard exclusion. |
## Script API
| Member | Kind | Description |
| --- | --- | --- |
| `nav.findPath()` | Global | Find world-space path through a NavWorld2D. |
| `nav.isWalkable()` | Global | Check a world-space point. |
| `nav.bake()` | Global | Bake navigation data after authored changes. |
| `nav.areaIndex` | Property | Current/selected navigation area index surface. |
| `nav.areaMask` | Property | Navigation area mask. |
| `nav.areaCosts` | Property | Navigation area costs. |
## Notes & behavior
- NavWorld2D is a scene component; there is no `this.navWorld` object. Scripts use the global `nav` module.
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Tileset
> Realot Studio Tileset component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Tileset component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top GameObject → 2D Object → Tileset, then open the Tileset Editor window from the Inspector. Import one auto-sliced 4×4 sheet or 16 role images.
## What it does
Defines a reusable 16-role autotile set. The editor can auto-slice one image or accept separate role images.
> **Component setup & editor tools:** Tileset stores tile definitions used by Tilemap and is edited through the Tileset panel.
## How to add and use Tileset
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Tileset** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select/create a Tileset entity → Inspector → Add Component → Tileset → open the Tileset panel. Define tile data there, then assign/use the Tileset from a Tilemap.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `name` | string | Tileset display name. | `New Tileset` |
| `tileWidth` | number | Tile width in pixels/world units. | `32` |
| `tileHeight` | number | Tile height. | `32` |
| `slots` | object | @type {Record} role name -> spriteKey (or null if that slot hasn't been filled in yet). | `{}` |
## Autotile roles
| Slot | Role | Meaning |
| --- | --- | --- |
| 1 | `cornerTL` | Canonical role slot |
| 2 | `edgeT` | Canonical role slot |
| 3 | `cornerTR` | Canonical role slot |
| 4 | `stubT` | Canonical role slot |
| 5 | `edgeL` | Canonical role slot |
| 6 | `center` | Canonical role slot |
| 7 | `edgeR` | Canonical role slot |
| 8 | `lineV` | Canonical role slot |
| 9 | `cornerBL` | Canonical role slot |
| 10 | `edgeB` | Canonical role slot |
| 11 | `cornerBR` | Canonical role slot |
| 12 | `stubB` | Canonical role slot |
| 13 | `stubL` | Canonical role slot |
| 14 | `lineH` | Canonical role slot |
| 15 | `stubR` | Canonical role slot |
| 16 | `single` | Canonical role slot |
## Notes & behavior
- Autotile selection is computed from the four orthogonal neighbors; the stored Tilemap data is the filled-cell set, not a baked per-cell sprite choice.
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Tilemap
> Realot Studio Tilemap component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Tilemap component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Top GameObject → 2D Object → Tilemap. Assign a Tileset entity in the Inspector; T and Y tools appear when a Tilemap/Tileset exists.
## What it does
Sparse painted tile grid that references a Tileset entity by ID.
> **Component setup & editor tools:** Tilemap paints a tile grid and exposes tilemap-specific viewport/panel tools.
## How to add and use Tilemap
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Tilemap** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select/create a Tilemap entity → Inspector → Add Component → Tilemap. Use the Tilemap viewport/panel tools to paint the configured Tileset.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `tilesetEntityId` | nullable value | @type {string|null} entity id of the Tileset-holding entity this tilemap paints with. | `null` |
| `cells` | object | @type {Record} sparse map of "col,row" -> true for every painted cell. | `{}` |
## Notes & behavior
- Tilemap has no dedicated `this.tilemap` script API in the current engine. It is edited as scene data by the editor and rendered by TilemapSystem.
- Cells may use negative coordinates. The key format is `col,row`.
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.
---
# Script
> Realot Studio Script component reference: fields, script API, behavior and examples.
> **Scope:** This page documents the Script component in Realot Studio. Runtime fields are serialized scene data; the Script API section lists only members intentionally exposed to game scripts.
> **Where to find it in the editor:** Inspector → Add Component → Script, then use the script editor via the script asset/project item. IntelliSense completion is driven from the same runtime option metadata.
## What it does
Script component holding a script name, source and enabled state.
> **Component setup & editor tools:** Script attaches a JavaScript file to an entity. The Inspector provides Create New Script, Load Script…, and Open Script Editor controls.
## How to add and use Script
**Editor path:** Select the target entity in the **Hierarchy** (left side) → look at the **Inspector** (right side) → click **Add Component** at the bottom of the Inspector → search for **Script** → click the component row. The Add Component picker is a centered modal with a search box; it only lists components not already attached.
For components with a dedicated editor tool, the tool is opened or activated from the location described below. Do not assume that adding the component alone activates its editor; some systems require a separate window, panel, or viewport tool.
## Component setup & editor tools
- Select entity → Inspector → Script section → Create New Script, Load Script…, or Open Script Editor. After attachment, Enabled controls whether the script runs.
### What you should see after adding it
The component appears as its own section in the Inspector. Its serialized settings are listed in the **Component data** table below. If a field is conditional, it appears only when the relevant mode/type is selected. If a field is a runtime state field (for example grounded or resolved velocity), treat it as read-only diagnostic state unless the API reference explicitly documents it as writable.
### How to read the settings
For every setting below, the documentation distinguishes **type**, **default**, **meaning**, and tuning direction where behavior is known. When a value represents a direction, use the engine's coordinate convention documented in [Coordinate system](../../reference/coordinate-system.html); do not substitute Unity/Godot conventions.
## Component data
| Field | Type | Purpose | Default |
| --- | --- | --- | --- |
| `scriptName` | string | Script asset/name. | `NewScript` |
| `source` | string | Script source code. | |
| `enabled` | boolean | Whether the script is enabled. | `true` |
| `inspectValues` | object | Inspector field stored on this component. | `{}` |
## Notes & behavior
- Scripts are executed by ScriptSystem and receive the lifecycle/globals documented under Scripting. Script components are scene data rather than a `this.script` runtime API.
> **Need the full workflow?:** Components: complete workflow covers adding, configuring, testing, combining, and removing components.