From 29ee5ddc25371985725ac7846ac3db818377aebf Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Thu, 30 Jul 2026 19:10:38 +0200 Subject: [PATCH 01/13] Added first version of the automation workflows manual. --- docs/en/manuals/automation-workflows.md | 767 ++++++++++++++++++ .../images/automation/automation_loop.png | Bin 0 -> 38438 bytes .../images/automation/cube-preview.png | Bin 0 -> 86923 bytes .../images/automation/editor_server.png | Bin 0 -> 66838 bytes .../images/automation/main-preview.png | Bin 0 -> 10673 bytes 5 files changed, 767 insertions(+) create mode 100644 docs/en/manuals/automation-workflows.md create mode 100644 docs/en/manuals/images/automation/automation_loop.png create mode 100644 docs/en/manuals/images/automation/cube-preview.png create mode 100644 docs/en/manuals/images/automation/editor_server.png create mode 100644 docs/en/manuals/images/automation/main-preview.png diff --git a/docs/en/manuals/automation-workflows.md b/docs/en/manuals/automation-workflows.md new file mode 100644 index 00000000..4d1b40ab --- /dev/null +++ b/docs/en/manuals/automation-workflows.md @@ -0,0 +1,767 @@ +--- +title: Automation and working with AI agents +brief: This manual explains how to automate the Defold editor and build process, create project-specific tools, run automated tests, and connect AI coding agents and multimodal models to processes whose results can be verified unambiguously. +--- + +# Automation and working with AI agents + +Defold supports automation at several levels: + +* [editor scripts](/manuals/editor-scripts) allow you to customize editor workflows, add specific tools, and speed up the creation of levels, assets, etc. +* [editor UI scripts](/manuals/editor-scripts-ui/) allow you to create custom visual tools, popups, configurators, etc. +* [editor HTTP API](https://github.com/defold/defold/blob/dev/editor/doc/http-api.md) allows you to control an open project via OpenAPI operations. +* [Bob CLI](/manuals/bob) can build a project and create data archives or standalone bundles from the command line. +* shell scripts can generate, validate, and manage files. + +Therefore, Defold can offer: + +* team- or project-specific processes and tool integrations; +* repeatable, custom commands used during project development; +* content generation and validation; +* local testing tools; +* continuous integration (CI); +* IDE integrations; +* support for AI coding agents; +* visual and multimodal analysis. + +Defold is well suited to these tasks because it combines text-based project files that are easy to edit and manage with version control—Lua scripts and Protobuf-based resource files—with version-matched API documentation, a machine-readable editor interface, structured compilation results, observable runtime output, scene previews, an extensible editor, and a command-line build tool. LLM coding agents can be an optional layer on top of this toolset. Test collections, browser automation, image comparison tools, or multimodal models can be used to verify the results. + +::: important +The editor HTTP API is experimental and may change between Defold versions. Always read the OpenAPI document generated by the currently running editor. +::: + +## Choosing an automation interface + +Choosing an interface appropriate to the task is one of the most important aspects of effective automation. The table below can help you choose the simplest interface for a given action: + +| Interface | Suitable for | +| --------------------------- | ------------------------------------------------------------------------- | +| Shell script or task runner | Generation, formatting, validation, and repeatable local tasks | +| Bob | Editor-independent builds, bundles, reports, and CI | +| Editor script | Custom commands, resource tools, user interfaces, and editor integrations | +| Lifecycle hook | Validation or generation before and after editor builds or bundling | +| Editor HTTP API | External tools, IDE integrations, test controllers, and AI agents | +| In-game test collection | Game logic, messages, components, input, physics, and engine behavior | +| Browser automation | HTML5 interaction tests, screenshots, and web integrations | +| AI coding agent | Tasks where the required files and operations are not known in advance | +| Multimodal model | Semantic analysis of scenes, GUI layouts, and runtime screenshots | + +Prefer a deterministic solution when the sequence of operations is already known. For example, a level validator should normally have stable inputs, outputs, and exit codes. + +An agent might be useful when a task requires investigation, finding the relevant resources, selecting an implementation, modifying several files, interpreting errors, and iterating towards clearly defined acceptance criteria. + +## The automation loop + +A reliable automation process should form a closed loop: + +1. Inspect - read project files, OpenAPI, and documentation +2. Change - use editor scripts, the HTTP API, or shell scripts to modify files +3. Verify - use Bob and the Editor HTTP API to build, run tests, and gather logs and images +4. Evaluate - check acceptance criteria and decide next steps: finish or retry + +![automation_loop](images/automation/automation_loop.png) + +Verification should provide evidence from the actual environment. Suitable evidence includes: + +* a successful compilation result; +* a completed test suite; +* expected output from the running game; +* a generated bundle; +* a deterministic image comparison; +* a screenshot that satisfies defined visual criteria. + +Define the expected result before making changes. Also define a timeout or a maximum number of repair attempts. An unattended process should not continue indefinitely when it cannot satisfy the acceptance criteria. + +## Starting the Defold editor from an automation tool + +To start Defold locally, an automation tool must know the path to the editor executable and the absolute path to the project's `game.project` file. + +Tools can locate installed Defold versions through the `installations.json` metadata, as described in the [Editor manual](/manuals/editor/#editor-installation-metadata). + +The `launcherPath` field contains the executable that should be started. Pass the `game.project` path as the first positional argument to open that project directly. + +The optional `--port` or `-p` argument selects the editor HTTP server port. Omitting it lets Defold choose an available port and is usually preferable when several projects may be open. + +For example: + +```sh +# Linux +/path/to/Defold/Defold --port 8181 /absolute/path/to/project/game.project +``` + +```sh +# macOS +/path/to/Defold.app/Contents/MacOS/Defold --port 8181 /absolute/path/to/project/game.project +``` + +```powershell +# Windows +C:\path\to\Defold\Defold.exe --port 8181 C:\absolute\path\to\project\game.project +``` + +The editor is a graphical desktop application, so it must be started in an interactive user session with access to the display. +Use Bob instead when a graphical editor session is unavailable, such as in headless CI. + +After launching the editor, wait until the project has finished opening and `.internal/editor.port` has been created, then poll `http://localhost:$(cat .internal/editor.port)/openapi.json` until it returns the OpenAPI document. This document provides everything the tool needs to discover and use the editor API. + +## Automating a running editor via HTTP server + +When a project is open, the editor starts a local HTTP server. Select Help ▸ Open Editor Server to open its local home page in the default web browser on localhost at the selected port: + +![editor_server](images/automation/editor_server.png) + +The selected port is also written to: + +```text +.internal/editor.port +``` + +The following variables are used in the examples below: + +```sh +PORT="$(cat .internal/editor.port)" +BASE_URL="http://127.0.0.1:$PORT" +``` + +::: important +The editor server is a local control interface for the development environment. Do not expose it through a public address or an untrusted tunnel. +::: + +## Discovering the API through OpenAPI + +The only Defold-specific bootstrap information an external tool should need to work with an open Defold editor is an `openapi.json` file hosted by the editor's local HTTP server: + +```sh +curl -sS "http://localhost:$(cat .internal/editor.port)/openapi.json" +``` + +The returned OpenAPI 3.0.3 document describes the operations supported by the current editor version, including paths, methods, parameters, command names, request formats, responses, status codes, and authentication requirements. + +List the documented paths: + +```sh +curl -sS "$BASE_URL/openapi.json" | + jq -r '.paths | keys[]' +``` + +List the available editor commands: + +```sh +curl -sS "$BASE_URL/openapi.json" | + jq -r ' + .paths["/command/{command}"].post.parameters[] + | select(.name == "command") + | .schema.enum[] + ' +``` + +A version-aware integration should read it to verify that the required operations are available and configure its tools from the returned schemas. + +Project-specific endpoints can also appear in the same document when the editor scripts that define them include an OpenAPI operation description. + +### Built-in operations + +In Defold 1.13.1, the most useful endpoints are: + +| Endpoint | Purpose | +| --------------------------- | -------------------------------------------------------- | +| `GET /openapi.json` | Discover the current editor API | +| `POST /command/{command}` | Execute an editor command | +| `GET /ref` | Search the runtime and editor API documentation (1.13.1+)| +| `GET /console` | Read the current console contents | +| `GET /console/stream` | Continuously follow console output | +| `GET /preview/{path}` | Render a supported scene resource to PNG (1.13.1+) | +| `POST /eval` | Execute authenticated Lua code in the editor environment (1.13.0+) | +| `GET`, `POST /prefs/{path}` | Read and write editor preferences | + +## Automated compiling and running + +Editor commands are invoked through: + +```text +POST /command/{command} +``` + +Compile without running the game: + +```sh +curl -sS \ + -X POST \ + "$BASE_URL/command/compile" | + jq +``` + +Compile and run: + +```sh +curl -sS \ + -X POST \ + "$BASE_URL/command/run" | + jq +``` + +A successful compilation returns: + +```json +{ + "success": true, + "issues": [] +} +``` + +A failed compilation returns HTTP status `422` with a structured list of issues: + +```json +{ + "success": false, + "issues": [ + { + "message": "Example compiler message", + "severity": "error", + "resource": "/main/player.script", + "range": { + "start": { + "line": 12, + "character": 4 + }, + "end": { + "line": 12, + "character": 17 + } + } + } + ] +} +``` + +The available fields depend on the type of error. Use the resource path and source range when available, but also handle issues that contain only a message. + +Commonly used commands include: + +`compile` +: Compile the project without running it. + +`run` +: Compile and run the project. + +`clean-build` +: Clear the build cache and rebuild the project. Use this only when a normal compilation behaves inconsistently or appears to miss changes. + +`build-html5` +: Build the project for HTML5 and open it in a browser. + +`fetch-libraries` +: Download and reload project dependencies. + +`hot-reload` +: Reload modified resources into a running game. + +`reload-extensions` +: Reload editor scripts. + +`debugger-start` +: Start the project with the debugger or attach the debugger to a running project. + +`debugger-stop` +: Stop the debugger and the running project. + +Older examples may use `/command/build`, but you should use the commands exposed by the current OpenAPI document. + +Commands that operate on project resources synchronize changes made outside the editor before execution. This makes the following loop reliable: + +```text +edit file → POST /command/compile → inspect issues +``` + +Possible command responses include: + +| Status | Meaning | +| ------ | ----------------------------------------------------- | +| `200` | The command completed and returned a result | +| `202` | The command was accepted and continues asynchronously | +| `403` | The command is not active in the current editor state | +| `404` | The command is not available | +| `422` | Compilation or validation failed | +| `500` | An internal editor error occurred | + +### HTML5 browser automation + +Automated workflows and agents can also build HTML5 through the editor: + +```sh +curl -sS \ + -X POST \ + "$BASE_URL/command/build-html5" +``` + +The command runs asynchronously and normally returns HTTP `202`. The editor serves the result at: + +```text +http://127.0.0.1:/html5/ +``` + +Wait until the address is available before starting browser tests. + +HTML5 builds can be exercised with external browser automation tools such as Playwright, Puppeteer, or Selenium. These tools can generate keyboard, mouse, and emulated touch events targeting the Defold canvas, which the engine processes through the project’s normal input bindings and `on_input()` callbacks. They can also modify the viewport size. This makes HTML5 useful for automated interaction tests. + +## Discovering documentation + +The `/ref` endpoint searches the API documentation included with the running editor version. It is the preferred source for exact API names and signatures that match the version of Defold being used. + +Search for a function: + +```sh +curl -sS \ + --get \ + --data-urlencode "q=go.animate" \ + "$BASE_URL/ref" | + jq +``` + +Filter by environment and language: + +```sh +curl -sS \ + --get \ + --data-urlencode "environment=runtime" \ + --data-urlencode "language=Lua" \ + --data-urlencode "q=collision message|raycast" \ + "$BASE_URL/ref" | + jq +``` + +Available parameters: + +`environment` +: `editor`, `runtime`, or comma-separated values. + +`language` +: `Lua`, `C`, `C++`, or comma-separated values. + +`q` +: A case-insensitive search expression. Whitespace represents the AND operator, while `|` represents OR. + +Agents should prefer focused queries instead of retrieving the entire API reference in order to save tokens. + +### Documentation as knowledge base for LLMs + +Defold also publishes official documentation in formats suitable for language models and local search tools: + +* [llms.txt](https://defold.com/llms.txt) is a concise index of individual manuals, API namespaces, and examples; +* [llms-full.txt](https://defold.com/llms-full.txt) combines all manuals, API documentation, and examples into one searchable file. + +Use `llms.txt` to retrieve only the relevant pages in the official documentation needed for the current task. + +Use `llms-full.txt` for offline search, local indexing, or [Retrieval-Augmented Generation (RAG)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation). Again, the complete file should not normally be included in every model request in order to save tokens. + +## Automating reading logs and test results + +The editor HTTP API provides access to console output. Read the current console contents as JSON using the `console` command: + +```sh +curl -sS "$BASE_URL/console" | jq +``` + +The response contains console lines in the `lines` field and semantic regions in the `regions` field, such as errors, evaluation results, and resource references. + +To continuously follow new output, use the console stream: + +```sh +curl -N "$BASE_URL/console/stream" +``` + +The connection remains open until the client closes it, such as after receiving a completion marker or an error, detecting process termination, or reaching a timeout or line limit. + +Defold can also persist the game log by setting `Write Log File` in `game.project`. Read more details about logging in the [Debugging manual](/manuals/debugging-game-and-system-logs/). File logging is particularly useful for packaged applications and tests on target devices where the editor console is unavailable. + +### Logging solutions + +Reading the console is useful only when the project logs custom information in addition to internal errors and warnings. Useful logs can help agents understand the flow of the game, detect issues, and debug more effectively. Some tools, such as Cursor, offer a debug mode that uses print statements to gather additional information, which can work well with Defold projects. + +The project can use `print()` and `pprint()` directly or adopt a community logging library from [assets tagged logging](https://defold.com/assets/?tag=logging) or [assets tagged debugging](https://defold.com/assets/?tag=debugging). + +### Automated test reporting + +Human-readable messages are useful during development and debugging, but automation should use a stable result protocol. One option is a unique prefix followed by a JSON object, e.g.: + +```text +TEST {"run":"8f13","event":"suite_start","tests":2} TEST {"run":"8f13","event":"case","name":"player_moves","status":"pass","duration_ms":3} +``` + +The collector could then search each console line for the `TEST` marker, ignoring unrelated messages, and decode and parse the JSON after it. + +Every test suite should print an unambiguous final result. A process crash, a timeout, or a disconnected stream is neither a pass nor an ordinary assertion failure and should be reported separately. + +It is good practice to store the complete console output and, when a test fails, include the test name, assertion details, elapsed time, relevant log lines, Defold version, target platform, and paths to generated artifacts. + +### Test frameworks + +Projects may implement their own small runner or use a [community library](https://defold.com/assets/?tag=testing). + +For example, [DefTest](https://defold.com/assets/deftest/) is a Defold unit-testing library based on the Telescope framework. It supports test suites, setup and teardown functions, assertions, test-name filtering, mocks for selected Defold APIs, and optional coverage collection through LuaCov. Tests can run from a dedicated bootstrap collection, including in a headless build created with Bob. + +A framework's normal console output may be sufficient for developers, but agents and CI systems should still receive an explicit final event or another unambiguous machine-readable result. If an existing framework does not provide the required format, add a small adapter around its completion callback or summary output. + +## Rendering scene previews + +Since Defold 1.13.1, a supported scene resource can be rendered to PNG through the `/preview/{path}` endpoint, for example: + +```sh +mkdir -p build/automation + +curl -sS \ + "$BASE_URL/preview/main/main.collection?width=1280&height=720" \ + --output build/automation/main-preview.png +``` + +This command creates a screenshot of the main collection from the open Basic 3D template project: + +![editor-screenshot-main](images/automation/main-preview.png) + +The following command generates a screenshot of the cube model: + +```sh +curl -sS \ + "$BASE_URL/preview/assets/models/cube.model?width=1280&height=720" \ + --output build/automation/cube-preview.png +``` + +![editor-screenshot-cube](images/automation/cube-preview.png) + +Previews can be useful in automation workflows and can help multimodal agents analyze a visual setup automatically, for example, by verifying level and GUI layouts, checking the correctness of shaders and lighting setups, performing visual regression tests, and generating documentation thumbnails. A multimodal model can evaluate semantic conditions that are difficult to express, such as clipped text, overlapping controls, unclear selection states, or content extending outside a safe area. + +The path after `/preview/` does not include a leading slash. The optional dimensions default to the project display size and must be between `1` and `4096`. + +| Status | Meaning | +| ------ | ------------------------------------------------------------- | +| `200` | The preview was rendered | +| `400` | The dimensions are invalid | +| `404` | The resource was not found | +| `422` | The resource is not loaded or does not support scene previews | + +> **Note** +> +> A preview is rendered by the editor. It is not a screenshot of the running game and does not verify scripts, user input, physics, runtime-created objects, post-processing, or platform-specific behavior. + +Use a screenshot of the running game when these elements matter. + +## Executing editor Lua code + +The authenticated `POST /eval` endpoint executes Lua code in the editor extension environment. + +The current session token is stored in `.internal/editor.token`: + +```sh +TOKEN="$(cat .internal/editor.token)" +``` + +The token is reset each session. Using the token, you can run Lua code from an external CLI: + +```sh +curl -sS \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: text/plain" \ + --data-binary 'print(editor.version) return editor.platform' \ + "$BASE_URL/eval" +``` + +Printed output and return values are provided as text: + +```text +1.13.1 +=> x86_64-linux +``` + +| Status | Meaning | +| ------ | --------------------------------------------- | +| `200` | The code was executed | +| `401` | The bearer token is missing or invalid | +| `422` | The Lua code could not be parsed or executed | +| `503` | The editor extension environment is not ready | + +A client may retry after a `503` response, but it should use a bounded number of attempts. Correct the code before repeating a request that returned `422`. + +Lua code running in the editor can use the [Editor API](https://defold.com/ref/editor-lua/). Through this API, code can use the full editor scripting environment and the Bob builder, open URLs in the default browser, run commands, and more. This can be useful for custom development workflows and for creating or modifying resources. + +It cannot use game runtime APIs such as `go.*` to manipulate the running game. Use runtime tests, the console, the debugger, or browser automation to verify gameplay. + +### Modifying resources and files + +Many Defold source resources are stored in text formats, but their schemas are implementation details of the editor. Prefer editor transactions when modifying structured resources. Choose the modification method according to the resource type: + +| Change | Preferred method | +| ------------------------------------------------------------------- | -------------------------------------- | +| Lua, shader, JSON, or another known text format | Direct file modification | +| Unsaved text in an open editor tab | `editor.get()` and `editor.transact()` | +| Collection, game object, GUI, atlas, or another structured resource | Editor transaction | +| Repeatedly generated content | Standalone generator | +| Repeatable project operation | Editor command or custom HTTP endpoint | +| CI-only transformation | Standalone script run before Bob | + +Inspect a resource before changing it: + +```sh +curl -sS \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: text/plain" \ + --data-binary ' + local path = "/game.project" + pprint(editor.properties(path)) + return editor.get(path, "path") + ' \ + "$BASE_URL/eval" +``` + +Check `editor.can_get()`, `editor.can_set()`, and the other `editor.can_*()` functions before performing a transaction. + +Use `editor.execute()` to run a formatter, validator, or generator: + +```lua +local output = editor.execute( + "python3", + "scripts/generate_levels.py", + { + out = "capture" + } +) + +print(output) +``` + +When the command does not modify project resources, set `reload_resources = false` to avoid an unnecessary reload. + +::: important +Do not modify files in `.internal/` or generated content in `build/`. +::: + +## Preferences + +Editor preferences can be read and written through: + +```text +GET /prefs/{path} +POST /prefs/{path} +``` + +For example, the following request prints the currently set font size: + +```sh +curl -sS "$BASE_URL/prefs/code/font/size" | jq +``` + +The following request sets the current font size to 16: + +```sh +curl -sS \ + -X POST \ + -H "Content-Type: application/json" \ + --data '16' \ + "$BASE_URL/prefs/code/font/size" +``` + +The editor validates the value against the preference schema. An invalid path or value returns HTTP `400`. + +Preferences are persistent user or project-user settings, not project configuration (`game.project`) stored in the repository. If an automation changes a preference temporarily, it should save the previous value and restore it after the operation. + +## Custom HTTP endpoints + +Additional endpoints can be defined with the [`get_http_server_routes()`](/manuals/editor-scripts/#http-server) editor script function. + +The optional OpenAPI operation table makes the endpoint available through the same `/openapi.json` entry point as the built-in operations. + +Custom endpoints can be useful for content generation and validation, project reports, localization checks, resource analysis, project-specific testing operations, or simplified tools for IDEs and AI agents. + +A good endpoint should perform one clearly named operation, validate its input, return a structured result, be idempotent where possible, and limit expensive operations. + +Custom endpoints are not automatically protected by the `/eval` token. When an endpoint performs sensitive operations, add project-specific authentication or additional safety measures. + +## Lifecycle hooks + +A project can contain one `hooks.editor_script` file in its root directory. + +Hooks are available before and after builds, before and after bundle creation, and when a game process starts or terminates. Only the root `hooks.editor_script` receives these events, giving the project one place in which to define the order of its steps. + +Lifecycle hooks run only in the editor. Put shared validation and generation logic in standalone scripts and invoke the same scripts from both editor hooks and CI. + +They can respond to editor lifecycle events, for example: + +```lua +local M = {} + +local function validate_project() + print(editor.execute( + "python3", + "scripts/validate_project.py", + { + out = "capture", + reload_resources = false + } + )) +end + +function M.on_build_started(opts) + validate_project() +end + +function M.on_build_finished(opts) + print("Build successful:", opts.success) +end + +return M +``` + +An error raised from `on_build_started()` stops the editor build. + +## Additional best practices for automated testing + +Use several levels of verification. Begin with the narrowest and fastest test capable of detecting the problem, then continue to runtime and platform tests. + +Prefer separate, isolated test collections. Each test should establish a known state, execute one behavior, verify the result, clean up its resources, and print a structured status. + +For more complex games, you can also create separate "development room" collections that contain predefined setups, preferably with gray-boxed blockouts, and allow you to test different mechanics or scenarios. + +### Writing reusable and testable code + +When writing code, keep reusable logic in Lua modules with minimal engine dependencies. This makes it easier to test independently of the game environment. + +Read more in the [Writing Code manual](https://defold.com/manuals/writing-code/). + +### Agentic testing workflow + +AI agents should `POST /command/compile` after each coherent group of source changes to inspect errors or warnings. Frequent, small compilation gates make it easier to identify which change introduced a problem. + +Modifying the `game.project` file allows you to select a separate bootstrap collection for tests: + +```ini +[bootstrap] +main_collection = /test/test.collectionc +``` + +After successfully running automated tests or agentic verification, it is good practice to restore the previous bootstrap collection setting. + +## Headless automation and continuous integration + +Continuous integration (CI) should use the Bob build tool. + +A basic CI process can resolve dependencies, build an archive, and generate a JSON report: + +```sh +mkdir -p build/reports + +java -jar bob.jar \ + --root . \ + --archive \ + --build-report-json build/reports/build-report.json \ + resolve build +``` + +Alternatively, build a headless test bundle with test settings: + +```sh +java -jar bob.jar \ + --root . \ + --settings test/test.settings \ + --platform x86_64-linux \ + --variant headless \ + --archive \ + --bundle-output build/test-bundle \ + resolve build bundle +``` + +Run the resulting executable with a platform-appropriate process runner and capture its exit code and logs. + +The [Bob manual](/manuals/bob) describes supported platforms, settings files, bundles, caches, native extensions, and build reports. + +An AI agent can help diagnose or repair a failed stage, but the stage itself should remain deterministic. + +## AI agents and integration layers + +Defold interfaces are model-neutral. They can be used by Claude Code, Codex, Cursor, Grok-based tools, DeepSeek, and other open-source models, as well as any custom agent environment that can: + +* read and write project files; +* execute local commands; +* send HTTP requests to `localhost`; +* parse JSON; +* inspect images when needed. + +A model available only through a chat interface can suggest code, but it cannot independently inspect the running editor or verify the result. + +### Automation integration layer + +An integration layer, sometimes referred to as an automation bridge, connects Defold to an external tool. + +The integration layer can be: + +* a shell script; +* a command-line program; +* an IDE extension; +* a client generated from OpenAPI; +* a test controller; +* an MCP server. + +The integration layer should expose controlled operations and keep authentication data local. Deterministic tools should provide verification evidence. + +When working with the editor, it should discover operations through `openapi.json`. It should not maintain a separate, permanently hard-coded copy of the editor API. + +### Model Context Protocol + +[Model Context Protocol](https://modelcontextprotocol.io/) is one possible communication protocol between an AI agent and an integration layer. An MCP server can expose Defold operations as tools and project documentation as resources. + +As of now, Defold does not provide an official MCP server. Official integration is based on the editor OpenAPI document, Bob, editor scripts, and project-defined tools. + +Keeping MCP separate from the editor core provides several advantages: + +* the editor remains independent of a specific model provider or agent protocol; +* the same interface supports automation unrelated to artificial intelligence; +* clients can use OpenAPI directly; +* an MCP adapter can expose only the operations appropriate for its environment; +* permission and confirmation policies remain under the control of the application hosting the agent. + +It might be practical to separate tools by privilege level: + +| Level | Examples | +| ------------ | ----------------------------------------------------- | +| Read-only | Project inspection, OpenAPI, `/ref`, console, preview | +| Verification | Compilation, tests, HTML5 builds, image comparisons | +| Modification | File changes, resource transactions | +| Privileged | `/eval`, external commands, dependency changes | + + +::: important +Do not give every model unrestricted shell and `/eval` access. +::: + +Community-created MCP projects include: + +* [Fulviuus/defold-mcp](https://github.com/Fulviuus/defold-mcp); +* [ChadAragorn/defold-mcp](https://github.com/ChadAragorn/defold-mcp); +* an [AIbase directory entry](https://mcp.aibase.com/server/1917146819408359426) for the ChadAragorn project. + +These projects are not developed, audited, maintained, or officially supported by the Defold Foundation. Before installing any community solution, inspect its current source code, dependencies, permissions, network behavior, tests, and compatibility with the current Defold version. + +### Project instructions and AGENTS.md + +Store project-specific automation rules in version control. A concise, canonical file, such as `AGENTS.md`, can be used across different tools' configurations. There are many resources on writing effective agent instructions; among their most important recommendations are keeping the instructions concise and maintainable. + +Agents should preferably follow the same automation loop as any other automated integration. + +Agents can also use certain `skills`, which are text files that explain to models how to perform particular actions or follow specific workflows. + +One good example of agent instructions and a set of custom skills suited to Defold can be found [here](https://forum.defold.com/t/agent-config-collection-of-agents-md-and-skills/82387). + +## Security + +Automation is part of the project's security model. + +* Connect to the editor server through `127.0.0.1` and do not expose its port publicly. +* Treat the entire editor HTTP server as a trusted local control interface. +* Protect `.internal/editor.token`; it grants access to `/eval`. +* Allow the local integration layer to use the token without placing it in model prompts or reports. +* Remember that custom endpoints are not authenticated automatically. +* Do not provide a general AI agent with signing keys, deployment tokens, store credentials, or production secrets. +* Run broad autonomous changes in a separate branch, worktree, temporary copy, container, or restricted account. +* Require approval before deleting resources, adding dependencies, changing native extensions, modifying release settings, publishing bundles, or accessing external services. +* Treat issue content, imported files, source comments, and generated data as untrusted input. +* Verify that project policy allows code, assets, logs, or screenshots to be sent to a hosted model. + +Before using a third-party integration layer or MCP server, inspect what it can read, write, execute, download, and expose over the network. diff --git a/docs/en/manuals/images/automation/automation_loop.png b/docs/en/manuals/images/automation/automation_loop.png new file mode 100644 index 0000000000000000000000000000000000000000..637adb60f23241c77a53f8f533ea46e62a90e1a2 GIT binary patch literal 38438 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 XZ_bP0l+XkK;%15# literal 0 HcmV?d00001 diff --git a/docs/en/manuals/images/automation/cube-preview.png b/docs/en/manuals/images/automation/cube-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..56176916f7452f69c96544785449005c1b2bf910 GIT binary patch literal 86923 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 literal 0 HcmV?d00001 diff --git a/docs/en/manuals/images/automation/editor_server.png b/docs/en/manuals/images/automation/editor_server.png new file mode 100644 index 0000000000000000000000000000000000000000..886dc97b79bf292d652771db9b781df0f7400142 GIT binary patch literal 66838 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

N5h-7tEQ)0E)-*8EpgY4_ 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 a@QTi+vW6J(NcJBEPhMIXTqgP9>;D1-FNfp+ literal 0 HcmV?d00001 diff --git a/docs/en/manuals/images/automation/main-preview.png b/docs/en/manuals/images/automation/main-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..ec29606acb0c69a1e04118dd09d1539dfd0c3638 GIT binary patch literal 10673 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%0AvPd?lJ|IWN*OdD zdT7))3(2%o&6{H7M~OkjV}x}pUP4-b-SdzbLTIKPu-JqwB%gJsIjZpK5u@HC{fmJc zLc+mN#sf+xqoA4hq&W&25;3+$U9*sktwXtEtb(vQP_YeJpH+2&UVrV`kZ49|##Ugl z9~ts8>rOSgFjLQHNUwhpaJvTcdeE2gfXF5k6!Xf8r<6bg;yaDY%|g=6)AL3wnM5|I zI6XHcHz7^r`mGga(u%JQQmtXm?&M$(Hu$a2%i*zeN+D^u5be_Vm08FyCY8DG3?CfJ z1Qp|mbWv5p5z(ttA*HI&Z@_|v09wqt^AmbYlAid2o=6Qe!Uem82dljsEp}HQtStAa z)JM^65r#aIwLPDH5-Y@k?SueEnOjDmLu$kgqSvXhn?aiJ~BXYJu$>Ai- zXw_jH_poS3c}}?I{$qxJ77i}vRwd-to;$n$onhK*`?=Dg(^Aii+McP(D{@Ym??0+B zR~|LREo9*ql2=tO6W?E7`)A$Rg<$7RkWKfsO=5~hhLn-IVfIBLFM$}CW#7U6wU|Z& ztKwjoEIyXS54}cAmo{577lZE*>WWvG6-N;t5hb1Nq9PQ1BZ9IR$1N_Xi6#sgb~IB^ zbo>8dqcx6eUGU1D*c;GMZH1z{A>#kGv6Y1z9(vv?6|}Y}BNbPtrFdQfi>Zq5BI5%! z=PEERi7U*i%a#vYi^^?8MSxB~#!F@4YD1r&#CKBh0qWo-V%dq>X4OwMhJzW@Qw*r8 zIfW>fg@X!sKgbg)nn@G`uqq4Dm^VXr$o63tOZ=QwpbYw;>Kxs;`l2@8PubhDx_o=J z6`)5UM*MFZe@fDJPS&I?rnzfi9Ds!p0_b-Z?)}(p=Izl}x1s8q2r+EkE#8aJ)&$&3 zD)}V~MUO%#|0z-1Icaga?#E93Z~_PlKv3SsaXor>u6GvRb-t_)YLRead6=Oa;%9p7 z0rm8QFcf`iPWqy@bK(ML-JSpgoEr$rM5I^axJ&Rami+X@Cr(!jq|TZ8MXY62s>S)$ z;-=NrDnJBRjuT7`%%B3Pvl*@arlBTCHAjNPX@)7ra8dp^#`ml}2x226US-|s!&>BA zm7aXXg1A5ka;;9dihrK!+WBlPbR{7|>N}>|X0Df&I}QyRZnn}u%5BRIZt%XYr&@f! z5#tvE6^xN7b}>vX=ezBQr-U5FxR3n>XRCgBw3b zI-b+742BWCSYOtLdUzHNV9Ey|mz~Q?`*GZL{V%Q)!%3v@&7fk=<<_xq*T_d-TbGvD zprPUwT>Uo139&43l*c8?=oqD58N5dvzWK8DP^M}TR%#e1h1_s6((x9SRfqPtOA${{ z>QDgt4NM}|#G66ZXgq$4O1nh{;3lG%>FNYF&v|6JQ$m9((5;99-`IGMV+=!Dq?w~s zdr%RBFzdj&Q_s3`ufDtsy2_!SL*ge5=aPkAy*G;rmA?T{og1(!!GX8)s)IBJzB$r> zuY6n>dS>1jjYIj<`q+u>fL@6R=T#?oC7(N-=b#Gx2D&W}Yuv!X-M|NFct>q!gf9XW zaIH7{q8E<4fmfl=_~?gyrwiy_hkG(Ol~FjJme??hAX_p?Hj%ICnHkRD>Jp? zCy=02(5%%1t;oJD+^!cXDqw2L;BFFh8tgHYvlLs*S1t zSswFeU3VEPkkL9St+13~c0)e`r$A)T7#5DxrOX?a>bH$bp+S*!RDOwJ#hf5#9 zmm@=n&Tn!Pj&YO&h;8I!ZKD7*BQu@GyGVn(gM|HV(qKTRAksqY8~KXuSSh+ez5)ax z8;>e6cC}x{S^H!_UyZS(Em5`4U ut5sIP{Sp^A!4F+6I{dI$2VKko5VVn9;?IdcTX-05-0N~+SHaGpAO8bE4eba3 literal 0 HcmV?d00001 From 099aff3704ac2f80745461fe967208bd3532a9d3 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Thu, 30 Jul 2026 19:18:47 +0200 Subject: [PATCH 02/13] Fixed spelling issues and expanded wordlist. --- .wordlist.txt | 9 +++++++++ docs/en/manuals/automation-workflows.md | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.wordlist.txt b/.wordlist.txt index 8d6fbd33..a15ac041 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -13,6 +13,7 @@ admob Adoptium Adreno agentic +AIbase alt Andrioli androideabi @@ -64,6 +65,7 @@ callstack CCD CDN Celtoys +ChadAragorn checkboxes checksums childed @@ -84,6 +86,7 @@ Commonmark config ConfigFile configurability +configurators coroutine coroutines CORS @@ -260,6 +263,7 @@ lifecycle linkers liveupdate lldb +LLM localhost Localizations lookups @@ -269,6 +273,7 @@ LSP Lua Lua's Luacheck +LuaCov luaj luajit LuaMem @@ -278,6 +283,7 @@ LZ4 macOS mathematic Mbed +MCP metamethods metatables Middleware @@ -397,6 +403,7 @@ Rodrigo Rosen RPG scalable +schemas scriptable scroller SD @@ -504,6 +511,7 @@ unlockable Unreferenced unscaled unstripped +untrusted upscaled upscaling URI @@ -511,6 +519,7 @@ userdata UUID UV UVs +validator Vararg varyings vec diff --git a/docs/en/manuals/automation-workflows.md b/docs/en/manuals/automation-workflows.md index 4d1b40ab..edeb5507 100644 --- a/docs/en/manuals/automation-workflows.md +++ b/docs/en/manuals/automation-workflows.md @@ -347,8 +347,8 @@ Agents should prefer focused queries instead of retrieving the entire API refere Defold also publishes official documentation in formats suitable for language models and local search tools: -* [llms.txt](https://defold.com/llms.txt) is a concise index of individual manuals, API namespaces, and examples; -* [llms-full.txt](https://defold.com/llms-full.txt) combines all manuals, API documentation, and examples into one searchable file. +* the [LLM documentation index](https://defold.com/llms.txt) is a concise index of individual manuals, API namespaces, and examples; +* the [full LLM documentation](https://defold.com/llms-full.txt) combines all manuals, API documentation, and examples into one searchable file. Use `llms.txt` to retrieve only the relevant pages in the official documentation needed for the current task. @@ -733,8 +733,8 @@ Do not give every model unrestricted shell and `/eval` access. Community-created MCP projects include: -* [Fulviuus/defold-mcp](https://github.com/Fulviuus/defold-mcp); -* [ChadAragorn/defold-mcp](https://github.com/ChadAragorn/defold-mcp); +* the [Fulviuus Defold MCP project](https://github.com/Fulviuus/defold-mcp); +* the [ChadAragorn Defold MCP project](https://github.com/ChadAragorn/defold-mcp); * an [AIbase directory entry](https://mcp.aibase.com/server/1917146819408359426) for the ChadAragorn project. These projects are not developed, audited, maintained, or officially supported by the Defold Foundation. Before installing any community solution, inspect its current source code, dependencies, permissions, network behavior, tests, and compatibility with the current Defold version. From 59b1f952ea749c7ca6245a747e53a086ef0012bd Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Thu, 30 Jul 2026 19:20:04 +0200 Subject: [PATCH 03/13] Fixed missing line break. --- docs/en/manuals/automation-workflows.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/en/manuals/automation-workflows.md b/docs/en/manuals/automation-workflows.md index edeb5507..6882deb7 100644 --- a/docs/en/manuals/automation-workflows.md +++ b/docs/en/manuals/automation-workflows.md @@ -385,7 +385,8 @@ The project can use `print()` and `pprint()` directly or adopt a community loggi Human-readable messages are useful during development and debugging, but automation should use a stable result protocol. One option is a unique prefix followed by a JSON object, e.g.: ```text -TEST {"run":"8f13","event":"suite_start","tests":2} TEST {"run":"8f13","event":"case","name":"player_moves","status":"pass","duration_ms":3} +TEST {"run":"8f13","event":"suite_start","tests":2} +TEST {"run":"8f13","event":"case","name":"player_moves","status":"pass","duration_ms":3} ``` The collector could then search each console line for the `TEST` marker, ignoring unrelated messages, and decode and parse the JSON after it. From 2963a4b66e00ca4c49782b62a21a64c8ce11062a Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Thu, 30 Jul 2026 19:22:16 +0200 Subject: [PATCH 04/13] Added nickname to wordlist. --- .wordlist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.wordlist.txt b/.wordlist.txt index a15ac041..ce6dfaf3 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -157,6 +157,7 @@ framerate frontend FSAA Fullscreen +Fulviuus FX GameAnalytics Gameboy From 94e9e38ec6f787cc321413dd2b059aa6ff7831a1 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Sat, 1 Aug 2026 20:39:33 +0200 Subject: [PATCH 05/13] Separated automation workflows manual into 4 separate manuals and added 5th on engine service. --- .wordlist.txt | 1 - docs/en/en.json | 25 + docs/en/manuals/ai-agents.md | 186 ++++++ docs/en/manuals/automated-testing.md | 213 +++++++ docs/en/manuals/automation-workflows.md | 768 ------------------------ docs/en/manuals/automation.md | 88 +++ docs/en/manuals/editor-http-api.md | 478 +++++++++++++++ docs/en/manuals/engine-service.md | 160 +++++ 8 files changed, 1150 insertions(+), 769 deletions(-) create mode 100644 docs/en/manuals/ai-agents.md create mode 100644 docs/en/manuals/automated-testing.md delete mode 100644 docs/en/manuals/automation-workflows.md create mode 100644 docs/en/manuals/automation.md create mode 100644 docs/en/manuals/editor-http-api.md create mode 100644 docs/en/manuals/engine-service.md diff --git a/.wordlist.txt b/.wordlist.txt index ce6dfaf3..57ec165e 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -13,7 +13,6 @@ admob Adoptium Adreno agentic -AIbase alt Andrioli androideabi diff --git a/docs/en/en.json b/docs/en/en.json index bf0c09de..5431130c 100644 --- a/docs/en/en.json +++ b/docs/en/en.json @@ -1644,6 +1644,31 @@ ], "divider": true }, + { + "name": "Automation", + "items": [ + { + "path": "/manuals/automation", + "name": "Overview" + }, + { + "path": "/manuals/editor-http-api", + "name": "Editor HTTP API" + }, + { + "path": "/manuals/engine-service", + "name": "Engine service" + }, + { + "path": "/manuals/automated-testing", + "name": "Automated testing" + }, + { + "path": "/manuals/ai-agents", + "name": "AI coding agents" + } + ] + }, { "name": "Workflow", "items": [ diff --git a/docs/en/manuals/ai-agents.md b/docs/en/manuals/ai-agents.md new file mode 100644 index 00000000..db945663 --- /dev/null +++ b/docs/en/manuals/ai-agents.md @@ -0,0 +1,186 @@ +--- +title: Using AI coding agents with Defold +brief: This manual explains how to connect model-neutral coding agents to Defold automation interfaces while keeping verification, permissions, and security explicit. +--- + +# Using AI coding agents with Defold + +AI coding agents can inspect, modify, and verify Defold projects by calling the same model-neutral interfaces used by developers, local scripts, IDE integrations, and CI. Use an agent when the work requires investigation and adaptation; keep known build, test, validation, and deployment stages deterministic. + +Defold does not depend on a particular model provider or agent protocol. An agent environment only needs the specific capabilities granted for the task, such as reading project files, executing selected commands, calling local HTTP operations, parsing JSON, and inspecting images. + +## When an agent is appropriate + +Prefer an ordinary script or test when the sequence of operations is known. Stable generators, formatters, validators, builds, and regression tests should have predictable inputs, outputs, timeouts, and exit codes. + +An agent can be useful when a task requires these activities: + +* finding relevant resources and documentation; +* selecting among possible implementations; +* changing related files whose locations were not known in advance; +* interpreting build or test failures; +* comparing a visual result with semantic acceptance criteria; +* making a bounded repair attempt based on collected evidence. + +The agent should not invent its own definition of success. Define acceptance criteria and the available verification steps before it begins changing the project. + +## Model-neutral Defold interfaces + +You can build an integration from the smallest set of supported interfaces needed for the task using any available model: + +* Project files and shell tools provide direct inspection and controlled text changes. +* [Editor scripts](/manuals/editor-scripts) provide project-specific resource operations and tools. +* The [editor HTTP API](/manuals/editor-http-api) provides editor commands, build results, console output, reference search, previews, preferences, and editor-script routes. +* The [engine service and runtime automation APIs](/manuals/engine-service) provide live debug-engine state, input, screenshots, and extension-defined operations. +* [Bob](/manuals/bob) provides command-line builds, reports, archives, and bundles. +* [Automated tests](/manuals/automated-testing) provide deterministic completion events and failure evidence. + +A model available only through a chat interface can suggest code, but it cannot independently inspect the local project or verify a running result. The surrounding integration determines what the agent can actually observe and do. + +## Integration layers + +An integration layer connects an agent to local Defold operations. It can be a shell wrapper, command-line program, IDE extension, OpenAPI client, test controller, or protocol adapter. + +Keep policy and credentials in this local layer. Expose small, well-named operations rather than unrestricted access when possible. Each mutating operation should return structured results or lead to a deterministic verification step. + +For editor operations, discover the current interface through `/openapi.json`; do not give the agent a permanently hard-coded copy of an experimental API. For runtime extensions, check their health, API version, and capabilities. + +### Model Context Protocol + +[Model Context Protocol](https://modelcontextprotocol.io/) (MCP) is one optional adapter between an agent and an integration layer. An MCP server can expose Defold operations as tools and selected documentation as resources. + +MCP is not required by Defold. Keeping the adapter separate from the engine and editor means that: + +* the supported Defold interfaces remain independent of a model provider or agent protocol; +* non-AI clients can use OpenAPI and command-line tools directly; +* an adapter can expose only operations appropriate for its environment; +* permission and confirmation policies remain with the application hosting the agent; +* the adapter can translate stable agent tools into version-specific editor or extension requests. + +Do not assume that installing an MCP server makes its operations official or safe. Review the adapter as executable third-party code. + +## Privilege separation + +Separate capabilities by risk and grant only the levels needed for the current task: + +| Level | Examples | +| --- | --- | +| Read-only | Project inspection, OpenAPI, `/ref`, console, and editor previews | +| Verification | Builds, tests, HTML5 output, runtime observations, and image comparisons | +| Modification | File changes, resource transactions, and generated content | +| Privileged | `/eval`, arbitrary external commands, dependencies, signing, and publishing | + +::: important +Do not give every model unrestricted shell and `/eval` access. The editor token and broad command execution can provide control over the local development environment. +::: + +The local integration layer can read `.internal/editor.token` when authorized to use `/eval`, but it should not place the token in model prompts, logs, or reports. + +## Project instructions + +Available Large Language Models used for agentic workflows generally perform better with good instructions. Therefore, agents markdown files describing their desired behaviour, or skills are often being added to projects. It is good to design and write your own instructions for each project separately for best results, but some common knowledge and rules could be re-used. + +A first file that many agents search for and read is a canonical file such as `AGENTS.md` that can describe: + +* project structure and important entry points; +* formatting and naming conventions; +* commands for builds, tests, and validation; +* required completion events and artifact locations; +* files or directories that must not be changed; +* operations that require approval; +* platform assumptions and known limitations. + +Keep the instructions up-to-date, specific, and short enough to review. You can store concise project-specific instructions in version control and manage their changes to increase performance of the workflows. + +Where an agent platform supports reusable skills or workflows, make them call the same canonical project scripts rather than duplicating build and test logic in provider-specific configuration. + +One community example of Defold-oriented instructions and skills is available in the [Defold forum here](https://forum.defold.com/t/agent-config-collection-of-agents-md-and-skills/82387). + +## Documentation discovery + +In order for agents to perform well, a good and actual documentation is needed. One can gather actual informations from: + +* `/openapi.json` describes the current editor HTTP API. +* `/ref` searches API documentation included with the running editor when that operation is available. +* The [LLM documentation index](https://defold.com/llms.txt) links to official manuals, API namespaces, and examples. +* The [full LLM documentation](https://defold.com/llms-full.txt) supports offline search and local indexing. + +Retrieve only the relevant pages for the task. Use the full combined document for offline indexing or or [Retrieval-Augmented Generation (RAG)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation). Again, the complete file should not normally be included in every model request in order to save tokens. + +## Bounded change and verification loops + +Agents should follow the same [inspect, change, verify, evaluate loop](/manuals/automation/#the-automation-loop) as any other automation. + +Before changing files, define: + +* the acceptance criteria; +* the permitted files and operations; +* the build and test commands; +* required logs, reports, state, or images; +* a timeout for every asynchronous step; +* a maximum number of repair attempts. + +Compile or build after each coherent group of changes, then run the narrowest relevant test. A failed build should produce structured issues. A runtime suite should produce an explicit completion event. A timeout or crashed process must be classified separately from an assertion failure. + +An agent may diagnose and repair a deterministic CI failure, but the CI stage itself should remain reproducible without the agent. + +## Multimodal evaluation + +An agent with image input can inspect [editor previews](/manuals/editor-http-api/#rendering-scene-previews), runtime screenshots, visual differences, and browser captures. + +Use multimodal evaluation for semantic questions such as clipped labels, overlapping controls, unclear selection states, composition, or content outside a safe area. Define the expected viewport and criteria in advance. + +Do not use a screenshot as the only proof for logic that can be asserted deterministically. An editor preview also cannot verify runtime scripts, physics, dynamic objects, or platform-specific rendering. See [Editor previews and runtime screenshots](/manuals/automated-testing/#editor-previews-and-runtime-screenshots). + +## MCP integrations + +[Model Context Protocol](https://modelcontextprotocol.io/) is one possible communication protocol between an AI agent and an integration layer. An MCP server can expose Defold operations as tools and project documentation as resources. + +As of now, Defold does not provide an official MCP server. Official integration is based on the editor OpenAPI document, Bob, editor scripts, and project-defined tools. + +Keeping MCP separate from the editor core provides several advantages: + +* the editor remains independent of a specific model provider or agent protocol; +* the same interface supports automation unrelated to artificial intelligence; +* clients can use OpenAPI directly; +* an MCP adapter can expose only the operations appropriate for its environment; +* permission and confirmation policies remain under the control of the application hosting the agent. + +It might be practical to separate tools by privilege level: + +| Level | Examples | +| ------------ | ----------------------------------------------------- | +| Read-only | Project inspection, OpenAPI, `/ref`, console, preview | +| Verification | Compilation, tests, HTML5 builds, image comparisons | +| Modification | File changes, resource transactions | +| Privileged | `/eval`, external commands, dependency changes | + + +::: important +Do not give every model unrestricted shell and `/eval` access. +::: + +### Community MCP integrations + +Community-created MCP integrations include: + +* the [Fulviuus Defold MCP project](https://github.com/Fulviuus/defold-mcp); +* the [ChadAragorn Defold MCP project](https://github.com/ChadAragorn/defold-mcp). + +These projects are not developed, audited, maintained, or officially supported by the Defold Foundation. Before installing any community integration, inspect its current source, dependencies, permissions, network behavior, tests, and compatibility with the Defold version in use. + +## Security and isolation + +Agent-driven automation is part of the project's security model: + +* Connect to editor and runtime development services through `127.0.0.1`; never expose them publicly. +* Treat the editor server and engine service as trusted local control interfaces. +* Keep editor tokens, signing keys, deployment tokens, store credentials, and production secrets out of prompts and reports. +* Require approval before deletion, dependency changes, native extension changes, release configuration, signing, publishing, or access to external services. +* Run broad autonomous work in a separate branch, worktree, temporary copy, container, sandbox, or restricted account. +* Treat issue text, imported files, source comments, generated documents, and tool output as untrusted input rather than instructions. +* Review downloaded dependencies and scripts before executing them. +* Verify that project policy allows source code, assets, logs, screenshots, and other project data to be sent to a hosted model. +* Retain a reviewable diff and deterministic test evidence before accepting changes. + +Isolation limits the impact of a mistake; it does not expand the operations that an agent is authorized to perform. diff --git a/docs/en/manuals/automated-testing.md b/docs/en/manuals/automated-testing.md new file mode 100644 index 00000000..0986ee2d --- /dev/null +++ b/docs/en/manuals/automated-testing.md @@ -0,0 +1,213 @@ +--- +title: Automated testing and verification +brief: This manual explains how to design, run, and report deterministic Defold tests locally, in a running game, in browsers, and in continuous integration. +--- + +# Automated testing and verification + +Automated testing verifies Defold code and content with explicit, machine-readable evidence. Use this manual to design tests that work with local scripts, CI runners, and coding agents alike. It covers module tests, running collections, browser tests, runtime automation, visual checks, headless builds, and provides useful good practices. + +## Verification levels + +Begin with the narrowest and fastest check that can detect the problem, then add runtime or platform tests where needed: + +| Level | Suitable evidence | +| --- | --- | +| Static validation | Parser, formatter, resource validator, or generated-file comparison | +| Module test | Assertion results for reusable Lua logic with minimal engine dependencies | +| Running collection | Messages, components, input, physics, lifecycle, and engine behavior | +| Runtime automation | Live scene state, injected input, application state, and runtime screenshots | +| HTML5 browser test | Canvas input, browser integration, viewport behavior, and web output | +| Platform test | Behavior and rendering from the actual target platform | +| Build and bundle | Bob exit status, build report, archive, and bundle artifacts | + +A successful compilation proves that the project builds; it does not prove gameplay behavior. A screenshot proves what one frame looked like; it does not prove a hidden state transition, calculation, or message exchange. Prefer deterministic assertions whenever the condition can be expressed directly. + +## Reusable and testable Lua + +Keep reusable logic in Lua modules with minimal engine dependencies. Pure data transformations, rules, state machines, and calculations can then be exercised without constructing a complete game world. + +Separate engine-facing code from the logic it invokes. A script can translate messages and component state into calls to a module, while tests call the module directly with controlled inputs. See the [Writing Code manual](/manuals/writing-code). + +## Tests in a running collection + +Use a dedicated test collection when the behavior depends on game objects, components, messages, input, physics, or other engine systems. + +Each test should: + +1. establish a known state; +2. execute one behavior; +3. assert the expected result; +4. clean up created resources; +5. emit a structured result. + +Prefer isolated test collections over starting the entire game. A project can select a test bootstrap collection through a settings file or a temporary project setting: + +```ini +[bootstrap] +main_collection = /test/test.collectionc +``` + +Do not leave a temporary test bootstrap in the project's normal configuration. In CI, prefer a dedicated settings file passed to Bob. + +For complex games, create small "development room" collections with predefined scenarios and simple blockouts. They make mechanics reproducible without navigating through unrelated game state. + +### Test frameworks + +Projects can implement a small runner or use a [community testing library](https://defold.com/assets/?tag=testing). + +For example, [DefTest](https://defold.com/assets/deftest/) is a unit-testing library based on Telescope. It supports suites, setup and teardown functions, assertions, name filtering, mocks for selected Defold APIs, and optional LuaCov coverage. Tests can run from a dedicated bootstrap collection, including in a headless bundle created with Bob. + +A framework's normal console summary can be useful to developers, but an unattended controller still needs an explicit completion result. Add a small adapter around the framework callback or summary if necessary. + +## Structured test results + +Human-readable logs help with diagnosis, while automation needs a stable result protocol. One simple protocol uses a unique prefix followed by one JSON object on each physical console line: + +```text +TEST {"run":"8f13","event":"suite_start","tests":2} +TEST {"run":"8f13","event":"case","name":"player_moves","status":"pass","duration_ms":3} +TEST {"run":"8f13","event":"case","name":"player_stops","status":"pass","duration_ms":2} +TEST {"run":"8f13","event":"suite_end","status":"pass","passed":2,"failed":0} +``` + +Do not pretty-print one event across several log lines. A collector should process each line independently, find the `TEST` prefix, parse the JSON that follows, and ignore unrelated engine output. + +Include a unique run identifier so output from an old or concurrent process cannot complete the current run. Every suite must emit one unambiguous final event. + +Report these outcomes separately: + +| Outcome | Meaning | +| --- | --- | +| Pass | A matching final event reports success | +| Assertion failure | The suite completed and reported failed assertions | +| Crash | The engine process terminated unexpectedly | +| Timeout | The expected final event did not arrive before the deadline | +| Disconnected | The output channel closed while the process state remained uncertain | + +A crash, timeout, or disconnected stream is not an ordinary assertion failure and must never be inferred as a pass. + +## Collecting console output + +When a game runs from the editor, the [editor HTTP API](/manuals/editor-http-api/#reading-console-output) provides both current console history and a continuous stream: + +```sh +PORT="$(cat .internal/editor.port)" +BASE_URL="http://127.0.0.1:$PORT" + +curl -sS "$BASE_URL/console" | jq +curl -N "$BASE_URL/console/stream" +``` + +Close the stream after a matching suite completion event, process termination, an error, or a configured timeout and line limit. + +Defold can also persist the game log by enabling `Write Log File` in `game.project`. See [Game and system logs](/manuals/debugging-game-and-system-logs/). File logging is useful for packaged applications and target devices where the editor console is unavailable. + +The project can use `print()` and `pprint()` or a [community logging library](https://defold.com/assets/?tag=logging). Keep diagnostic logging separate from the structured result prefix. + +## Testing a running game through a runtime API + +A runtime automation API can inspect and control a live debug engine. Use it when tests must find runtime objects, inject input, wait for visible state, or capture the rendered result. The [engine service manual](/manuals/engine-service/#automation-bridge-extension) explains how these routes differ from editor operations. + +The following example uses the current Automation Bridge Python helper structure. The project must include a compatible version of the debug extension, expose an element with the given automation id, and publish the `screen` application state: + +```python +from automation_bridge import editor + +project = editor.open_project(".") +game = project.build_and_run() + +try: + play = game.element(automation_id="play_button") + game.click(play) + game.wait_for_state("screen", "gameplay", timeout=5.0) + screenshot = game.screenshot() + print(screenshot.path) +finally: + game.close_engine() +``` + +Application-defined states and automation ids use Automation Bridge's optional debug-only Lua API, which the project must enable and publish. A fixed sleep is vulnerable to machine speed and frame timing; bounded polling for a defined state is more reliable. + +Automation Bridge is an extension, not part of the core engine. Consult its [Python API reference](https://github.com/defold/extension-automation-bridge/tree/master/automation_bridge/automation-bridge-python) for installed-version selectors, waits, state, events, screenshots, and diagnostics. + +## Browser tests for HTML5 + +The editor can create and serve an HTML5 build through its current `build-html5` command, as described in the [editor HTTP API manual](/manuals/editor-http-api/#building-html5). Bob can also create an HTML5 bundle without the editor. + +External browser automation can: + +* wait for the Defold canvas and application readiness; +* send keyboard, mouse, and emulated touch input; +* resize the viewport; +* collect browser console output and JavaScript errors; +* take screenshots and compare artifacts. + +Input directed at the canvas is processed through the project's normal input bindings and `on_input()` callbacks. Test both the game response and browser-specific integration points. + +Keep browser tests bounded. Distinguish a page-load failure, missing canvas, JavaScript error, test timeout, and failed game assertion in the final report. + +## Editor previews and runtime screenshots + +The two image sources answer different questions: + +| Image | Use it for | It does not prove | +| --- | --- | --- | +| [Editor preview](/manuals/editor-http-api/#rendering-scene-previews) | Loaded resource layout, static scene composition, editor rendering, and thumbnails | Runtime scripts, physics, input, dynamic objects, or target-platform rendering | +| Runtime screenshot | The rendered state of a running build after a controlled scenario | Hidden logic, complete interaction history, or state not visible in the frame | + +Need to inspect a `.collection` without starting the game? Use an editor preview. Need to verify dynamically spawned objects or post-processing after gameplay input? Use a runtime screenshot after deterministic setup and assertions. + +### Visual regression + +For stable rendering, compare the produced image with an approved baseline. Fix the viewport, display settings, test content, frame or synchronization point, platform, and tolerance. Store the difference image and comparison metrics when a check fails. + +A multimodal model can evaluate semantic conditions that are difficult to express as pixels, such as clipped text, overlapping controls, unclear selection states, or content outside a safe area. Treat that evaluation as an additional signal with explicit criteria, not as a substitute for deterministic logic checks or image comparison. + +## Headless tests and CI + +Use [Bob](/manuals/bob) for editor-independent CI. + +A basic job can resolve dependencies, build an archive, and generate a JSON report: + +```sh +mkdir -p build/reports + +java -jar bob.jar \ + --root . \ + --archive \ + --build-report-json build/reports/build-report.json \ + resolve build +``` + +Build a headless test bundle with dedicated settings: + +```sh +java -jar bob.jar \ + --root . \ + --settings test/test.settings \ + --platform x86_64-linux \ + --variant headless \ + --archive \ + --bundle-output build/test-bundle \ + resolve build bundle +``` + +Run the resulting executable with a platform-appropriate process controller. Capture its exit status and logs, enforce a timeout, and require the structured suite completion event. Headless builds do not provide graphical evidence, so run a separate graphical or platform test when rendering matters. + +The Bob manual describes platforms, settings files, bundles, caches, native extensions, and build reports. + +## Failure reports and artifacts + +Retain enough evidence to reproduce and diagnose a failure: + +* test name, run identifier, and assertion details; +* elapsed time and classified outcome; +* complete console or process log; +* Defold version, target platform, and relevant configuration; +* Bob build report and process exit status; +* runtime state or scene snapshot when available; +* screenshots, baseline differences, recordings, or browser traces; +* paths or links to all generated artifacts. + +The same evidence format should be usable by a developer, local script, CI service, or [AI coding agent](/manuals/ai-agents). This keeps verification deterministic even when diagnosis or repair is delegated. diff --git a/docs/en/manuals/automation-workflows.md b/docs/en/manuals/automation-workflows.md deleted file mode 100644 index 6882deb7..00000000 --- a/docs/en/manuals/automation-workflows.md +++ /dev/null @@ -1,768 +0,0 @@ ---- -title: Automation and working with AI agents -brief: This manual explains how to automate the Defold editor and build process, create project-specific tools, run automated tests, and connect AI coding agents and multimodal models to processes whose results can be verified unambiguously. ---- - -# Automation and working with AI agents - -Defold supports automation at several levels: - -* [editor scripts](/manuals/editor-scripts) allow you to customize editor workflows, add specific tools, and speed up the creation of levels, assets, etc. -* [editor UI scripts](/manuals/editor-scripts-ui/) allow you to create custom visual tools, popups, configurators, etc. -* [editor HTTP API](https://github.com/defold/defold/blob/dev/editor/doc/http-api.md) allows you to control an open project via OpenAPI operations. -* [Bob CLI](/manuals/bob) can build a project and create data archives or standalone bundles from the command line. -* shell scripts can generate, validate, and manage files. - -Therefore, Defold can offer: - -* team- or project-specific processes and tool integrations; -* repeatable, custom commands used during project development; -* content generation and validation; -* local testing tools; -* continuous integration (CI); -* IDE integrations; -* support for AI coding agents; -* visual and multimodal analysis. - -Defold is well suited to these tasks because it combines text-based project files that are easy to edit and manage with version control—Lua scripts and Protobuf-based resource files—with version-matched API documentation, a machine-readable editor interface, structured compilation results, observable runtime output, scene previews, an extensible editor, and a command-line build tool. LLM coding agents can be an optional layer on top of this toolset. Test collections, browser automation, image comparison tools, or multimodal models can be used to verify the results. - -::: important -The editor HTTP API is experimental and may change between Defold versions. Always read the OpenAPI document generated by the currently running editor. -::: - -## Choosing an automation interface - -Choosing an interface appropriate to the task is one of the most important aspects of effective automation. The table below can help you choose the simplest interface for a given action: - -| Interface | Suitable for | -| --------------------------- | ------------------------------------------------------------------------- | -| Shell script or task runner | Generation, formatting, validation, and repeatable local tasks | -| Bob | Editor-independent builds, bundles, reports, and CI | -| Editor script | Custom commands, resource tools, user interfaces, and editor integrations | -| Lifecycle hook | Validation or generation before and after editor builds or bundling | -| Editor HTTP API | External tools, IDE integrations, test controllers, and AI agents | -| In-game test collection | Game logic, messages, components, input, physics, and engine behavior | -| Browser automation | HTML5 interaction tests, screenshots, and web integrations | -| AI coding agent | Tasks where the required files and operations are not known in advance | -| Multimodal model | Semantic analysis of scenes, GUI layouts, and runtime screenshots | - -Prefer a deterministic solution when the sequence of operations is already known. For example, a level validator should normally have stable inputs, outputs, and exit codes. - -An agent might be useful when a task requires investigation, finding the relevant resources, selecting an implementation, modifying several files, interpreting errors, and iterating towards clearly defined acceptance criteria. - -## The automation loop - -A reliable automation process should form a closed loop: - -1. Inspect - read project files, OpenAPI, and documentation -2. Change - use editor scripts, the HTTP API, or shell scripts to modify files -3. Verify - use Bob and the Editor HTTP API to build, run tests, and gather logs and images -4. Evaluate - check acceptance criteria and decide next steps: finish or retry - -![automation_loop](images/automation/automation_loop.png) - -Verification should provide evidence from the actual environment. Suitable evidence includes: - -* a successful compilation result; -* a completed test suite; -* expected output from the running game; -* a generated bundle; -* a deterministic image comparison; -* a screenshot that satisfies defined visual criteria. - -Define the expected result before making changes. Also define a timeout or a maximum number of repair attempts. An unattended process should not continue indefinitely when it cannot satisfy the acceptance criteria. - -## Starting the Defold editor from an automation tool - -To start Defold locally, an automation tool must know the path to the editor executable and the absolute path to the project's `game.project` file. - -Tools can locate installed Defold versions through the `installations.json` metadata, as described in the [Editor manual](/manuals/editor/#editor-installation-metadata). - -The `launcherPath` field contains the executable that should be started. Pass the `game.project` path as the first positional argument to open that project directly. - -The optional `--port` or `-p` argument selects the editor HTTP server port. Omitting it lets Defold choose an available port and is usually preferable when several projects may be open. - -For example: - -```sh -# Linux -/path/to/Defold/Defold --port 8181 /absolute/path/to/project/game.project -``` - -```sh -# macOS -/path/to/Defold.app/Contents/MacOS/Defold --port 8181 /absolute/path/to/project/game.project -``` - -```powershell -# Windows -C:\path\to\Defold\Defold.exe --port 8181 C:\absolute\path\to\project\game.project -``` - -The editor is a graphical desktop application, so it must be started in an interactive user session with access to the display. -Use Bob instead when a graphical editor session is unavailable, such as in headless CI. - -After launching the editor, wait until the project has finished opening and `.internal/editor.port` has been created, then poll `http://localhost:$(cat .internal/editor.port)/openapi.json` until it returns the OpenAPI document. This document provides everything the tool needs to discover and use the editor API. - -## Automating a running editor via HTTP server - -When a project is open, the editor starts a local HTTP server. Select Help ▸ Open Editor Server to open its local home page in the default web browser on localhost at the selected port: - -![editor_server](images/automation/editor_server.png) - -The selected port is also written to: - -```text -.internal/editor.port -``` - -The following variables are used in the examples below: - -```sh -PORT="$(cat .internal/editor.port)" -BASE_URL="http://127.0.0.1:$PORT" -``` - -::: important -The editor server is a local control interface for the development environment. Do not expose it through a public address or an untrusted tunnel. -::: - -## Discovering the API through OpenAPI - -The only Defold-specific bootstrap information an external tool should need to work with an open Defold editor is an `openapi.json` file hosted by the editor's local HTTP server: - -```sh -curl -sS "http://localhost:$(cat .internal/editor.port)/openapi.json" -``` - -The returned OpenAPI 3.0.3 document describes the operations supported by the current editor version, including paths, methods, parameters, command names, request formats, responses, status codes, and authentication requirements. - -List the documented paths: - -```sh -curl -sS "$BASE_URL/openapi.json" | - jq -r '.paths | keys[]' -``` - -List the available editor commands: - -```sh -curl -sS "$BASE_URL/openapi.json" | - jq -r ' - .paths["/command/{command}"].post.parameters[] - | select(.name == "command") - | .schema.enum[] - ' -``` - -A version-aware integration should read it to verify that the required operations are available and configure its tools from the returned schemas. - -Project-specific endpoints can also appear in the same document when the editor scripts that define them include an OpenAPI operation description. - -### Built-in operations - -In Defold 1.13.1, the most useful endpoints are: - -| Endpoint | Purpose | -| --------------------------- | -------------------------------------------------------- | -| `GET /openapi.json` | Discover the current editor API | -| `POST /command/{command}` | Execute an editor command | -| `GET /ref` | Search the runtime and editor API documentation (1.13.1+)| -| `GET /console` | Read the current console contents | -| `GET /console/stream` | Continuously follow console output | -| `GET /preview/{path}` | Render a supported scene resource to PNG (1.13.1+) | -| `POST /eval` | Execute authenticated Lua code in the editor environment (1.13.0+) | -| `GET`, `POST /prefs/{path}` | Read and write editor preferences | - -## Automated compiling and running - -Editor commands are invoked through: - -```text -POST /command/{command} -``` - -Compile without running the game: - -```sh -curl -sS \ - -X POST \ - "$BASE_URL/command/compile" | - jq -``` - -Compile and run: - -```sh -curl -sS \ - -X POST \ - "$BASE_URL/command/run" | - jq -``` - -A successful compilation returns: - -```json -{ - "success": true, - "issues": [] -} -``` - -A failed compilation returns HTTP status `422` with a structured list of issues: - -```json -{ - "success": false, - "issues": [ - { - "message": "Example compiler message", - "severity": "error", - "resource": "/main/player.script", - "range": { - "start": { - "line": 12, - "character": 4 - }, - "end": { - "line": 12, - "character": 17 - } - } - } - ] -} -``` - -The available fields depend on the type of error. Use the resource path and source range when available, but also handle issues that contain only a message. - -Commonly used commands include: - -`compile` -: Compile the project without running it. - -`run` -: Compile and run the project. - -`clean-build` -: Clear the build cache and rebuild the project. Use this only when a normal compilation behaves inconsistently or appears to miss changes. - -`build-html5` -: Build the project for HTML5 and open it in a browser. - -`fetch-libraries` -: Download and reload project dependencies. - -`hot-reload` -: Reload modified resources into a running game. - -`reload-extensions` -: Reload editor scripts. - -`debugger-start` -: Start the project with the debugger or attach the debugger to a running project. - -`debugger-stop` -: Stop the debugger and the running project. - -Older examples may use `/command/build`, but you should use the commands exposed by the current OpenAPI document. - -Commands that operate on project resources synchronize changes made outside the editor before execution. This makes the following loop reliable: - -```text -edit file → POST /command/compile → inspect issues -``` - -Possible command responses include: - -| Status | Meaning | -| ------ | ----------------------------------------------------- | -| `200` | The command completed and returned a result | -| `202` | The command was accepted and continues asynchronously | -| `403` | The command is not active in the current editor state | -| `404` | The command is not available | -| `422` | Compilation or validation failed | -| `500` | An internal editor error occurred | - -### HTML5 browser automation - -Automated workflows and agents can also build HTML5 through the editor: - -```sh -curl -sS \ - -X POST \ - "$BASE_URL/command/build-html5" -``` - -The command runs asynchronously and normally returns HTTP `202`. The editor serves the result at: - -```text -http://127.0.0.1:/html5/ -``` - -Wait until the address is available before starting browser tests. - -HTML5 builds can be exercised with external browser automation tools such as Playwright, Puppeteer, or Selenium. These tools can generate keyboard, mouse, and emulated touch events targeting the Defold canvas, which the engine processes through the project’s normal input bindings and `on_input()` callbacks. They can also modify the viewport size. This makes HTML5 useful for automated interaction tests. - -## Discovering documentation - -The `/ref` endpoint searches the API documentation included with the running editor version. It is the preferred source for exact API names and signatures that match the version of Defold being used. - -Search for a function: - -```sh -curl -sS \ - --get \ - --data-urlencode "q=go.animate" \ - "$BASE_URL/ref" | - jq -``` - -Filter by environment and language: - -```sh -curl -sS \ - --get \ - --data-urlencode "environment=runtime" \ - --data-urlencode "language=Lua" \ - --data-urlencode "q=collision message|raycast" \ - "$BASE_URL/ref" | - jq -``` - -Available parameters: - -`environment` -: `editor`, `runtime`, or comma-separated values. - -`language` -: `Lua`, `C`, `C++`, or comma-separated values. - -`q` -: A case-insensitive search expression. Whitespace represents the AND operator, while `|` represents OR. - -Agents should prefer focused queries instead of retrieving the entire API reference in order to save tokens. - -### Documentation as knowledge base for LLMs - -Defold also publishes official documentation in formats suitable for language models and local search tools: - -* the [LLM documentation index](https://defold.com/llms.txt) is a concise index of individual manuals, API namespaces, and examples; -* the [full LLM documentation](https://defold.com/llms-full.txt) combines all manuals, API documentation, and examples into one searchable file. - -Use `llms.txt` to retrieve only the relevant pages in the official documentation needed for the current task. - -Use `llms-full.txt` for offline search, local indexing, or [Retrieval-Augmented Generation (RAG)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation). Again, the complete file should not normally be included in every model request in order to save tokens. - -## Automating reading logs and test results - -The editor HTTP API provides access to console output. Read the current console contents as JSON using the `console` command: - -```sh -curl -sS "$BASE_URL/console" | jq -``` - -The response contains console lines in the `lines` field and semantic regions in the `regions` field, such as errors, evaluation results, and resource references. - -To continuously follow new output, use the console stream: - -```sh -curl -N "$BASE_URL/console/stream" -``` - -The connection remains open until the client closes it, such as after receiving a completion marker or an error, detecting process termination, or reaching a timeout or line limit. - -Defold can also persist the game log by setting `Write Log File` in `game.project`. Read more details about logging in the [Debugging manual](/manuals/debugging-game-and-system-logs/). File logging is particularly useful for packaged applications and tests on target devices where the editor console is unavailable. - -### Logging solutions - -Reading the console is useful only when the project logs custom information in addition to internal errors and warnings. Useful logs can help agents understand the flow of the game, detect issues, and debug more effectively. Some tools, such as Cursor, offer a debug mode that uses print statements to gather additional information, which can work well with Defold projects. - -The project can use `print()` and `pprint()` directly or adopt a community logging library from [assets tagged logging](https://defold.com/assets/?tag=logging) or [assets tagged debugging](https://defold.com/assets/?tag=debugging). - -### Automated test reporting - -Human-readable messages are useful during development and debugging, but automation should use a stable result protocol. One option is a unique prefix followed by a JSON object, e.g.: - -```text -TEST {"run":"8f13","event":"suite_start","tests":2} -TEST {"run":"8f13","event":"case","name":"player_moves","status":"pass","duration_ms":3} -``` - -The collector could then search each console line for the `TEST` marker, ignoring unrelated messages, and decode and parse the JSON after it. - -Every test suite should print an unambiguous final result. A process crash, a timeout, or a disconnected stream is neither a pass nor an ordinary assertion failure and should be reported separately. - -It is good practice to store the complete console output and, when a test fails, include the test name, assertion details, elapsed time, relevant log lines, Defold version, target platform, and paths to generated artifacts. - -### Test frameworks - -Projects may implement their own small runner or use a [community library](https://defold.com/assets/?tag=testing). - -For example, [DefTest](https://defold.com/assets/deftest/) is a Defold unit-testing library based on the Telescope framework. It supports test suites, setup and teardown functions, assertions, test-name filtering, mocks for selected Defold APIs, and optional coverage collection through LuaCov. Tests can run from a dedicated bootstrap collection, including in a headless build created with Bob. - -A framework's normal console output may be sufficient for developers, but agents and CI systems should still receive an explicit final event or another unambiguous machine-readable result. If an existing framework does not provide the required format, add a small adapter around its completion callback or summary output. - -## Rendering scene previews - -Since Defold 1.13.1, a supported scene resource can be rendered to PNG through the `/preview/{path}` endpoint, for example: - -```sh -mkdir -p build/automation - -curl -sS \ - "$BASE_URL/preview/main/main.collection?width=1280&height=720" \ - --output build/automation/main-preview.png -``` - -This command creates a screenshot of the main collection from the open Basic 3D template project: - -![editor-screenshot-main](images/automation/main-preview.png) - -The following command generates a screenshot of the cube model: - -```sh -curl -sS \ - "$BASE_URL/preview/assets/models/cube.model?width=1280&height=720" \ - --output build/automation/cube-preview.png -``` - -![editor-screenshot-cube](images/automation/cube-preview.png) - -Previews can be useful in automation workflows and can help multimodal agents analyze a visual setup automatically, for example, by verifying level and GUI layouts, checking the correctness of shaders and lighting setups, performing visual regression tests, and generating documentation thumbnails. A multimodal model can evaluate semantic conditions that are difficult to express, such as clipped text, overlapping controls, unclear selection states, or content extending outside a safe area. - -The path after `/preview/` does not include a leading slash. The optional dimensions default to the project display size and must be between `1` and `4096`. - -| Status | Meaning | -| ------ | ------------------------------------------------------------- | -| `200` | The preview was rendered | -| `400` | The dimensions are invalid | -| `404` | The resource was not found | -| `422` | The resource is not loaded or does not support scene previews | - -> **Note** -> -> A preview is rendered by the editor. It is not a screenshot of the running game and does not verify scripts, user input, physics, runtime-created objects, post-processing, or platform-specific behavior. - -Use a screenshot of the running game when these elements matter. - -## Executing editor Lua code - -The authenticated `POST /eval` endpoint executes Lua code in the editor extension environment. - -The current session token is stored in `.internal/editor.token`: - -```sh -TOKEN="$(cat .internal/editor.token)" -``` - -The token is reset each session. Using the token, you can run Lua code from an external CLI: - -```sh -curl -sS \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: text/plain" \ - --data-binary 'print(editor.version) return editor.platform' \ - "$BASE_URL/eval" -``` - -Printed output and return values are provided as text: - -```text -1.13.1 -=> x86_64-linux -``` - -| Status | Meaning | -| ------ | --------------------------------------------- | -| `200` | The code was executed | -| `401` | The bearer token is missing or invalid | -| `422` | The Lua code could not be parsed or executed | -| `503` | The editor extension environment is not ready | - -A client may retry after a `503` response, but it should use a bounded number of attempts. Correct the code before repeating a request that returned `422`. - -Lua code running in the editor can use the [Editor API](https://defold.com/ref/editor-lua/). Through this API, code can use the full editor scripting environment and the Bob builder, open URLs in the default browser, run commands, and more. This can be useful for custom development workflows and for creating or modifying resources. - -It cannot use game runtime APIs such as `go.*` to manipulate the running game. Use runtime tests, the console, the debugger, or browser automation to verify gameplay. - -### Modifying resources and files - -Many Defold source resources are stored in text formats, but their schemas are implementation details of the editor. Prefer editor transactions when modifying structured resources. Choose the modification method according to the resource type: - -| Change | Preferred method | -| ------------------------------------------------------------------- | -------------------------------------- | -| Lua, shader, JSON, or another known text format | Direct file modification | -| Unsaved text in an open editor tab | `editor.get()` and `editor.transact()` | -| Collection, game object, GUI, atlas, or another structured resource | Editor transaction | -| Repeatedly generated content | Standalone generator | -| Repeatable project operation | Editor command or custom HTTP endpoint | -| CI-only transformation | Standalone script run before Bob | - -Inspect a resource before changing it: - -```sh -curl -sS \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: text/plain" \ - --data-binary ' - local path = "/game.project" - pprint(editor.properties(path)) - return editor.get(path, "path") - ' \ - "$BASE_URL/eval" -``` - -Check `editor.can_get()`, `editor.can_set()`, and the other `editor.can_*()` functions before performing a transaction. - -Use `editor.execute()` to run a formatter, validator, or generator: - -```lua -local output = editor.execute( - "python3", - "scripts/generate_levels.py", - { - out = "capture" - } -) - -print(output) -``` - -When the command does not modify project resources, set `reload_resources = false` to avoid an unnecessary reload. - -::: important -Do not modify files in `.internal/` or generated content in `build/`. -::: - -## Preferences - -Editor preferences can be read and written through: - -```text -GET /prefs/{path} -POST /prefs/{path} -``` - -For example, the following request prints the currently set font size: - -```sh -curl -sS "$BASE_URL/prefs/code/font/size" | jq -``` - -The following request sets the current font size to 16: - -```sh -curl -sS \ - -X POST \ - -H "Content-Type: application/json" \ - --data '16' \ - "$BASE_URL/prefs/code/font/size" -``` - -The editor validates the value against the preference schema. An invalid path or value returns HTTP `400`. - -Preferences are persistent user or project-user settings, not project configuration (`game.project`) stored in the repository. If an automation changes a preference temporarily, it should save the previous value and restore it after the operation. - -## Custom HTTP endpoints - -Additional endpoints can be defined with the [`get_http_server_routes()`](/manuals/editor-scripts/#http-server) editor script function. - -The optional OpenAPI operation table makes the endpoint available through the same `/openapi.json` entry point as the built-in operations. - -Custom endpoints can be useful for content generation and validation, project reports, localization checks, resource analysis, project-specific testing operations, or simplified tools for IDEs and AI agents. - -A good endpoint should perform one clearly named operation, validate its input, return a structured result, be idempotent where possible, and limit expensive operations. - -Custom endpoints are not automatically protected by the `/eval` token. When an endpoint performs sensitive operations, add project-specific authentication or additional safety measures. - -## Lifecycle hooks - -A project can contain one `hooks.editor_script` file in its root directory. - -Hooks are available before and after builds, before and after bundle creation, and when a game process starts or terminates. Only the root `hooks.editor_script` receives these events, giving the project one place in which to define the order of its steps. - -Lifecycle hooks run only in the editor. Put shared validation and generation logic in standalone scripts and invoke the same scripts from both editor hooks and CI. - -They can respond to editor lifecycle events, for example: - -```lua -local M = {} - -local function validate_project() - print(editor.execute( - "python3", - "scripts/validate_project.py", - { - out = "capture", - reload_resources = false - } - )) -end - -function M.on_build_started(opts) - validate_project() -end - -function M.on_build_finished(opts) - print("Build successful:", opts.success) -end - -return M -``` - -An error raised from `on_build_started()` stops the editor build. - -## Additional best practices for automated testing - -Use several levels of verification. Begin with the narrowest and fastest test capable of detecting the problem, then continue to runtime and platform tests. - -Prefer separate, isolated test collections. Each test should establish a known state, execute one behavior, verify the result, clean up its resources, and print a structured status. - -For more complex games, you can also create separate "development room" collections that contain predefined setups, preferably with gray-boxed blockouts, and allow you to test different mechanics or scenarios. - -### Writing reusable and testable code - -When writing code, keep reusable logic in Lua modules with minimal engine dependencies. This makes it easier to test independently of the game environment. - -Read more in the [Writing Code manual](https://defold.com/manuals/writing-code/). - -### Agentic testing workflow - -AI agents should `POST /command/compile` after each coherent group of source changes to inspect errors or warnings. Frequent, small compilation gates make it easier to identify which change introduced a problem. - -Modifying the `game.project` file allows you to select a separate bootstrap collection for tests: - -```ini -[bootstrap] -main_collection = /test/test.collectionc -``` - -After successfully running automated tests or agentic verification, it is good practice to restore the previous bootstrap collection setting. - -## Headless automation and continuous integration - -Continuous integration (CI) should use the Bob build tool. - -A basic CI process can resolve dependencies, build an archive, and generate a JSON report: - -```sh -mkdir -p build/reports - -java -jar bob.jar \ - --root . \ - --archive \ - --build-report-json build/reports/build-report.json \ - resolve build -``` - -Alternatively, build a headless test bundle with test settings: - -```sh -java -jar bob.jar \ - --root . \ - --settings test/test.settings \ - --platform x86_64-linux \ - --variant headless \ - --archive \ - --bundle-output build/test-bundle \ - resolve build bundle -``` - -Run the resulting executable with a platform-appropriate process runner and capture its exit code and logs. - -The [Bob manual](/manuals/bob) describes supported platforms, settings files, bundles, caches, native extensions, and build reports. - -An AI agent can help diagnose or repair a failed stage, but the stage itself should remain deterministic. - -## AI agents and integration layers - -Defold interfaces are model-neutral. They can be used by Claude Code, Codex, Cursor, Grok-based tools, DeepSeek, and other open-source models, as well as any custom agent environment that can: - -* read and write project files; -* execute local commands; -* send HTTP requests to `localhost`; -* parse JSON; -* inspect images when needed. - -A model available only through a chat interface can suggest code, but it cannot independently inspect the running editor or verify the result. - -### Automation integration layer - -An integration layer, sometimes referred to as an automation bridge, connects Defold to an external tool. - -The integration layer can be: - -* a shell script; -* a command-line program; -* an IDE extension; -* a client generated from OpenAPI; -* a test controller; -* an MCP server. - -The integration layer should expose controlled operations and keep authentication data local. Deterministic tools should provide verification evidence. - -When working with the editor, it should discover operations through `openapi.json`. It should not maintain a separate, permanently hard-coded copy of the editor API. - -### Model Context Protocol - -[Model Context Protocol](https://modelcontextprotocol.io/) is one possible communication protocol between an AI agent and an integration layer. An MCP server can expose Defold operations as tools and project documentation as resources. - -As of now, Defold does not provide an official MCP server. Official integration is based on the editor OpenAPI document, Bob, editor scripts, and project-defined tools. - -Keeping MCP separate from the editor core provides several advantages: - -* the editor remains independent of a specific model provider or agent protocol; -* the same interface supports automation unrelated to artificial intelligence; -* clients can use OpenAPI directly; -* an MCP adapter can expose only the operations appropriate for its environment; -* permission and confirmation policies remain under the control of the application hosting the agent. - -It might be practical to separate tools by privilege level: - -| Level | Examples | -| ------------ | ----------------------------------------------------- | -| Read-only | Project inspection, OpenAPI, `/ref`, console, preview | -| Verification | Compilation, tests, HTML5 builds, image comparisons | -| Modification | File changes, resource transactions | -| Privileged | `/eval`, external commands, dependency changes | - - -::: important -Do not give every model unrestricted shell and `/eval` access. -::: - -Community-created MCP projects include: - -* the [Fulviuus Defold MCP project](https://github.com/Fulviuus/defold-mcp); -* the [ChadAragorn Defold MCP project](https://github.com/ChadAragorn/defold-mcp); -* an [AIbase directory entry](https://mcp.aibase.com/server/1917146819408359426) for the ChadAragorn project. - -These projects are not developed, audited, maintained, or officially supported by the Defold Foundation. Before installing any community solution, inspect its current source code, dependencies, permissions, network behavior, tests, and compatibility with the current Defold version. - -### Project instructions and AGENTS.md - -Store project-specific automation rules in version control. A concise, canonical file, such as `AGENTS.md`, can be used across different tools' configurations. There are many resources on writing effective agent instructions; among their most important recommendations are keeping the instructions concise and maintainable. - -Agents should preferably follow the same automation loop as any other automated integration. - -Agents can also use certain `skills`, which are text files that explain to models how to perform particular actions or follow specific workflows. - -One good example of agent instructions and a set of custom skills suited to Defold can be found [here](https://forum.defold.com/t/agent-config-collection-of-agents-md-and-skills/82387). - -## Security - -Automation is part of the project's security model. - -* Connect to the editor server through `127.0.0.1` and do not expose its port publicly. -* Treat the entire editor HTTP server as a trusted local control interface. -* Protect `.internal/editor.token`; it grants access to `/eval`. -* Allow the local integration layer to use the token without placing it in model prompts or reports. -* Remember that custom endpoints are not authenticated automatically. -* Do not provide a general AI agent with signing keys, deployment tokens, store credentials, or production secrets. -* Run broad autonomous changes in a separate branch, worktree, temporary copy, container, or restricted account. -* Require approval before deleting resources, adding dependencies, changing native extensions, modifying release settings, publishing bundles, or accessing external services. -* Treat issue content, imported files, source comments, and generated data as untrusted input. -* Verify that project policy allows code, assets, logs, or screenshots to be sent to a hosted model. - -Before using a third-party integration layer or MCP server, inspect what it can read, write, execute, download, and expose over the network. diff --git a/docs/en/manuals/automation.md b/docs/en/manuals/automation.md new file mode 100644 index 00000000..6a50e093 --- /dev/null +++ b/docs/en/manuals/automation.md @@ -0,0 +1,88 @@ +--- +title: Automation in Defold +brief: This manual introduces Defold's automation interfaces and explains how to choose between editor, runtime, command-line, testing, and agent-driven workflows. +--- + +# Automation in Defold + +This manual provides the overall mental model and links to the focused manuals for each interface. + +Defold supports automation at several levels: + +* [editor scripts](/manuals/editor-scripts) - allow you to customize editor workflows, add specific tools, and speed up the creation of levels, assets, etc. +* [editor UI scripts](/manuals/editor-scripts-ui/) - allow you to create custom visual tools, popups, configurators, etc. +* [editor HTTP API](/manuals/editor-http-api) - allows you to control an open project via OpenAPI operations. +* [Bob CLI](/manuals/bob) - can build a project and create data archives or standalone bundles from the command line. +* [engine HTTP service](/manuals/engine-service) - lets external tools query and send commands to a running debug build +* [Automation Bridge](https://github.com/defold/extension-automation-bridge) - official Defold extension provides additional runtime automation endpoints +* shell scripts can generate, validate, and perform ordinary file operations. +* external platform or web browser automation tools + +The most important distinction is between the Defold editor and a running game. They are separate processes with separate HTTP servers: + +| Layer | Process | Purpose | +| --- | --- | --- | +| Editor HTTP API | Defold editor | Project resources, builds, editor commands, previews, preferences, console output, and editor scripts | +| Engine service | Running Defold game engine (`dmengine`) | Development services, profiling, runtime messages, and extension-defined runtime automation APIs | + +Use the [editor HTTP API](/manuals/editor-http-api) to control the open project. Use the [engine service](/manuals/engine-service) or a runtime automation extension when you must observe or control the running game. + +## Choosing an automation interface + +Choosing an interface appropriate to the task is one of the most important aspects of effective automation. The table below can help you choose the simplest interface for a given action: + +| Interface | Suitable for | +| --- | --- | +| Shell script or task runner | Generation, formatting, validation, and repeatable local tasks | +| Bob | Editor-independent builds, bundles, reports, and CI | +| Editor script | Custom commands, resource tools, user interfaces, and editor integrations | +| Lifecycle hook | Validation or generation before and after editor builds or bundling | +| Editor HTTP API | External tools, IDE integrations, and test controllers for an open project | +| In-game test collection | Game logic, messages, components, input, physics, and engine behavior | +| Runtime automation API | Scene inspection, injected input, screenshots, and live application state | +| Browser automation | HTML5 interaction tests, screenshots, and web integrations | +| AI coding agent | Tasks where the relevant files and operations are not known in advance | +| Multimodal model | Semantic analysis of scenes, GUI layouts, and runtime screenshots | + +For example: + +* Need to automatically inspect visually a collection (e.g. level layout), a model (e.g. shaders correctness) or a GUI interface without running the game? Use an [editor preview](/manuals/editor-http-api/#rendering-scene-previews). +* Need to verify dynamically spawned game objects, physics, or runtime scripts? Use a [running test collection or runtime automation API](/manuals/automated-testing/#tests-in-a-running-collection). +* Need to build without a graphical editor e.g. during CI automated tests? Use [Bob](/manuals/bob). + +## Deterministic automation or AI agents + +Prefer a deterministic solution when the sequence of operations is already known, like e.g. in a level validator, formatter, build job, or regression test. These should normally have stable inputs, outputs, timeouts, and exit codes. It is good for automated hooks and tests, that can be reliably run on CI. A deterministic solution for procedural resource creation for your projects is also prefered, e.g. a tool to convert gltf objects to models with a given material, populate a level with e.g. trees, etc. These procedures can be easily created for every project with Editor Scripts and UI. Read more about them in [the manual](/manuals/editor-scripts-ui). + +An agent can be useful when a task requires investigation or multimodal (e.g. including visual) analysis: locating relevant resources, selecting an implementation, modifying several files, interpreting errors, and iterating toward defined acceptance criteria. The agent should though still call deterministic interfaces and consume the same evidence as a local script or CI runner. See the manual on [using AI coding agents with Defold](/manuals/ai-agents). + +## The automation loop + +A reliable automation process forms a closed loop: + +1. Inspect - read project files, the current interface description, and relevant documentation. +2. Change - use editor transactions, editor scripts, or file and shell tools. +3. Verify - build, run focused tests, and gather logs, reports, state, or images. +4. Evaluate - compare the evidence with acceptance criteria, then finish or retry. + +![The inspect, change, verify, and evaluate automation loop](images/automation/automation_loop.png) + +Verification should provide evidence from the actual environment. Suitable evidence includes: + +* a successful build result; +* an explicitly completed test suite; +* expected state from the running game; +* a generated bundle or build report; +* a deterministic image comparison; +* a screenshot that satisfies defined visual criteria. + +Define the expected result before making changes. Also define a timeout and a maximum number of repair attempts. An unattended process should not continue indefinitely when it cannot satisfy the acceptance criteria. + +## Next steps + +Find more details on specific topics regarding automation workflows in the given manuals: + +* [Automating the Defold editor tasks with HTTP API](/manuals/editor-http-api) +* [The engine service and runtime HTTP API](/manuals/engine-service) +* [Automated testing and verification](/manuals/automated-testing) +* [Using AI coding agents with Defold](/manuals/ai-agents) diff --git a/docs/en/manuals/editor-http-api.md b/docs/en/manuals/editor-http-api.md new file mode 100644 index 00000000..fdf6ef4f --- /dev/null +++ b/docs/en/manuals/editor-http-api.md @@ -0,0 +1,478 @@ +--- +title: Automating the Defold editor with HTTP +brief: This manual explains how external tools can discover and use the local HTTP API of an open Defold editor project. +--- + +# Automating the Defold editor with HTTP + +The editor HTTP API controls an open project in the Defold editor. Use it for editor commands, builds, project resources, previews, preferences, console output, documentation search, and editor-script integrations. To inspect or control the running game instead, use the [engine service or a runtime automation API](/manuals/engine-service). + +::: important +The editor HTTP API is experimental and may change between Defold versions. The `/openapi.json` document generated by the running editor is the source of truth for its available operations and schemas. +::: + +## Starting the editor from an external tool + +An external tool needs the editor executable and the absolute path to the project's `game.project` file. + +Installed Defold versions can be located through `installations.json`, as described in the [Editor manual](/manuals/editor/#editor-installation-metadata). Its `launcherPath` field contains the executable to start. Pass the `game.project` path as the first positional argument to open that project directly. + +The optional `--port` or `-p` argument selects the editor server port. Omitting it lets Defold choose an available port and is usually preferable when several projects may be open. + +```sh +# Linux +/path/to/Defold/Defold --port 8181 /absolute/path/to/project/game.project +``` + +```sh +# macOS +/path/to/Defold.app/Contents/MacOS/Defold --port 8181 /absolute/path/to/project/game.project +``` + +```powershell +# Windows +C:\path\to\Defold\Defold.exe --port 8181 C:\absolute\path\to\project\game.project +``` + +The editor is a graphical desktop application. Start it in an interactive user session with access to the display. Use [Bob](/manuals/bob) when a graphical session is unavailable, such as in headless CI. + +After starting the editor, wait until the project has opened and `.internal/editor.port` exists. Then poll `/openapi.json` until it returns a valid document. Do not assume that creating the process means the project is ready. + +## Locating the editor server + +The editor starts a local HTTP server while a project is open. Select Help ▸ Open Editor Server to open its home page in the default browser: + +![The local editor server home page](images/automation/editor_server.png) + +The selected port is written inside the project to: + +```text +.internal/editor.port +``` + +The examples in this manual use these shell variables: + +```sh +PORT="$(cat .internal/editor.port)" +BASE_URL="http://127.0.0.1:$PORT" +``` + +The port file belongs to the current editor session. Read it again after restarting the editor. + +::: important +The editor server is a trusted local control interface. Connect through `127.0.0.1` and do not expose it through a public address, port forward, or untrusted tunnel. +::: + +## Discovering operations through OpenAPI + +The only Defold-specific bootstrap information an external tool should need is the editor port and the OpenAPI document: + +```sh +curl -sS "http://127.0.0.1:$(cat .internal/editor.port)/openapi.json" +``` + +The returned OpenAPI 3.0.3 document describes the operations supported by the running editor version, including paths, methods, parameters, command names, request formats, responses, status codes, and authentication requirements. + +List the documented paths: + +```sh +curl -sS "$BASE_URL/openapi.json" | + jq -r '.paths | keys[]' +``` + +List the available editor commands: + +```sh +curl -sS "$BASE_URL/openapi.json" | + jq -r ' + .paths["/command/{command}"].post.parameters[] + | select(.name == "command") + | .schema.enum[] + ' +``` + +A version-aware integration should verify each required operation and configure requests from the returned schema. Do not maintain a supposedly exhaustive copy of endpoint or command names. + +Project-defined routes also appear in `/openapi.json` when their editor scripts provide an OpenAPI operation description. + +## Executing editor commands + +Editor commands are invoked through: + +```text +POST /command/{command} +``` + +For example, the current `build` command compiles and runs the project: + +```sh +curl -sS \ + -X POST \ + "$BASE_URL/command/build" | + jq +``` + +A successful build returns a structured result: + +```json +{ + "success": true, + "issues": [] +} +``` + +A failed build returns HTTP status `422` with issues such as: + +```json +{ + "success": false, + "issues": [ + { + "message": "Example compiler message", + "severity": "error", + "resource": "/main/player.script", + "range": { + "start": { + "line": 12, + "character": 4 + }, + "end": { + "line": 12, + "character": 17 + } + } + } + ] +} +``` + +The available fields depend on the error. Use the resource path and source range when present, but also handle issues that contain only a message. + +Commonly useful commands, when listed by the running editor, include: + +`build` +: Compile and run the project. + +`clean-build` +: Clear the build cache, then compile and run. Use this only when an ordinary build behaves inconsistently or appears to miss changes. + +`build-html5` +: Build the project for HTML5 and make the output available through the editor server. + +`fetch-libraries` +: Download and reload project dependencies. + +`hot-reload` +: Reload modified resources into a running game. + +`reload-extensions` +: Reload editor scripts. + +`debugger-start`, `debugger-stop`, and the debugger step commands +: Control a debug session and the running project. + +This is not an exhaustive command reference. Exact names and availability depend on the editor version and current editor state; discover them from `/openapi.json`. + +Commands that operate on project resources synchronize external file changes before execution. This supports a reliable loop: + +```text +edit file --> POST /command/build --> inspect issues and runtime output +``` + +For compile-only automation, standalone bundles, or headless CI, use [Bob](/manuals/bob). + +### Command responses and asynchronous work + +The command operation documents response codes in the current OpenAPI schema. Typical meanings are: + +| Status | Meaning | +| --- | --- | +| `200` | The command completed and returned a result | +| `202` | The command was accepted and continues asynchronously | +| `403` | The command is not active in the current editor state | +| `404` | The command is not available | +| `422` | Build or validation failed | +| `500` | An internal editor error occurred | + +An HTTP `202` response is not proof that the requested result exists. Wait for the relevant output, resource, console marker, or served URL and enforce a timeout. + +### Building HTML5 + +If the current OpenAPI document lists `build-html5`, invoke it through the command operation: + +```sh +curl -sS \ + -X POST \ + "$BASE_URL/command/build-html5" +``` + +The command runs asynchronously and normally returns HTTP `202`. After the build completes, the editor serves it at: + +```text +http://127.0.0.1:/html5/ +``` + +Wait until the URL is available before starting browser tests. See [Browser tests for HTML5](/manuals/automated-testing/#browser-tests-for-html5). + +## Searching API documentation + +When present in `/openapi.json`, the `/ref` operation searches API documentation included with the running editor version. It provides names and signatures that match that version. + +Search for a function: + +```sh +curl -sS \ + --get \ + --data-urlencode "q=go.animate" \ + "$BASE_URL/ref" | + jq +``` + +Filter by environment and language: + +```sh +curl -sS \ + --get \ + --data-urlencode "environment=runtime" \ + --data-urlencode "language=Lua" \ + --data-urlencode "q=collision message|raycast" \ + "$BASE_URL/ref" | + jq +``` + +The search parameters are: + +`environment` +: `editor`, `runtime`, or comma-separated values. + +`language` +: `Lua`, `C`, `C++`, or comma-separated values. + +`q` +: A case-insensitive expression. Whitespace represents AND, while `|` represents OR. + +Prefer focused searches instead of retrieving an entire reference when only one API or message is needed. + +## Reading console output + +Read the editor console as JSON: + +```sh +curl -sS "$BASE_URL/console" | jq +``` + +The response contains console text in `lines` and semantic regions in `regions`, including errors, evaluation results, and resource references. + +Follow console output continuously: + +```sh +curl -N "$BASE_URL/console/stream" +``` + +The stream includes existing console lines and then remains open for new output. Close it after receiving a completion marker or error, detecting process termination, or reaching a timeout or line limit. + +For test-result framing and failure classification, see [Automated testing and verification](/manuals/automated-testing/#structured-test-results). + +## Rendering scene previews + +When `/preview/{path}` is available, the editor can render a supported scene resource to PNG: + +```sh +mkdir -p build/automation + +curl -sS \ + "$BASE_URL/preview/main/main.collection?width=1280&height=720" \ + --output build/automation/main-preview.png +``` + +This renders the main collection from the open Basic 3D template project: + +![An editor-rendered preview of the main collection](images/automation/main-preview.png) + +Render its cube model in the same way: + +```sh +curl -sS \ + "$BASE_URL/preview/assets/models/cube.model?width=1280&height=720" \ + --output build/automation/cube-preview.png +``` + +![An editor-rendered preview of the cube model](images/automation/cube-preview.png) + +The path after `/preview/` does not include a leading slash. The optional dimensions default to the project display size and must be between `1` and `4096`. + +| Status | Meaning | +| --- | --- | +| `200` | The preview was rendered | +| `400` | The dimensions are invalid | +| `404` | The resource was not found | +| `422` | The resource is not loaded or does not support scene previews | + +Previews are useful for checking static level and GUI layouts, shader and lighting setup, visual regressions, and documentation thumbnails. + +::: important +An editor preview is not a screenshot of the running game. It does not verify scripts, input, physics, dynamically created objects, runtime post-processing, or platform-specific rendering. Use a [runtime screenshot](/manuals/automated-testing/#editor-previews-and-runtime-screenshots) when those elements matter. +::: + +## Executing editor Lua + +The authenticated `POST /eval` operation executes Lua in the editor extension environment. The per-session bearer token is stored in: + +```text +.internal/editor.token +``` + +Read the token and execute code: + +```sh +TOKEN="$(cat .internal/editor.token)" + +curl -sS \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: text/plain" \ + --data-binary 'print(editor.version) return editor.platform' \ + "$BASE_URL/eval" +``` + +Printed output and return values are returned as text. Typical responses are: + +| Status | Meaning | +| --- | --- | +| `200` | The code was executed | +| `401` | The bearer token is missing or invalid | +| `422` | The Lua code could not be parsed or executed | +| `503` | The editor extension environment is not ready | + +A client may retry after `503`, but it should use a bounded number of attempts. Correct the code before repeating a request that returned `422`. + +Evaluated code can use the [Editor API](https://defold.com/ref/editor-lua/) and the editor scripting environment. It cannot use game runtime APIs such as `go.*` to manipulate a running game. Use a runtime test, debugger, browser test, or [runtime automation API](/manuals/engine-service/#automation-bridge-extension) for gameplay. + +### Modifying resources and files + +Many Defold source resources use text formats, but their schemas are implementation details of the editor. Prefer editor transactions for structured resources: + +| Change | Preferred method | +| --- | --- | +| Lua, shader, JSON, or another known text format | Direct file modification | +| Unsaved text in an open editor tab | `editor.get()` and `editor.transact()` | +| Collection, game object, GUI, atlas, or another structured resource | Editor transaction | +| Repeatedly generated content | Standalone generator | +| Repeatable project operation | Editor command or custom HTTP endpoint | +| CI-only transformation | Standalone script run before Bob | + +Inspect a resource before changing it: + +```sh +curl -sS \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: text/plain" \ + --data-binary ' + local path = "/game.project" + pprint(editor.properties(path)) + return editor.get(path, "path") + ' \ + "$BASE_URL/eval" +``` + +Check `editor.can_get()`, `editor.can_set()`, and the other `editor.can_*()` functions before performing a transaction. + +Use `editor.execute()` in editor Lua to run a formatter, validator, or generator: + +```lua +local output = editor.execute( + "python3", + "scripts/generate_levels.py", + { + out = "capture" + } +) + +print(output) +``` + +When the command does not modify project resources, set `reload_resources = false` to avoid an unnecessary reload. + +::: important +Do not modify files in `.internal/` or generated content in `build/`. +::: + +## Preferences + +Editor preferences can be read and written through the path documented in OpenAPI, currently `/prefs/{path}`. + +Read the configured code font size: + +```sh +curl -sS "$BASE_URL/prefs/code/font/size" | jq +``` + +Set it to 16: + +```sh +curl -sS \ + -X POST \ + -H "Content-Type: application/json" \ + --data '16' \ + "$BASE_URL/prefs/code/font/size" +``` + +The editor validates the value against its preference schema. An invalid path or value returns HTTP `400`. + +Preferences are persistent user or project-user settings, not project configuration stored in `game.project`. If automation changes a preference temporarily, save the previous value and restore it afterward. + +## Project-defined routes + +Editor scripts can define additional routes with [`get_http_server_routes()`](/manuals/editor-scripts/#http-server). An optional OpenAPI operation table exposes a route through the same `/openapi.json` document as built-in operations. + +Project-defined routes can provide content generation, validation, reports, localization checks, resource analysis, project-specific tests, or a smaller interface for an IDE or external controller. + +A good route should perform one clearly named operation, validate its input, return a structured result, be idempotent where possible, and limit expensive work. + +Project-defined routes are not automatically protected by the `/eval` token. Add project-specific authentication and safety checks when a route performs sensitive operations. + +## Lifecycle hooks + +A project can contain one `hooks.editor_script` file in its root. Hooks run before and after builds, before and after bundle creation, and when a game process starts or terminates. Only the root hook file receives these events, giving the project one place to define their order. + +```lua +local M = {} + +local function validate_project() + print(editor.execute( + "python3", + "scripts/validate_project.py", + { + out = "capture", + reload_resources = false + } + )) +end + +function M.on_build_started(opts) + validate_project() +end + +function M.on_build_finished(opts) + print("Build successful:", opts.success) +end + +return M +``` + +An error raised from `on_build_started()` stops the editor build. Lifecycle hooks run only in the editor; put shared validation and generation logic in standalone scripts that can also be invoked from CI. + +## Security and compatibility + +Treat the entire editor server as a trusted local interface: + +* Do not expose the port access publicly. +* Protect `.internal/editor.token`; it authorizes `/eval` for the current session. +* Do not give every model unrestricted `/eval` access. +* Keep the token in the local integration layer rather than prompts, reports, or logs. +* Remember that project-defined routes do not inherit `/eval` authentication. +* Read up-to-date `/openapi.json` after editor restart, before relying on an operation. +* Use bounded waits for asynchronous commands and for editor startup. + +## Engine Server + +The editor server belongs to the editor process. A running game has a different port and different responsibilities, described in [the engine service and runtime HTTP API manual](/manuals/engine-service). diff --git a/docs/en/manuals/engine-service.md b/docs/en/manuals/engine-service.md new file mode 100644 index 00000000..92aee78a --- /dev/null +++ b/docs/en/manuals/engine-service.md @@ -0,0 +1,160 @@ +--- +title: The engine service and runtime HTTP APIs +brief: This manual explains the development HTTP service in a running Defold debug engine and how runtime extensions such as Automation Bridge use it. +--- + +# The engine service and runtime HTTP APIs + +The engine service is a development HTTP service owned by a running debug engine (`dmengine`). Use it for engine development services, profiling, runtime messages, or extension-defined runtime automation. It is separate from the [editor server](/manuals/editor-http-api), which belongs to the Defold editor and controls the open project. + +## Editor server and engine service + +Building and running a project creates two processes with different responsibilities: + +| Service | Owner | Typical responsibility | +| --- | --- | --- | +| Editor server | Defold editor | Project resources, editor commands, builds, console history, reference search, previews, preferences, and editor scripts | +| Engine service | Running debug engine | Development and profiling infrastructure, runtime messages, engine state, and extension-defined routes | + +The two services use different ports. A tool that connects to the editor port cannot call runtime extension routes there, and a tool that connects to the engine service cannot call editor operations such as `/preview` or `/prefs`. + +## Availability and port discovery + +The engine service is part of development and profiling infrastructure. Debug engine instances create the service; release builds do not provide it. + +When the editor starts a debug engine, it requests a dynamically assigned service port. The engine reports the selected port in its log: + +```text +INFO:ENGINE: Engine service started on port +``` + +The line appears in the editor console when the game was launched from the editor. A simple local controller can parse this line, but a reusable integration should let the editor or its wrapper track the engine instance and registered port. This avoids confusing an old port with a newly started or reused process. + +The engine also advertises development targets through service discovery on supported platforms. That mechanism is primarily used by Defold tooling and should not be replaced with a permanently hard-coded port. + +Use `127.0.0.1` when controlling a local desktop engine: + +```sh +ENGINE_PORT=51337 +ENGINE_URL="http://127.0.0.1:$ENGINE_PORT" +``` + +The number above is only an example. Always use the port selected by the running engine. + +## Built-in endpoints + +The current debug engine registers a small set of core routes. Their conceptual purposes are: + +| Endpoint | Purpose | +| --- | --- | +| `GET /ping` | Check that the engine service responds | +| `GET /info` | Read engine version, platform, build identifier, and log-service information | +| `GET /state` | Read development connection state used by Defold tooling | +| `POST /post//` | Post a Protobuf-encoded Defold message to a named engine socket | + +For example: + +```sh +curl -sS "$ENGINE_URL/ping" +curl -sS "$ENGINE_URL/info" | jq +curl -sS "$ENGINE_URL/state" | jq +``` + +The `/post` route is used by development operations such as hot reload, reboot, resize, and process control. Its body is a binary Protobuf message of the type named in the route; it is not a JSON message API. + +These routes are development infrastructure, and additional profiler and resource-inspection routes exist in the engine implementation. Do not treat every observed route or response field as a permanent public guarantee. The engine service does not currently publish an OpenAPI document. Integrations should limit themselves to documented behavior or to an extension's versioned API. + +## Extension-defined runtime routes + +In debug builds, the native extension SDK can provide access to the engine web server. An extension can register a route prefix on that server and expose operations that depend on runtime data. + +This is useful for development tools because an extension can share the existing engine service instead of opening another HTTP server. The route design, response format, versioning, and capabilities belong to the extension, not to the core engine. + +An extension-defined runtime automation API should: + +* use a distinct, versioned route prefix; +* expose a health operation and supported capabilities; +* return structured errors; +* handle unavailable platform or engine features explicitly; +* keep operations local to development and testing; +* document whether it is omitted from release builds. + +## Automation Bridge extension + +The official Defold [Automation Bridge](https://github.com/defold/extension-automation-bridge) extension is a debug-only native extension built on the engine service. It is not part of the core engine. It registers a versioned runtime automation API under: + +```text +http://127.0.0.1:/automation-bridge/v1 +``` + +Its runtime API provides capabilities such as scene and node inspection, input, screen information, screenshots, recording, lifecycle information, and optional application-defined synchronization. Representative operations include: + +```text +GET /automation-bridge/v1/health +GET /automation-bridge/v1/scene +POST /automation-bridge/v1/input/click +GET /automation-bridge/v1/screenshot +``` + +This is not a complete endpoint reference. Use the extension's [native API documentation](https://github.com/defold/extension-automation-bridge/tree/master/automation_bridge) and [Python helper documentation](https://github.com/defold/extension-automation-bridge/tree/master/automation_bridge/automation-bridge-python) for the version installed in the project. + +Automation Bridge exposes neither its HTTP API nor its Lua module in release builds. Its health response reports API compatibility and supported capabilities. Clients should check that response instead of assuming that every route, graphics feature, input backend, or screenshot implementation is available. + +### Editor and runtime clients + +The Automation Bridge Python helpers illustrate the two-client architecture. `editor.open_project()` returns an editor project client, and `project.build_and_run()` returns a separate engine client: + +```text +Python test or automation script + | + +-- project --> editor HTTP API + | commands, debugger, console, preferences, + | reference, previews, build, and port discovery + | + +-- game --> engine service + | + +-- /automation-bridge/v1 + scene, input, screenshots, + runtime state, and synchronization +``` + +The transition from `project` to `game` makes the process boundary explicit: + +```python +from automation_bridge import editor + +project = editor.open_project(".") +game = project.build_and_run() +``` + +This division is useful even when using another language or client library: editor operations remain on the editor server, while observations and actions against the live game remain on the engine service. + +## Choosing the correct interface + +| Task | Interface | +| --- | --- | +| Compile and run the project from an open editor | Editor HTTP API | +| Modify editor resources | Editor HTTP API or editor script | +| Render an editor preview | Editor HTTP API | +| Read editor build errors | Editor HTTP API | +| Inspect the running scene | Runtime automation API | +| Inject input into the game | Runtime automation API | +| Capture a runtime screenshot or state | Runtime automation API | +| Read live engine development state | Engine service or runtime automation API | +| Build in headless CI | Bob | + +An editor preview can answer questions about a loaded resource without starting the game. Runtime scripts, physics, input, dynamically created objects, and platform rendering require a running engine and should be verified through [automated runtime testing](/manuals/automated-testing). + +## Limitations and security + +The engine service and extension-defined routes are development tools, not application networking or a game backend. + +* Connect locally through `127.0.0.1`; do not publish the service through a router, public interface, or untrusted tunnel. +* Do not assume that engine service routes require authentication. +* Release builds may omit the engine service and debug extensions entirely. +* Runtime routes can vary by extension version, platform, graphics backend, and engine capabilities. +* Use version or capability negotiation for extension-defined APIs. +* Do not claim OpenAPI support unless a particular extension explicitly provides it. +* Use normal, secured application networking for shipped game features. + +If tests need runtime inspection, input, screenshots, or application synchronization, install a purpose-built debug extension and follow its security and compatibility documentation. From 24a789299e9c6b9f634047f2c2dcb76d6dc49162 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Sat, 1 Aug 2026 20:44:09 +0200 Subject: [PATCH 06/13] Fixed spelling issues --- docs/en/manuals/ai-agents.md | 4 ++-- docs/en/manuals/automation.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/manuals/ai-agents.md b/docs/en/manuals/ai-agents.md index db945663..66dd1372 100644 --- a/docs/en/manuals/ai-agents.md +++ b/docs/en/manuals/ai-agents.md @@ -11,7 +11,7 @@ Defold does not depend on a particular model provider or agent protocol. An agen ## When an agent is appropriate -Prefer an ordinary script or test when the sequence of operations is known. Stable generators, formatters, validators, builds, and regression tests should have predictable inputs, outputs, timeouts, and exit codes. +Prefer an ordinary script or test when the sequence of operations is known. Stable generators, formatters, validation tools, builds, and regression tests should have predictable inputs, outputs, timeouts, and exit codes. An agent can be useful when a task requires these activities: @@ -98,7 +98,7 @@ One community example of Defold-oriented instructions and skills is available in ## Documentation discovery -In order for agents to perform well, a good and actual documentation is needed. One can gather actual informations from: +Agents perform best with accurate, current documentation. Gather current information from: * `/openapi.json` describes the current editor HTTP API. * `/ref` searches API documentation included with the running editor when that operation is available. diff --git a/docs/en/manuals/automation.md b/docs/en/manuals/automation.md index 6a50e093..c24fdd50 100644 --- a/docs/en/manuals/automation.md +++ b/docs/en/manuals/automation.md @@ -52,7 +52,7 @@ For example: ## Deterministic automation or AI agents -Prefer a deterministic solution when the sequence of operations is already known, like e.g. in a level validator, formatter, build job, or regression test. These should normally have stable inputs, outputs, timeouts, and exit codes. It is good for automated hooks and tests, that can be reliably run on CI. A deterministic solution for procedural resource creation for your projects is also prefered, e.g. a tool to convert gltf objects to models with a given material, populate a level with e.g. trees, etc. These procedures can be easily created for every project with Editor Scripts and UI. Read more about them in [the manual](/manuals/editor-scripts-ui). +Prefer a deterministic solution when the sequence of operations is already known, like e.g. in a level validator, formatter, build job, or regression test. These should normally have stable inputs, outputs, timeouts, and exit codes. It is good for automated hooks and tests, that can be reliably run on CI. A deterministic solution for procedural resource creation for your projects is also preferred, e.g. a tool to convert gltf objects to models with a given material, populate a level with e.g. trees, etc. These procedures can be easily created for every project with Editor Scripts and UI. Read more about them in [the manual](/manuals/editor-scripts-ui). An agent can be useful when a task requires investigation or multimodal (e.g. including visual) analysis: locating relevant resources, selecting an implementation, modifying several files, interpreting errors, and iterating toward defined acceptance criteria. The agent should though still call deterministic interfaces and consume the same evidence as a local script or CI runner. See the manual on [using AI coding agents with Defold](/manuals/ai-agents). From d0b0246a0132cf577518fb88669f52f131fcc8f5 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Mon, 3 Aug 2026 09:13:06 +0200 Subject: [PATCH 07/13] Condensed and improved automation entry point manual --- docs/en/manuals/automation.md | 57 ++++++++++------------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/docs/en/manuals/automation.md b/docs/en/manuals/automation.md index c24fdd50..75e7fd59 100644 --- a/docs/en/manuals/automation.md +++ b/docs/en/manuals/automation.md @@ -5,50 +5,25 @@ brief: This manual introduces Defold's automation interfaces and explains how to # Automation in Defold -This manual provides the overall mental model and links to the focused manuals for each interface. +This manual provides the overall description and links to the separate manuals for each topic. -Defold supports automation at several levels: +Defold supports automation at several levels. Choosing an interface appropriate to the task is one of the most important aspects of effective automation. The table below can help you choose the simplest interface for a given action: -* [editor scripts](/manuals/editor-scripts) - allow you to customize editor workflows, add specific tools, and speed up the creation of levels, assets, etc. -* [editor UI scripts](/manuals/editor-scripts-ui/) - allow you to create custom visual tools, popups, configurators, etc. -* [editor HTTP API](/manuals/editor-http-api) - allows you to control an open project via OpenAPI operations. -* [Bob CLI](/manuals/bob) - can build a project and create data archives or standalone bundles from the command line. -* [engine HTTP service](/manuals/engine-service) - lets external tools query and send commands to a running debug build -* [Automation Bridge](https://github.com/defold/extension-automation-bridge) - official Defold extension provides additional runtime automation endpoints -* shell scripts can generate, validate, and perform ordinary file operations. -* external platform or web browser automation tools - -The most important distinction is between the Defold editor and a running game. They are separate processes with separate HTTP servers: - -| Layer | Process | Purpose | -| --- | --- | --- | -| Editor HTTP API | Defold editor | Project resources, builds, editor commands, previews, preferences, console output, and editor scripts | -| Engine service | Running Defold game engine (`dmengine`) | Development services, profiling, runtime messages, and extension-defined runtime automation APIs | - -Use the [editor HTTP API](/manuals/editor-http-api) to control the open project. Use the [engine service](/manuals/engine-service) or a runtime automation extension when you must observe or control the running game. - -## Choosing an automation interface - -Choosing an interface appropriate to the task is one of the most important aspects of effective automation. The table below can help you choose the simplest interface for a given action: - -| Interface | Suitable for | +| Layer | Purpose | | --- | --- | -| Shell script or task runner | Generation, formatting, validation, and repeatable local tasks | -| Bob | Editor-independent builds, bundles, reports, and CI | -| Editor script | Custom commands, resource tools, user interfaces, and editor integrations | -| Lifecycle hook | Validation or generation before and after editor builds or bundling | -| Editor HTTP API | External tools, IDE integrations, and test controllers for an open project | -| In-game test collection | Game logic, messages, components, input, physics, and engine behavior | -| Runtime automation API | Scene inspection, injected input, screenshots, and live application state | -| Browser automation | HTML5 interaction tests, screenshots, and web integrations | -| AI coding agent | Tasks where the relevant files and operations are not known in advance | -| Multimodal model | Semantic analysis of scenes, GUI layouts, and runtime screenshots | - -For example: - -* Need to automatically inspect visually a collection (e.g. level layout), a model (e.g. shaders correctness) or a GUI interface without running the game? Use an [editor preview](/manuals/editor-http-api/#rendering-scene-previews). -* Need to verify dynamically spawned game objects, physics, or runtime scripts? Use a [running test collection or runtime automation API](/manuals/automated-testing/#tests-in-a-running-collection). -* Need to build without a graphical editor e.g. during CI automated tests? Use [Bob](/manuals/bob). +| [Editor Scripts](/manuals/editor-scripts) | Custom commands and Editor workflows or integrations to speed up testing and development, e.g. creation of levels, assets | +| [Editor UI scripts](/manuals/editor-scripts-ui/) | Custom visual tools, popups, configurators, or user interfaces utilizing Editor Scripts | +| [Editor HTTP API](/manuals/editor-http-api) | Control the open game project in the Defold Editor via OpenAPI operations, project resources, builds, editor commands, previews, preferences, console output, or editor scripts for custom operations, external tools, IDE integrations, and test controllers | +| [Bob CLI](/manuals/bob) | Building a project, creating data archives or standalone bundles from the command line, reports, CI | +| [Lifecycle hooks](/manuals/editor-http-api#lifecycle-hooks) | Validation or generation before and after editor builds or bundling | +| [Engine HTTP service](/manuals/engine-service) | Running Defold game engine (`dmengine`) inspection, development services, profiling, runtime messages, or extension-defined runtime automation APIs, external tools querying, sending commands to a running debug build | +| [Automation Bridge](https://github.com/defold/extension-automation-bridge) | official Defold extension that provides additional engine runtime automation endpoints | +| [Automated tests](/manuals/automated-tests) | Testing game logic, messages, components, input, physics, and engine behavior, scene inspection, visual feedback e.g. via [editor preview](/manuals/editor-http-api/#rendering-scene-previews), injected input, live application state, [running test collections](/manuals/automated-testing/#tests-in-a-running-collection) | +| Shell scripts or task runners | Generation, formatting, validation, and repeatable tasks, ordinary file operations | +| External platform-specific and web browser automation tools | Desktop testing tools, HTML5 interaction tests, screenshots, web integrations | +| AI coding agents and multimodal models | Tasks where a deterministic approach is difficult or impossible to implement, semantic analysis of scenes, GUI layouts, or runtime screenshots | + +The most important distinction is between the Defold editor and a running game. They are separate processes with separate HTTP servers. ## Deterministic automation or AI agents From a4d4e54f57e24a020f29b35ba9f71bb42ef58311 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Mon, 3 Aug 2026 13:55:41 +0200 Subject: [PATCH 08/13] Improved editor http api manual --- docs/en/manuals/editor-http-api.md | 62 ++++++++++++++---------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/docs/en/manuals/editor-http-api.md b/docs/en/manuals/editor-http-api.md index fdf6ef4f..ddd922b9 100644 --- a/docs/en/manuals/editor-http-api.md +++ b/docs/en/manuals/editor-http-api.md @@ -3,12 +3,12 @@ title: Automating the Defold editor with HTTP brief: This manual explains how external tools can discover and use the local HTTP API of an open Defold editor project. --- -# Automating the Defold editor with HTTP +# Automating the Defold editor -The editor HTTP API controls an open project in the Defold editor. Use it for editor commands, builds, project resources, previews, preferences, console output, documentation search, and editor-script integrations. To inspect or control the running game instead, use the [engine service or a runtime automation API](/manuals/engine-service). +The Defold Editor opens up a special server for automated actions. HTTP API controls the opened project. Use it for editor commands, builds, project resources, previews, preferences, console output, documentation search, or editor-script integrations. To inspect or control the running game instead, use the [engine service or a runtime automation API](/manuals/engine-service). ::: important -The editor HTTP API is experimental and may change between Defold versions. The `/openapi.json` document generated by the running editor is the source of truth for its available operations and schemas. +The editor HTTP API is experimental and may change between Defold versions. The `/openapi.json` document generated by the running editor is the source of truth for its available operations and schemes. ::: ## Starting the editor from an external tool @@ -34,7 +34,7 @@ The optional `--port` or `-p` argument selects the editor server port. Omitting C:\path\to\Defold\Defold.exe --port 8181 C:\absolute\path\to\project\game.project ``` -The editor is a graphical desktop application. Start it in an interactive user session with access to the display. Use [Bob](/manuals/bob) when a graphical session is unavailable, such as in headless CI. +The editor is a graphical desktop application. Start it in an interactive user session with access to the display. Use [Bob](/manuals/bob) when a graphical session is unavailable, such as in headless CI, or for compile-only automation and creating standalone bundles. After starting the editor, wait until the project has opened and `.internal/editor.port` exists. Then poll `/openapi.json` until it returns a valid document. Do not assume that creating the process means the project is ready. @@ -50,7 +50,7 @@ The selected port is written inside the project to: .internal/editor.port ``` -The examples in this manual use these shell variables: +The examples and commands in this manual will from now on refer to these shell variables: ```sh PORT="$(cat .internal/editor.port)" @@ -60,7 +60,7 @@ BASE_URL="http://127.0.0.1:$PORT" The port file belongs to the current editor session. Read it again after restarting the editor. ::: important -The editor server is a trusted local control interface. Connect through `127.0.0.1` and do not expose it through a public address, port forward, or untrusted tunnel. +The editor server is a trusted local control interface. Do not expose it through a public address, port forward, or untrusted tunnel. ::: ## Discovering operations through OpenAPI @@ -91,7 +91,7 @@ curl -sS "$BASE_URL/openapi.json" | ' ``` -A version-aware integration should verify each required operation and configure requests from the returned schema. Do not maintain a supposedly exhaustive copy of endpoint or command names. +A version-aware integration should verify each required operation and configure requests from the returned schema. We advise against maintaining a supposedly exhaustive copy of endpoint or command names, as this can get outdated. Project-defined routes also appear in `/openapi.json` when their editor scripts provide an OpenAPI operation description. @@ -171,19 +171,13 @@ Commonly useful commands, when listed by the running editor, include: `debugger-start`, `debugger-stop`, and the debugger step commands : Control a debug session and the running project. -This is not an exhaustive command reference. Exact names and availability depend on the editor version and current editor state; discover them from `/openapi.json`. +Exact names and availability depend on the editor version and current editor state; discover them from `/openapi.json`. -Commands that operate on project resources synchronize external file changes before execution. This supports a reliable loop: - -```text -edit file --> POST /command/build --> inspect issues and runtime output -``` - -For compile-only automation, standalone bundles, or headless CI, use [Bob](/manuals/bob). +Commands that operate on project resources synchronize external file changes before execution. ### Command responses and asynchronous work -The command operation documents response codes in the current OpenAPI schema. Typical meanings are: +The command operation documents response codes in the current OpenAPI schema. | Status | Meaning | | --- | --- | @@ -212,13 +206,13 @@ The command runs asynchronously and normally returns HTTP `202`. After the build http://127.0.0.1:/html5/ ``` -Wait until the URL is available before starting browser tests. See [Browser tests for HTML5](/manuals/automated-testing/#browser-tests-for-html5). +Wait until the URL is available before starting browser tests. See [Browser tests for HTML5](/manuals/automated-testing/#browser-tests-for-html5) for more details. ## Searching API documentation When present in `/openapi.json`, the `/ref` operation searches API documentation included with the running editor version. It provides names and signatures that match that version. -Search for a function: +For example, to search for a function, use: ```sh curl -sS \ @@ -251,7 +245,9 @@ The search parameters are: `q` : A case-insensitive expression. Whitespace represents AND, while `|` represents OR. -Prefer focused searches instead of retrieving an entire reference when only one API or message is needed. +The are also condensed documentation resources: [LLM documentation index](https://defold.com/llms.txt) links to official manuals, API namespaces, and examples and the [full LLM documentation](https://defold.com/llms-full.txt) lists complete documentation to support offline search and local indexing. + +AI agents should prefer though specified searches instead of retrieving an entire reference when only one API or message is needed, in order to save on tokens and have a better prepared and clean context for a given task. ## Reading console output @@ -263,7 +259,7 @@ curl -sS "$BASE_URL/console" | jq The response contains console text in `lines` and semantic regions in `regions`, including errors, evaluation results, and resource references. -Follow console output continuously: +To follow console output continuously, use: ```sh curl -N "$BASE_URL/console/stream" @@ -275,7 +271,7 @@ For test-result framing and failure classification, see [Automated testing and v ## Rendering scene previews -When `/preview/{path}` is available, the editor can render a supported scene resource to PNG: +The Defold editor (since 1.13.1) can render a supported scene resource "screenshot" to PNG through command `/preview/{path}`: ```sh mkdir -p build/automation @@ -285,11 +281,11 @@ curl -sS \ --output build/automation/main-preview.png ``` -This renders the main collection from the open Basic 3D template project: +This renders the main collection from the open Basic 3D template project in a default initial view: ![An editor-rendered preview of the main collection](images/automation/main-preview.png) -Render its cube model in the same way: +You can use render to get previews of resources that utilise the visual scene editor, for example one can render a model component in the same way, that allows to verify it's look or e.g. shader correctness: ```sh curl -sS \ @@ -308,10 +304,10 @@ The path after `/preview/` does not include a leading slash. The optional dimens | `404` | The resource was not found | | `422` | The resource is not loaded or does not support scene previews | -Previews are useful for checking static level and GUI layouts, shader and lighting setup, visual regressions, and documentation thumbnails. +Previews might be very useful for visual analysis of the project - checking level layouts, GUI layouts, shader and lighting setup, visual regressions, or create documentation thumbnails. ::: important -An editor preview is not a screenshot of the running game. It does not verify scripts, input, physics, dynamically created objects, runtime post-processing, or platform-specific rendering. Use a [runtime screenshot](/manuals/automated-testing/#editor-previews-and-runtime-screenshots) when those elements matter. +An editor preview is not a screenshot of the running game. It does not verify dynamically created objects, runtime post-processing, or platform-specific rendering. Use a [runtime screenshot](/manuals/automated-testing/#editor-previews-and-runtime-screenshots) when those elements are needed. ::: ## Executing editor Lua @@ -349,7 +345,7 @@ Evaluated code can use the [Editor API](https://defold.com/ref/editor-lua/) and ### Modifying resources and files -Many Defold source resources use text formats, but their schemas are implementation details of the editor. Prefer editor transactions for structured resources: +Many Defold source resources use text formats and can be edited via any text editing tool. For modifying Defold project structured resources prefer editor transactions. | Change | Preferred method | | --- | --- | @@ -400,13 +396,13 @@ Do not modify files in `.internal/` or generated content in `build/`. Editor preferences can be read and written through the path documented in OpenAPI, currently `/prefs/{path}`. -Read the configured code font size: +You can for example read the configured code font size: ```sh curl -sS "$BASE_URL/prefs/code/font/size" | jq ``` -Set it to 16: +Or set it to e.g. 16: ```sh curl -sS \ @@ -418,7 +414,7 @@ curl -sS \ The editor validates the value against its preference schema. An invalid path or value returns HTTP `400`. -Preferences are persistent user or project-user settings, not project configuration stored in `game.project`. If automation changes a preference temporarily, save the previous value and restore it afterward. +Preferences are persistent user or project-user settings, not project configuration stored in `game.project`. If automation needs to change a preference temporarily, save the previous value and restore it afterward. ## Project-defined routes @@ -432,7 +428,7 @@ Project-defined routes are not automatically protected by the `/eval` token. Add ## Lifecycle hooks -A project can contain one `hooks.editor_script` file in its root. Hooks run before and after builds, before and after bundle creation, and when a game process starts or terminates. Only the root hook file receives these events, giving the project one place to define their order. +Hooks are functions that can be run before and after builds, before and after bundle creation, and when a game process starts or terminates. A project can contain one `hooks.editor_script` file in its root. Only the root hook file receives these events, giving the project one place to define their order. ```lua local M = {} @@ -467,11 +463,11 @@ Treat the entire editor server as a trusted local interface: * Do not expose the port access publicly. * Protect `.internal/editor.token`; it authorizes `/eval` for the current session. -* Do not give every model unrestricted `/eval` access. +* Do not give outside unrestricted `/eval` access. * Keep the token in the local integration layer rather than prompts, reports, or logs. * Remember that project-defined routes do not inherit `/eval` authentication. -* Read up-to-date `/openapi.json` after editor restart, before relying on an operation. -* Use bounded waits for asynchronous commands and for editor startup. +* Use up-to-date `/openapi.json`. +* Use bounded waits for asynchronous automatic commands and for editor startup. ## Engine Server From 40234c93cffd2cc2fdb8cb49c110fdb1db4b827c Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Mon, 3 Aug 2026 15:07:05 +0200 Subject: [PATCH 09/13] Condensed and improved engine service manual. --- docs/en/manuals/engine-service.md | 109 ++++++------------ .../images/automation/engine-server.png | Bin 0 -> 48645 bytes .../images/automation/engine-service.png | Bin 0 -> 15020 bytes 3 files changed, 37 insertions(+), 72 deletions(-) create mode 100644 docs/en/manuals/images/automation/engine-server.png create mode 100644 docs/en/manuals/images/automation/engine-service.png diff --git a/docs/en/manuals/engine-service.md b/docs/en/manuals/engine-service.md index 92aee78a..78740e16 100644 --- a/docs/en/manuals/engine-service.md +++ b/docs/en/manuals/engine-service.md @@ -1,28 +1,25 @@ --- title: The engine service and runtime HTTP APIs -brief: This manual explains the development HTTP service in a running Defold debug engine and how runtime extensions such as Automation Bridge use it. +brief: This manual explains the development HTTP service in a running Defold debug engine and how runtime extensions or external tools can use it. --- # The engine service and runtime HTTP APIs -The engine service is a development HTTP service owned by a running debug engine (`dmengine`). Use it for engine development services, profiling, runtime messages, or extension-defined runtime automation. It is separate from the [editor server](/manuals/editor-http-api), which belongs to the Defold editor and controls the open project. +Running a project in Debug mode creates a process for a given runtime instance of the engine with your game and a special engine service that can be accessed for development and profiling infrastructure, runtime logic and messages, engine state and extensions. -## Editor server and engine service +The engine service is a development HTTP service owned by a running debug engine (`dmengine`). -Building and running a project creates two processes with different responsibilities: +It is separate from the [editor server](/manuals/editor-http-api), which belongs to the Defold editor and controls the open project. -| Service | Owner | Typical responsibility | -| --- | --- | --- | -| Editor server | Defold editor | Project resources, editor commands, builds, console history, reference search, previews, preferences, and editor scripts | -| Engine service | Running debug engine | Development and profiling infrastructure, runtime messages, engine state, and extension-defined routes | +The two services use different ports. A tool that connects to the editor port cannot call runtime extension routes there, and vice versa - a tool that connects to the engine service cannot call editor operations. -The two services use different ports. A tool that connects to the editor port cannot call runtime extension routes there, and a tool that connects to the engine service cannot call editor operations such as `/preview` or `/prefs`. +The engine service is part of debug, development and profiling infrastructure. Release engine instances do not create the service. ## Availability and port discovery -The engine service is part of development and profiling infrastructure. Debug engine instances create the service; release builds do not provide it. +When the editor starts a debug engine, it requests a dynamically assigned service port. The engine reports the selected port in `Console` (`and its log if run from a CLI): -When the editor starts a debug engine, it requests a dynamically assigned service port. The engine reports the selected port in its log: +![Engine service port information in Defold debug build](images/automation/engine-service.png) ```text INFO:ENGINE: Engine service started on port @@ -32,18 +29,13 @@ The line appears in the editor console when the game was launched from the edito The engine also advertises development targets through service discovery on supported platforms. That mechanism is primarily used by Defold tooling and should not be replaced with a permanently hard-coded port. -Use `127.0.0.1` when controlling a local desktop engine: +Server is accessible on localhost (`127.0.0.1`) at a given port: -```sh -ENGINE_PORT=51337 -ENGINE_URL="http://127.0.0.1:$ENGINE_PORT" -``` - -The number above is only an example. Always use the port selected by the running engine. +![Engine server access](images/automation/engine-server.png) ## Built-in endpoints -The current debug engine registers a small set of core routes. Their conceptual purposes are: +The current debug engine registers a small set of core routes. | Endpoint | Purpose | | --- | --- | @@ -62,18 +54,18 @@ curl -sS "$ENGINE_URL/state" | jq The `/post` route is used by development operations such as hot reload, reboot, resize, and process control. Its body is a binary Protobuf message of the type named in the route; it is not a JSON message API. -These routes are development infrastructure, and additional profiler and resource-inspection routes exist in the engine implementation. Do not treat every observed route or response field as a permanent public guarantee. The engine service does not currently publish an OpenAPI document. Integrations should limit themselves to documented behavior or to an extension's versioned API. +These routes are development infrastructure, and additional profiler and resource-inspection routes exist in the engine implementation. ## Extension-defined runtime routes In debug builds, the native extension SDK can provide access to the engine web server. An extension can register a route prefix on that server and expose operations that depend on runtime data. -This is useful for development tools because an extension can share the existing engine service instead of opening another HTTP server. The route design, response format, versioning, and capabilities belong to the extension, not to the core engine. +This is useful for development tools because an extension can share the existing engine service instead of opening another HTTP server. An extension-defined runtime automation API should: * use a distinct, versioned route prefix; -* expose a health operation and supported capabilities; +* expose supported capabilities; * return structured errors; * handle unavailable platform or engine features explicitly; * keep operations local to development and testing; @@ -81,44 +73,34 @@ An extension-defined runtime automation API should: ## Automation Bridge extension -The official Defold [Automation Bridge](https://github.com/defold/extension-automation-bridge) extension is a debug-only native extension built on the engine service. It is not part of the core engine. It registers a versioned runtime automation API under: +The official Defold [Automation Bridge](https://github.com/defold/extension-automation-bridge) is a debug-only native extension built on the engine service. It registers a versioned runtime automation API under: ```text http://127.0.0.1:/automation-bridge/v1 ``` -Its runtime API provides capabilities such as scene and node inspection, input, screen information, screenshots, recording, lifecycle information, and optional application-defined synchronization. Representative operations include: +Its runtime API provides capabilities such as scene and node inspection, input, screen information, screenshots, recording, lifecycle information, and optional application-defined synchronization. Some operations include: -```text -GET /automation-bridge/v1/health -GET /automation-bridge/v1/scene -POST /automation-bridge/v1/input/click -GET /automation-bridge/v1/screenshot -``` +| Operation | Action | +| --- | --- | +| `GET /automation-bridge/v1/health` | health report, API capabilities and compatibility | +| `POST /automation-bridge/v1/input/click` | for runtime input interactions | +| `GET /automation-bridge/v1/screenshot` | for runtime screenshots | -This is not a complete endpoint reference. Use the extension's [native API documentation](https://github.com/defold/extension-automation-bridge/tree/master/automation_bridge) and [Python helper documentation](https://github.com/defold/extension-automation-bridge/tree/master/automation_bridge/automation-bridge-python) for the version installed in the project. +Use the extension's [native API documentation](https://github.com/defold/extension-automation-bridge/tree/master/automation_bridge) and [Python helper documentation](https://github.com/defold/extension-automation-bridge/tree/master/automation_bridge/automation-bridge-python) for the version installed in the project. -Automation Bridge exposes neither its HTTP API nor its Lua module in release builds. Its health response reports API compatibility and supported capabilities. Clients should check that response instead of assuming that every route, graphics feature, input backend, or screenshot implementation is available. +Automation Bridge exposes neither its HTTP API nor its Lua module in release builds. ### Editor and runtime clients -The Automation Bridge Python helpers illustrate the two-client architecture. `editor.open_project()` returns an editor project client, and `project.build_and_run()` returns a separate engine client: +The Automation Bridge Python helpers illustrate the two-client architecture. Function `editor.open_project()` returns an editor project client, and `project.build_and_run()` returns a separate engine client. -```text -Python test or automation script - | - +-- project --> editor HTTP API - | commands, debugger, console, preferences, - | reference, previews, build, and port discovery - | - +-- game --> engine service - | - +-- /automation-bridge/v1 - scene, input, screenshots, - runtime state, and synchronization -``` +| Client | Purpose | +| --- | --- | +| Project | Editor HTTP API, commands, debugger, console, preferences, reference, previews, build, and port discovery | +| Game - engine service | Scene, input, screenshots, runtime state, and synchronization | -The transition from `project` to `game` makes the process boundary explicit: +The division between `project` and `game` makes the process boundary explicit. Editor operations remain on the editor server, while observations and actions against the live game remain on the engine service. ```python from automation_bridge import editor @@ -127,34 +109,17 @@ project = editor.open_project(".") game = project.build_and_run() ``` -This division is useful even when using another language or client library: editor operations remain on the editor server, while observations and actions against the live game remain on the engine service. +## Limitations and security -## Choosing the correct interface +The engine service and extension-defined routes are development tools, and should be treated as such. -| Task | Interface | -| --- | --- | -| Compile and run the project from an open editor | Editor HTTP API | -| Modify editor resources | Editor HTTP API or editor script | -| Render an editor preview | Editor HTTP API | -| Read editor build errors | Editor HTTP API | -| Inspect the running scene | Runtime automation API | -| Inject input into the game | Runtime automation API | -| Capture a runtime screenshot or state | Runtime automation API | -| Read live engine development state | Engine service or runtime automation API | -| Build in headless CI | Bob | - -An editor preview can answer questions about a loaded resource without starting the game. Runtime scripts, physics, input, dynamically created objects, and platform rendering require a running engine and should be verified through [automated runtime testing](/manuals/automated-testing). +::: important +The engine service does not currently publish an OpenAPI document. Integrations should limit themselves to documented behavior or to an extension's versioned API. +::: -## Limitations and security - -The engine service and extension-defined routes are development tools, not application networking or a game backend. +Runtime scripts, physics, input, dynamically created objects, and platform rendering require a running engine and should be verified through [automated runtime testing](/manuals/automated-testing). -* Connect locally through `127.0.0.1`; do not publish the service through a router, public interface, or untrusted tunnel. +* Do not publish the service through a router, public interface, or untrusted tunnel. * Do not assume that engine service routes require authentication. -* Release builds may omit the engine service and debug extensions entirely. * Runtime routes can vary by extension version, platform, graphics backend, and engine capabilities. -* Use version or capability negotiation for extension-defined APIs. -* Do not claim OpenAPI support unless a particular extension explicitly provides it. -* Use normal, secured application networking for shipped game features. - -If tests need runtime inspection, input, screenshots, or application synchronization, install a purpose-built debug extension and follow its security and compatibility documentation. +* Use version or capability negotiation for extension-defined up-to-date APIs. diff --git a/docs/en/manuals/images/automation/engine-server.png b/docs/en/manuals/images/automation/engine-server.png new file mode 100644 index 0000000000000000000000000000000000000000..9edd0683f283671ea259037c09a42b5176f132cb GIT binary patch literal 48645 zcmce;2T)a6+ck*VYO5$_MG*{uN)Cd82nq%+IVTZBl7NULNfJz8LhzE6AQB}iIisQ= zSwW%#3P_NgCC}P)_xtugHS^W{Q#C_Xw+h^Q&)NG4YprMPb6-L3-1@b<*3!_>tfxqx zR-&Onhgpfu&EgTB}dT?1y{)ptG2ls^>1-no!4Ihqtk-$*8HR;nV;6dc~Z< zBJJ;+pYMFCWZ6I8RM?w9@%`r?G}1=rKP~-e>!4U+@7p zJe)N)F`+m-{GDN9y(RbI+}>_0$vNZ;IIp{FG`({XB0zox#xdG&|lV$=B(#&_7Qkb$6A?&$4YZy)j|Tl%HjOwKY-YeEoeh6Mc>&A0E>;o12?&V-S&% z7i&2!D44O9j;{7wwl%-!!K2Qp$2}5k24<+jw!b1z-CkwXGxY0M+@=Gq_1^n#`}z7B zTp9ZEGF2<%%F7hP@?WDr%bQ z+HGvH7Huw8mX@FIuG^7@Oql=OLDy7Fa{YVh#HUi~oQ!W|xz`W?tGkU& z<)cA}r>AGAQ&N7x;)2te)BQE6)uQnYx~>w&Rl%PZ=4ZDtF(n&^nVY3l<_;Caf6esq z4O*DjRUT+gpBT&?io5*z(k{^(Syds&lZOg*Cls8A>^5jRbOmL^sV9dHe#_Rc(ZQxp z&xjthuo#k=+P2$CXWb4i1sRz~PX)}P-P}&jPkyx!c3sFzNKCBDvE6On_)2H>1_p&x zqsqEW3$YL}SDk}$J6ri_ck-NcU6_tBs(gA_y&>mUZH!lvc6P$R*UauiS4qIgGxm8j zW$oR}(p$5Im8$ak(wVvh)!KyFsfmfwx@(t;-04{l*;-wvdU<&vYb$oq;WeWr`4SeC zGONbKnThq2cvP-Y!Q=|^IuJtJo;Oax{(dD;|pFU^Md6U7SqqE;&)Om(^7{6+N zBh4brVgKILKOPupnT+xj%nlx>xIcIheCR^XBP=wvH%BMm@i4Q2WwgXa)i@POl$6k+ z{rlfFW>~a|uHVTs96n=Yx1qGORM>eYZN$QM_wL;j17Fp3U8W7AEw47dIz_co39os6 zYK73TV?Ce3B{U~3uU%6R7r(_^T2>~7cEP&lX;07P6I0);n;4PAD4>0~_!==@HHG_B z8$0#Dtp)<;KDKY{n0oSL_139Ey=?r_@bBT#xG*U2@p8phJ{(H&>3; z&jnIlEjvHzjloMM<- zYS1I(*R)Xac}j;x%GW#7&difBBsF_kDhkW?J)$=>1_vj;L`m<6iezRN5&0G=pL<=@ zak9yngpW^PjNH6NOU_D@*1Tyc$*eeE-{U!s6Tc)#$H9e8zA2@8f7tg_#E{A=8yc&4 z;M@+4ckf$Ubr?e#Q!=^ZQjIHoA|;u`%WG>7sNbifGUHWVnPLmS4>Wx3Zws3>XFOf< zm^)5-him?H*X|sfUM2Sl?5k;gLUyauPz%SD<@BiGHcl;-$;rv$2b<2FJIBJpVko)2 zGuq;+y`y8<+qb92x+;&FgdMdgh?WUTxV@UL%U*Y6WaNR@;+gB$ubVcfy`-c>%03hP z^(p+e=iLcnUjliD44xi(!c0d;*OKk?V#Vr|1)6H)w9Uk?Z30)nH8$2Gu2C8~!)LmR5gc{# z>heCxzP?-6?>fSxexI7#)TqHOAW)a39rfVh+9fuwjFSXhCP=ee6I(0>kE`CEKr@j4B`sL3J^v!(@Q)M>PsWT4? z)U>thC2WGq-`u=S0+fxFm9<xK$-j5HyfN`{?$mkE#Ju- zS2lQlUMK6Co`6NG__kGS=vvgeb^N|LtLf;fGWTVV3M=lXXEO#O z*%>d5{~I+ml$KJ~?ch}S*zP?$iCaF|g<^c&&$7|+ah0|LXHRoQMMcMf^o8P|54N!z35lo|xv$?wZ?co? z%G+DXM_lG+wNi}|lXUXqhKG4b>m;=}At6B}S?2`uq1P1Q(+dcMUth$lSJ&=(+USMZ7M z{mrF3cBM##txP*&22bRaH#D5HeC>X;SFUQ2R_N>*+{Vd4q2od?XMG2;ygaOO%r9{r zXjC7IYL#~{P8~IJaoziYhoNCVKp1vKXLK|!xlyC&+WEfv#Oi>*!Sr;=6+f0<>}F?w zr-4jp;Q2}|0o&=CpCaqo^bT(#Ye>Kdr4IM4w6eOc)Vb&`nm=X1 zb}(kK^8QqzXxHz(a#z_1;ztkr033}!_Z|!m4o*qjSxN~D{tLF#e0*SgYBl+ta$g_j zdqN&{=B=kX`9WT z{r%00rq(RWi0ArC|04f8#G__{ua$eqA})QMJf*jj>z{vI{4DAJ&)@%tcYVU~pO4<| zxx{&vUi9kn64hGzyW5!qO9W}@9~`@umSpMg|HDUo?H2~>GzETsaQ}X(mp!8s7Z=y) z)Koxfs`V+4|BynfH*B1ooC7XP(9Rh z`JW~62eBOeuwbo}TOBo-9u+o2Pi3}qYEs_SeIP%(`IAKl&1TlWugz^v@4}~LZ}@1n z^(1}otfJq{65;9}C+nNAp#R%$yxM*8(_V?fo9t_aFa7g^C?2O2X7Jo~+c^}x7*D9g z$n7Dm=0fiEx?3yPkxFFEw887<%1!R!nMT+7I5MYYo~BV|`X1;_C$qc%6bz&HH@?m{ zuDel@XXKv+<#?#+!&2hKqz*_q?z%YTYWgMiiBVPXOE8Sm4w79@ z%{>=l-bLzeDZ2jmeb96Yq_Ro_AxGW0^T*x0ckvpHJ;F8$3JTuQ@?l9I9_}#fDE54M z+%8Fo?l7e}(;}>CDrkq`)o+K`+1Y)#@sZOrGbB*x@)t)sO5z>Hx(E+oHmQx4HAN4Q z7@E>M6YQTCPhX&$v$)_~+u)?mevs#v)WxZmzbXJ`*LrpFW{z#2(Uq^S^lm#&_8;cv=B|rXlprgSai!^! zHq*9kENF>|8n4A$a_s`*<2rzle)uPTLVx2vk>2PjHLZfpWRg~1Ae(9rN0)} z4;Cm*eav_wj`4(J?6n{7b{)T-00NT;RuJzrH7M*fnZR5M_D?S(N0E#TZ*Q*_up88_OV-t;P$;8g zW3~6U93-r1pf&$IppZhz<2|-up{sKQr#c1)ljuZ$pG0k#0mx;>s>xE5latRr+8M4C zC1nC6SZr-xpAaPFdng>V`ZCrRyXU{KFl(Wysd-pXP%XJ&#x%O=F#}`ikW%d@PIA;Qg|4o^5&IjuHF9EYez^abjoUCa^sHdv z-TI>IbY;!WT4?k2bJJtk3IQ~_sw}QtYu&WVPoOKP=Gd4BnADucmN$S3KI%)&p`(Iv zIO1A*K|YEXdbgeFH4nP*_2CZgIOFP2LgqW^Df5wcC`Y zM}Jy>DFmNwey#6;KcWJ394Rg?E>C&%Ze9JB6^?6oI_?ZPVxm8_8a(^O=;UPmo0}`r zjVgCt$fn8$iEju#ZYLM!x{w{}JgMo&rYa@v&+!?lM7AM2JNu<}w$)5egqKR9R=Nni zxC|e&K+P5j>c0Ed!{1LuMMtx-u}L9Ez5p0@4h12Nspq6LxBYORQW#B^Rh3RgR^V_*~ zI4HjwUq@hh0{X_xlr)Jy(Ki4P;Kv$L`!sh0N=f!XW$HIr21{lTiY?FsoH z^CNqByjH%vxVShgPrqbCUDAc~jEs!Mf+$kyCbegC?S@=>I$HXAK1b{lbIFqnJ{FFe zqdz;**C1foe%kM_@>x)^Pk9bwNjyOmZ;(G&(XRWMKZr#4EiuInJo~D#7e5(#Qevne!r;~f#ob!B!40v}GbI^e3 zH)nG%2B86?); zGWFM&mp-8mUG&gnPJs`XrR;wJ-H5eZ{=|eYb5K-DXRC8baWOVnANR{M{Z!1gKrXE6 z$D@v>Shd8bmYc1Ri{{N~l*RcWSFGuA{V-ByP<4ub#>U3dQVtwFdK4em+ga+9E$pJA z;){T}!bk6T@}%45En8$aEBLWL3r~|!DrBYR`iys(7LEG9t%=Q8q|H{Xd;2QygMwuE zQT5$3Q)blMj`7~wlFndgC6RlMU%%XxVp#kjroSp*G2*Oahv(7pck8%&eg^2)V~>cE z*1=n0%QRS!0R};3##QP+3kV3fb?a8eX8ylcgXa4}g+GT$U7R0t(Txq7L4xK_T^8r< zDDI_M`FVLHF@Dv>m!n{)C+k$&e!#ptMBbw&x=ck&a|L2Acf^zOI zQ|jrai@wgC%e$CAVBV~X{r1GjhpD|( ziefy(YndD^`z+41E-t${8dzdxtXfRAdH;a}s*#dUIFgIzC(~UQU3@aw)sqeh2{j$- z^v`xs^%mUVy(-B&PWFh3r@gul!$Y7mR1^t|?Bnz^4yqsLdC{Q~N%PFQ(f)o-{$#Tm zfkSMnam=VRh0e1XRiP*1v5E1{vy-N61^M5;eH;Jb!DQP0{(e)d$5?l@G_}-Q8v?%IxoFpgS%xgfh0s_M1MqA^bHOP`PtJG3#iox9{#|~t09nA-v*m}rCR^f^HZeK z%uEd>OL%PPZU69)6mf9Tc+~vBKC7S2&rjV>yV@d*BBZ-!&6?&shg57uG}?G~&T<13 zvgR}sAJK*1`WNyYRUtg?;<Hp5wYp#Gg zlJ0Sj%)e&z4rI2~Ki+fv2x6`>kXPcvgKcDiCn}G&?Ti;7SXEue;SAP8_2R|nn>TMJ zyAIi7AyX|;D++N-KQ$Y+ICt*#>(>P1%uEi%<25Fzg~bysIkw7pyE*`=yB;3p_4R7u z;o($T3O#`2HZE-_YqtCwf_%3*IXRIV!6K_%yY>nbjqq2mcs!ZJM2i$Or(Z(8(#p1q z+RmZz9QDFv`1@POpML64TOzfG;x$u^$n;?xLU1`SdqF_~aw!L5m{r?=%iPF0PK{UJ zPszWH)!ky!5?>QF;;xs)<$08&`}$*QzsC9V?99xkA)SAk9V+BToDX5ZLhuxn>GK;l zY+zH0y!Yb8izC1Wl%}@TsP>#F7--@C$Z=u2!7Fo`1#Q)>R2FHKY%4<|Q-9c@>-+2( z5Ymj~&+xV7P*W=7NLt*WJ^)ja=iBAOh?X!d_iME8FEFZq4r^GN6~*#V#X z|Azhko3{V^n*VPJc4}pk#FZ-vYDwBJ0|Nu+?ya7>W@-5ZhybZA+nmkqm60&G`|oA= z{#oD8-{1dw;RcMV{6J8^+yZrZe{cc3*8wOUG5EOA=lWoI1ZVv0l3an;*^e6>r&X7c zp{46wrvQzNKaufAfk<;oj>X?^>UNIK`hQn0sKgu)fdk3*M}e+>$zy?rAEO`8R(}5c z=@(Hz7!?BpLmGNLZJ%72C?{c6TIo{MG_*g+?T17~TN6fF<$+;H8W1uf7a|;YJ~Juj z`as;ub=!%+p55FKaZR*~4@?9vx%|d$Sx}NiP2~NBv9LwSGW*tluKwWd#B94`xN%Zt zgOcJE!f$2MO-cUlOD;^a>^LiM`P0dAe@tZ0Xx^CyL}4picd>BLNWx*@t_d{L*E9hBW_HhweRuLHe<)s{zQRTeR&gO-}j83n1z%scI>bn{H7VN zp6s7)I~j0LKtL6R@K;UL!y7klfNBWbb$1u7VBw2zbD5PTb1e7uyN#%aC=EHbW+-4M zNuA8Vyf^Ng7o(N6wK90i5^^4C{~#pV1rB!PdcOuPT8CUe`rHJj2TL4F6cd5^b=-N+ z(Mi&;G%4YQN@$SjV3Y`R2w6CR%dYu2}~8u$i#}!yW>N7 z5x%~@S2}3dtWm^>@e7pu>Dk%tUkv{+H2KFjAA*dO#c;7N~1JWOql&H)_x5s()i(~bQ+@JCrKPH<&Iyu;CTun{QqY|IU zO$W~QBxbhOgiClFF{;>E87x%$`=Th8@#f8&Irbwjps|mm^!AWA(9qDx=-$G}m{c1h z&wl8Tq@bYST3T9_%a>y*`=j@sIeS)0$-VPS3)vTAV`EAU_VZ_VcMKxg1Vm@1!%M7l zU?33+_k}jNDjq);BBVsOKpPC;1!4BfR;;=ViDU^gdO-q}3l({J@7|x-LN-1=B`}FE zZp&7TmoT|X@_lOqnPuO*_ar)at$aDARf zTeB=4^>$Bz^hi>{C!^D)lYP(iE^O z+NZ(Ts3wv!Gu<5~03d>1ieY{MP=vC3XD!h91n@Fx@F*DdWF^7;=zTPfU+?#hiHX5I z$6%aSR#I{f8I;)SGHV_c6?K?}d${=YZ}(dv3)ScSdHvf4`V`Ay@4}j?L$6>+W&XOV}2A zdreZbAxBaOJz=4z9>z6&!jF>3UNawsML{)6YFo!>t-P3dN-_#hFZPOcHaFKRF)+y&Rrj6GRX%!j|XQ9Ov}9dSsX>W z{IlqlD_7DkzFkhlL}B4(4MTmTa!oac2k;af;riOt^b!NhVrCB@7Jse_anGMGO)0*9 zJ)dq`$5(ZK%bq=nNE9>d1MBR>#DuD;X&iwGy`S`{X^?(wduz^|dAQw=8M4hwl%E+8 ze*u>{`-ji^VUAh);?TS)JFF9{urGh4c=xZi!b0Nd!2THaSld~hp+4Apct3@VmYIu0 z4u;(rz28+46u~O{^dpQW=QFM-Vte@e*`2>uXah4-Rr2gDeI~Ijty2u*;^Mwk>IcJDT0XpMUg-wld7g}jy`WAGD59fN8c_v`4J7xL_R&spCbA8a{Kx)MHe zznz_(-yucuEeGYk0NKjU7+!aNh!I#`A%rHm5`9Rzpekjuqc2f4nnDl$y%66^FHRazQJ2dJuSh?Nil~~9je!Y%tS}w`wx1%cxo+&=IGniOho=do1jAS zb*E!Wf=Y)D`L@v*dnHAo@QOYcyWStjEHP0A=NHk(XjM1T@u}ZKXJD52a0=atg@Ub} z0V^>uHV)_&B>D6?;+%kCnXe4H2^itl&6}0Jmr|hu$CHl1tM863+WG63X^IOP5K-^O z>(5)f#KNFgVw2`0v$7B`LiDrdEjg+Xm75s3Q4FavgVLBexlc;k1_rVu}d z!)PQ50W(GG^`*O5Y8H8Uc@jS%!nWkDNO)s^kkDTB)2Ht+o1jAw=@qNR za{m1J{IROzY}#3`045Aml8L5>Ci3LT6Jab}u@@6Jm|We_U}8Y%N*x9$0~53S9# zzwveP>bWVoVHYt_AuAi3FXt`tqd=^HAa#IceLOv7{lDIEcaOUM38jzZ|q?o!cIC$|jf7AMSaVi2b#U5&*Tw{R0CN5Rph85vELNH57Lpw;LGv+$L5N7KK${4c{1M z_Jj~Di67sxUZY@b!$t>yTIj%(gPtVGCo_B@#ehPl6R=r~j*iw4@`u_-sUe~Ra93${ zwLHX7$LXH|Fg0+qFf(5UV}0=OVYv;LuM=UtfPRic`BPtF&97PM$hK&v zB5?5yO?GZ>AH;IvLVG<^^7*qO7A%8RE;ttRd=wmM5(K|6LZm!B;gmsWvZ(XSM`(IL z&I-`y#=*mP#e1UNL;<|~D(5czf=-Q4JqX=a1D%*puGJ+IZH)juO}ROp1Pxxq?J3A! z_4hU%VC-@HhmJCGFHLKw`gp85B{7{4E^OyD#fCIzn8yRC9BcEMj}1Cz`GQqG^h%AI z!qf-tR{M_i15K&t3PHS2c~Fh{a{o)#yqY|I{6j!!?1R1kHN>s#xAqS#N8n<%-5Cxo z;qSRO2@uH_{~9hI`%j&tdGo^X83%y!XZQuj4s18LG}M|8(_!hSDrbi@L)*5$q6p#A4;7{IX?CCvwxlQKesL7m?HaMUMW%qae1g~@*{B}YS%sM)_aBkc+-8>+CS zaCczte-E$g>Rp(2Ub*z^7lkS&67K(3JNX~x?*HH1@1zEcH1QMyXA@D58j0&;Lrp{V zEwAlZ0DfXE`Rh_&*&x#uq29x`sPZXXL=9Tg){PsVfB*jd)&>?`jppg)_BWckCYFH( zjU$~dgW3_n5}L3IFePl#aZvcsgA8;$yv@is5EI_Bj~NbANSj{1VudO&-mUcsH1nVc zPX*1JooD}8wJHwPa(e3~MghV-P;jnCl} z>j7?(l9g2j5KskQC8&_N>6i(vwHy4V`1!?|b;sJzm7r3kT_4bz2aG4PQ8Hu&Uj0~E zDNCAXdV0E409PW0K>(*5^7`38g#_3DnDr0{rxNQ8$I2JXcIW$a7pdtJMb7TRd-uLE zXadK^TdUz7zr5Bz2R{f!sUU=#MkGN*-d`p}Sas7Tj9U2&%VN>4iJcO-3U?yd3x2MO zq2ZYDBL$eC^$ue(g<#D&asWhYG0M{pBpJ*B62nKxu{DY9uS4; z*XIZiU?CO?oDg3iVr>KGdUtmn?8r|s^5>^$8%;gsbsWFk!E_Je7c~+*+zhD9aekuV zCpan4y$PT<5itOpT;?a#p?@eN9jZpt_s`cJZOUJg_D<@gq^2r^4*K^obv8*rDugC@ zkU|8{k@-rJnAd)Y`*EIELqK9_Rl`J`Z2(oB;dLcL57N&et_AgT&pWt{cNTgehCoXL zRFbrX2plaw{T|cqH0Rmt`YYuSTbSo0V!2E)#fBv|ZWZlLZ#`Ey{2Jnu3ox9X`m|&Q z7oF|rhsq;OWD)!zE+*8m%)bAnatwqg2`xBjATcn_(APsUArd;J20tP=;ujEe4V*m~ zN_?X2W~Z#CWBdY^j~*KF{{3kJM(~a*03FONi_L{`fFIc>2D< z&Xitk7Z0lxEX~P6)?GbNTM4uw9s}q#p7i`@0pWy%TY;enqXm2}YiL-q6hXC_AWQ}f zle%PI#v3W%o-vu&2RoYcSmjZztZU(@S9`&>DM|p#+n}Rhxr~ohVGW4O-xQXd928Kk z%&Upm_siHpy!;7sQA{5T$q<6}%X|+Xfa{x-=e29rIJm`6Urv4fS~2(f05b*uvwxIEk*Kt?w?<~H zmJ)}NAXX-bk4npQOV-uZCzKZ9>^0*2B_9KPvP!7_WdEp-Ml|0!#f}?GBH=LY&h_>8 zXQhytW9yAE*(GWEsyZfI9k%Nb_)t1o;Gg%S`p!G`I3Xj6GDPBiabe!`{$>gp)1wwK zmkuveFU_ld1vAMD;4^7HXHlC>$gr0&m=i{Y0f8cNmn0P;gg!$lbM90pjrWexw3N;z zvX9DOs6jq;+hL{mS$Q}lKv6=)Um7OXh}9i5t4~mbE}nX#6|}4c{V?c57=Znw2+~Zb1SnaV(0-48o0tg7O=U+l_*N2a=_OvpLnHbn8Tf zlXMG{a08#Rf_;4>BhGn&WEKY=nMF=AQSd51+Y+2r1BwFNVW3ZCD4gxg6|p%{gMDPWufr$@{-#}WhJ9}ijb4hSXMj^ zRymIMgo9=5WIu!^#|Gjojikw$^5BZtW_R3d9etSDs*Cxi}o z(R^IzAZmO+@`~;ogmpAlSBi@MV{}D6Okp0&CL}E9*h}R3bhx2>Y*B=yBqe!V*jj39 zm8p7MkDWYd%c{T#Stw|7{Qk%NAw2+h5f#+7tAbvCe=G*;#kyL(g+fY@`S6?KZG+}Ry742!?B4rdE5mn5TV|7yhriO>C@yCje-4C z1$GD?uQS+%2FM(SGS>~K7-w1yC^I~&O((=a?H|9MIaBt`SOYDOz8TTZg84d`F#*Z> zLvSKCPG~zY`8^w$-b2%=7RoA3;xRV%P>86ra8VADmuTJqH3BB`OofV6OKQqDQ3l9( z=~xT18h;&eQ#rc;-sq^PUTC&dnU4J2BLeY!bq7iPPQ#E4u~YuLJR3v(sg|z6KHI6O zAlW1SPoJ9lmzH?jkp!$3ThyjL>IjXlK2GJD7oF;FQigDFw5b4EF`G_a7BLtA&Jdp& zT)w>i%@{Z|buL=V>F^IOba2Fv4kj#os+M#48wIEhCUQA^!ikw}+&bShK5)}Bmbw1^ z;Xyl2z-EN+$a2p8RLLf$Vkdk$XT=j(n1HrtErshrAHtP z_!y{P9}4F`USJ?8-jZc`K*E+XlgEbvQK^ry#zDDYp1}xIe4Gw6au?Mve)Jh(Z!`DX z5)%9F_&_)Up7mC*r|I+%2}xykR*J@2^rF4fnh!?l>OH zOfTjcx`)hX+;w>%*%ix&OH=dn^Wj)DVVL4Q5&AXL!tC9hH8aCSbhdE+b`-#ymMS7Q z!yPid!?o0VUOxHWN0U7H7tk*Wc*Bv*hMOx^ z^XwcPyc+yFAF~Q(DMo(VUtbjA)F*GPzx>Qh_hKA#$70>M!I>xf&-eoOqN9Jrw1JG* zh`@|#KE=J^Zg7E7eO|6 z3Gx7Yu<87`X%FZVfIuC_jouL*C&nuHNu$}eX;V1lY}86w0j> z-0#^3l27)tslC!WrTBL90k-99FL}Mzev6<=LC!@C?6*wDpwICs|GFZzXsXtMP&kKA1Tp%XvJW;nW6cqFo#wd>-J^GW5ZuN8c zVl=e03REvhhTWBmiGVT$=6uP(;50f9{{a0sG&Re?Z$dC#QKY2am6bg}IbT6P(RKWS;-7Zt5Q`>Ls}O%G2Wf1CPkuJW3V4ZN^VafECIKR-V_KGZ&olFsqW z{YPCb?raqQbKjkf?W&)rxEwy~u%L>Zi>bB5@km^p$HRx~&YnHXAZ&9F-B{1q*u%%C zR=F2P`$}J&dFb|NA9Z5v3e6F-`u-4mcc2p^_|V~0^M`)e(cdp~>C%39|7fzZvkiqk zB*7mibzYK&zz~8r1xDXjV%$@4132f=p5y-TK5qeCURjG{NZHP_f^u?l4uahMKv?O| zC2!mi0o;f}u8;q!W3L^M4?gzx&YCT7K<+{^L|=S+i$TnV;p5KzyRBSUcZlB$_z~r` zP5{Ujb4*!D$v??f0@!Z{(y(!jEc(EqZX}^a18@t__`5}|L3^R{^sE-EcZ&x?=QjEVQ+6wgULFRx4(Ze3VPFP{ng$hoUCGEV&?mE5G9wt zW^m&6J0RHVfp=iI;|_Tx73&~VBI~Rz=gMw1Hg%Q+3nE5mo3*tyXroT7`Wl1rTff0w z8gp#fJ?NNN`S><}>`DCI+k4;3OFlZEey}w^{)92c!CxV|uj30_D;6XQv7(CD z57R(tftjVugUKb(IKr;yoP*n=P%fy`Z$QeNx~G_t7BEnMgg{<}g0{{L2opbjj*@e- zs=8DB&k??!FCF|shL=DMXyiTbA3Cju^bEq4p*lWdJkfly1*Q5OTK}Ja{%PM=%)Cv! zvkL1^L(T<^9nqb3Wm#H}R@>g*-sZV*EKTbLOsn;P!h(-k-U2Y>*L!zoj;lu6PkrcV z>jFK_&|8moQlK@RMGVnE%$U~RPZsrFW>{gN*yqomSCv2V^gMh%g9C$$NHkk;qfX^s z{6?PC=0lsrdpI>y?f_gE=2m7|cBC+r$>wQ6)hR#nToDJrfkfP5Vh-YlU6RJutzEmH zjSYZSYiA@TVml!YvFzJ-6HBc4;`ADZJ$p>x=NEih9uI8sAS{dtG4>sj(Z>M39?GlJ zok5`XCf0sPxrexqZo4Oc-6}oUf|f!j{EIk%WcB0SN_dYd-{0TDA97A^DLnE*&~aa` zH*p8~OS525W%z+n^|!ZHrcXQW(`S4Rz-Eam0P&Fm)yT@P8WsY#N742#h87Uu=1sEf{bEC$DmzAoE9a6MZu$9b15R4D_t>#Oh;RypF3v=LiJI+t zW^wQS(#aT9l)JcYI9^sWir)B$9dh_RypOaERL`v(fg`4xg)KnKIJXgwcg4o`-R)Lz z+@YzVak)g&0*+5oUcmS+PYs~A>j8&q=h;7j>_p0Wb?6CRe*OpqkybM#HsyRrTTJJw zfy&mN1m7h-?)u%l`}g0%C#32Xt>V<6)}AO7^+eJ~ob_D(9d83C$}M;i2a6aGD4iwUP^Jx(;e zL%sT!F8zkPCEK!N6_e{6FVNOLX68E>AMDjP#ktD|G~WjXJaNHrU$Ag;dV<}5#_{^w zdb``4hEBN5^d5wUb~C`bTFkI)tBvp;@aJG*+XsLwPf!X{Q&a1Gia&g~iz-#1p`X9E zS9Aa0OHZP2#p(^0!#djAC8eb!z^#3`bwj}suOXK}tLb?z($GLw{yjUJ3Zor>d^s@1 zvTJylh@;gpJRgJZJfs!oefyT7b}!7fEnYG*I*azz(~!)Bk-rUQ15UA3_X~DN!Vi#U zaRO(cZ=z5vih_%aYLLdLw>=Ou^J948Tg9)y_R6j$51qQ zYyn2sn>TGbh22hfDg`wHCW|yj>(NA7qToE~st&70LFoPRatp4l6Y2)a#;2Fc2Wc?n zl~7RFh)Drp;O{#1!S((C@+&!Mup93oJ0kaAV9{u_Dlf&rIjOdQNkZj%v}_ioId*WUe-G2LK5`XC3DF+V0&9dipkz3}-Y-*)iZ zRkJjb^702cIoBUJaKKkdb3@Va?`wLFUUch*vr5JmQD12bMq=B#eae^a`*asZ;g4?L zUIA|f4nKK7?@~%PRUL@BVU*(7+lr5jxy6CPQ(ik-untD1cfhdAj-mIUdjG)RQ4lVF z?eRJVNi}WnozRew3(?d5hm}{kq0z_GAC78FH`_tXu(u9)=Q=HX`Jyr~)$e}6DR0W* zs?&?^)j_HMEP@PFMP5F>{YZQa+i9@&E8n1sywpl(1A5jvdShPVGmy)tUK`-dCvZkS z0JaOlhWkLJlif^r4Z@JQF4jiNf(|kw=kIXeb`&!jQuBf2x-_mjPc0(c2K3ljSyzF= z!O3_JVFQ$UvbeDlpV7Rt1SjmMC+{zHD}GoT+R+&jG*jL2REBRYEn&@Fz>o;4>_J=| zNKx$|?@(KzmygdDa)sWVBRhuLo51rtk(HyvKO{KamM`WeuTB$eXuEAZd4~C8&nfZ{ zgiDt$H5NGMX3QbgIWFY*LYe2e@%tJ|wUupk@{ohe!kmMz5=}5#*WF*wLPHnCd&l1O z?JoX1X+#3hQ)*EE7H0amNnQYQzJ!BWkaZY#hda5s$3a~8b8$UJtzFK86Qy9|y)C&% z@z|cdc#2hIBr}Mkdq~J0h{=~g76`I~fBGV*oxS}r8t}fl<@5lr`@ynMg7M6Z6&Y7s z9$>IKX`Yrq+6cya8<<2ZKqpN;JzoY(B~men43WN8LlO);ZpTGHKRjYrzGisB>5%_^ z`!h$S9 zkff22WjM}f;8guX94-n}*9yo~gdh9fy?c9s2N4rBS(f^c`(<(Yr%s&;eD(}j>VjH= z#woNylu=3}Ha>2HGs#}BUyqClG_IqDvix1h?m~LMlbFc4gInhd>rDne zgFn&lNa*1?8ka0As(+7kq%-chy=witmX;8#058}R?&ap)yDM?(js+C*Z%TzYyZ_+9 zehv;=R4vi@ab=?A4&=fjgIc+fiK!Z!4|0<@xxT0*_m{B|+(#(y-cO&FL470F48?K{ zSOECx=4gSp&|qNA3B(U^ z_73m2+F+cK{^(T(=#Ip^_Q%SVKL!RW;Z!-K68kAWsp>oq^SNVuOY;gQeMS*`w}^-X z*wc5dt)UnOT!SQnq1f;jg1Of2d&Wm$nZ`zbz(ZYPG3L*>0V@JRiWYPiU32vH9dQHh zPn_2$1AA$ieJ6-P&5EMgQeVzaiQMI5R~4P? zp}{e+)c_47nIK5CcXge`Yx!ggf%O1P{Cac1BKV**#Q3jXxpLFaoqwJr3hR$e%cwp+ zBV%I+{wn$4+l+w$5!;uLC8WST;+x**zA&7NU*~+4gHGd zB>Mj}_%dxhGV&?5bp=6pAY&s_QwQP3y?7j{ha!Crz6EG%e>}&j69y4`Z;ZfNT^HwX zJTp5fk_)Cp$|dF}2y^Gr++*UMx!S9x$Mqxb&y9VxC@i)7c&=taymS5hHO;^B?cNR_ z5Pzs2Xa`z6%p4q#P^oYPeEho z`k$u3u6O~wni802Z&#tn$aDhpYjzPRjZ-i*#~enP!CCg91ViQ>gU~@n95{vh4ohn51edR@9MjG1P zg0zrH$fLR-^)*7v2HBVYsR%bZDG~EGFxtfdf{TWRXOQx#Ev{%2l9G~pA-O7bkdc+O zw6HhXT5w%GV83bUylZ(CzJwBx;E8Vp60gB!5JM^{VLY`*-hdp&?>mWL05}Q6zXc*6107lmC}k#T9OFfY4yUOTe=TR7Z%5 zANDh!!N#Hz)6EUBh(51;Hf+DK%iI#^!&m9pv14ds#cteSy~Y)RyhLqvgSn6D>w5=K z129pu3(sy6##6*j0`6FUOJ2|*sfPwfqS5>U8Xio(pO;^4+LMWOFuxj13wdJ63-!?!Dn+Dq<`5pxIhQ)+8g06 zHPTH9PJRx>MQE@PwjW;(O)Bn^oK(RPd?sKJ_+f*7LSP>|tMc~lWZHW2`K?`JVEuvpU7&Vm&A#`2a*qB>*m&uGc{j(o zGr`FcI8llB(BPInR9AbUCn;l=;dZ6FfJOs48XcnuX?gH29a1;E{3Ui1bOB7qu3=rF zK)nRl_5Yd)Z5e|KjNvhI49D%GP^18hnD1VWc{-XJ13&u`QQ%Kd0X9x7*60@?UF0_Zk~xj%>I zrB@*fSu6(+idhFCEN%Cmkp8DJL0`M*Mfa=|`X{Uzz=5$1Z`d&}>gyN5N&(8d z9QFPM9)k+Pd3Ie=rvS9>0Sz&sNA*5v#YFsD#v>?*L(P0d%*Zf554qm$kv_8GET~H8 z%YX-nJvkdTkDGr0G_5r_9eZYh9H8jI3cBp*2w@rEKHX}sxu`xqtp;^Yer$=5ARBQu z_H3ccd=`*1yrs2{MtQyN8}>+PYcrs`2<&9*H|I5PK0>YmnyYnx-AJ@X+T~4#PmTb=hiH+s2);?Doz$3I6*>FMb|BWp-k+~?P712r7tgd#F5lTTs!WuK@* z&JqqVGBB7+m=_>pfhmzR-&&_Hl5#2GPFp&3DX$(|QK_!$yz&il;B&7HGYd<;uXC@B zFyM%eRO@si4#_~=pSe2*r9b8E&R49gtlWu}qa8C){(7Zzv+<;u)sW;+JoA0$tVe&p zc4}&%&Y5pn0t)RdpR%ouNmc?)W#Lq$%Z~25c&_CuSmi*`?uCWv;yY26*RK~>R(hi1 z!2J-~_Q639PmTG38z&S4 Q>dc09wB-75Nib}8mHgt}w__!I+37*n;$=G=HNnnb{ z`i2GfeU(UG0xjyYQ%nK!<667*&`F>}x4CRlWW~tjq|0H4TyUN3+b6a4hYJREJoFF# zRWR)*FsynHlIz>{;o}y#ax7#oSn=T)25dn~-_pG?vJ(HDaoHh(sZQhZwp1+mnP(d@ zRFFE1qd0Qf+QAtWm?`2>05>@5$}PcAVBfhFA8+QegXO$+SA`zha&x!3v-6=SFpVn9 z_P5>SAp7v?uEP(iqzm|@kpkM zqyz@O*|oQTO&`WfdmJ_UAU*9PU^U;)!=g@mx}P`zsB`Smd*MfsQH7ET;2Yat^>Uvo z3b_Fb?kgy#`4Y;|ow0wCYsx-n?E{RkwX@p*Bqz1cw0NQ8tP?yeGa<&#dDeJ1t_7E6 zXpwn_-F#o^gE5_#;g=x2@8ly20?Vb#mrMAUN}DlaJbt`{ZDYzDBQYal=EXiDI?ayL zvm$UDBZ)qL@q&!4Oe=DWYqdVnJ2-{Fu;A&b_AEQY(Zx5jve5H&kZz48=DefJ$yF<% zZ>2D1quzMm+Rv9Mh~>v*P0=xbKXRgwzlP{$l1!BhXV1C)~mhO3m&?k|d#t>-Vv&XZ|h6D@NKvpVc z{84}{BxeFDU+hYZ|@o<0VRIaHMoa1TfW+*QH;Rg4ueM3xH@(^FHk5kenUia?h( zybZzj@k(39H4%leyOEJ_aMp%i2{qLR0j-7xRN$&piQ+e~pIv=&nLDZop*U!#Tc^JI zA`(14OmKjoVD-YSFc^4s#s-5ej8;1?V67|>4ZM)lI0rx*3-O<6^8L_4h&`n`YOhfTGwSR3 z-j+*5DDz9xruKkE!jtf8O2rs*6IWNLsi{4`=+v2#DdpL-wqdPmYemL|8fy}Y`>px9 z7;VUPig^bTB_&!uHN@iQXV$Th&k^p(NA>2`v&Ez-g%@>KE_CSX0T32Md+hDAfJCX%@|>6zr^DE69wjFD-=OrhO*-k%SYz=KFn}7H z{kJwTvmh8!=uwQliB#>d2<`jLsW3uJBG^5_FF5 z&Yh@z3M(}Kr3HBU^xOCED3*JQ57U|1<|!X}LF^43K9@e$l_9SgXKa+fqg>-RyH9M^ z*YRHZ62TIc&&eb-jl>?L^bN>r`mzdg#ruQIjGw# zwR%?SZ9r;>US+vbz$ZkF{lHG8;${9Yb~csadA$Xyx=Y5>R-CsP!9$xjZ=S#Av~6g~ z`XM8bJwwN@v)*{puZc404W_-G4N3Jb=qTm9lC;|LP{887c8n{*+ z@${mTwdl8%eb{KHPd|FUTpA4woAUN+3;Z_Z@WdZmeSKLAoBuAX38d!-pb?Po=+NQd z;?j7x(%aJBK=RedlWesL~v??*cFLzv9XJl?r}Bb|Fa z(CK{sE_w&RqhE=d+}b7r;G$=5Db-(Gbjq2Ucq%2ji0_!f?DGc2I&#w28wNdkY(g|J z86EeXJ9p08zKUslbKdmqJDFXEMTH&udf4w}rz@wT!rI2|-Binu)&7rb%d2e?TU-OM z-{7Q|aDp!Q0i?6^#RzAZXsCZ}VoZr^-vY;@oeR`2l9*gx{Ys;#9@fM|%pVy5*~sd}Z(H5uKycdy5E$_8hHj4!S+*^?edTa#v|rif@G;~GD#yg8-ImD~r+ zGJ=HOWc`nuFd-l6D>*&Aaab#q3P%WE^%GCeABbw1g}Q?bLJOrH1{!yF(A{%ZMU~5X z4=sv!(QKRd=ksej7Fqne_4R&sdy$Hk2EZuWU@q+tGu`y6+x2hj!o2@Q5sycmK_d4` zoO`FJQG*5zFq^YIvls*$fx&P5vqDBqPMesRbYnE2LmSO2?p==^?%cLz%aO*$jUduU zip!8HI?m=FtE;PD{JNq3WJ(^<8SZM+Wyp{rDb7PJ462$>_#Q(C>3873fk^$58-62A zFfUm8z06_5o9&FLQx!jG{A6ZMHYn+!86J40oW3}1W#Nd4gn=N<=@7ujj~_Rq^iC-Q zZxVr%^j?D&r|RaoCy9cG)QKu~E;%rBvV8_dk6T$==jb=v^X^4vW}Wta1|x6PyG_igtFyU!^>lYeJr-wQ z4J5XM$=sxYy+c{wPghrD)vj)C5+R^V;#QYy(rdk?zQxwm{$Mm4i%Mb+c9tE{_F%4Ws;05-Es!yBn|8QU z#GSmzM`Mmm0e^t3-U4pDt+jh1u;NG>;^1ptgOli%y?5*gr76$U0lbhB*t5E{Gx}|d z1dpLyK_Q6k_3cl7Frv|g_7@g;124gu5)Xmo3xrI&s^S!rdGt6j!~sQ5RSF~VodaLz zxu;Na3GfWnVS}zJZea%W)RUx0u6c~-jrZApF;^4J+qeOhm zGwJxp$|l%-&&m%702ZeJ0csFV24qu*jLR}uwrZ7U!B6x6Nd)XT;EG)d&rCf!{gGO2 z+2-Hf&D#m#Q}vpR7`EbrS(n^VfvMI^k9WXiLb}p(p;enwJ7|Bb+4eJ`MeVORsk+^B zj|*M9Ddk?? zU_#yG0JIRt6h#0Eg+Fr=GHR-FY6LK3#G&-G{?3bq%m@6_XYZK)C&4OIsb8sY=56by zUQ+6e2V2xdycfEoBfXWBv;iRX99{#W;iEn+3DpONpUdu{Zt3>Sp_5aFv<>JcfRE3_ z#H9J@aGl%hC^xzf?C1CbS*HVFD--y){nny0(h6YWu39jCLp6EyUXEXRWoX~+=4okgxZ=`^%RZ>YKM0|xj@D-6&} zLv+5JGW!OtFdGFHtPA*Gv3o#k?e4mTX~^&e-9f+;Lb(VC>&qO_}y8i_X>salo-=IO^w_V>fjYf^?hsoc3 z<73TQzz^@*zke)MS*h0KI>mG-XK8$AIn~TvL$UYv-Mjts*R}8>%bekCl@0dbfNq(8 zq$VYejIXR|)9#OzTIBX7zYXy}H$MZBa&TXw34YYok7K2F1cG#XZ_i|PIG6?6x{pPD z>`gS1VXvt2(*1t2+^$~Zfu#V%1?oC=f}2Ww@IVC!B+Qszpl*r36dSw-QL zJlu3yL_W__$ZTqs@TZ4|d3FjDweZcHoM40|522=CPM??;ap+zEZj@+C>k*=E(U7K- zm4#T9p@oufCF$D2d66@7NmWwJ!yoJ^D=X8gn8_5lzo~kd)W@{tTGsK0&{SS68&cT4 zUq2Nu-U#a`(Sl2ce|`bD2D&c6mTe01S_={5;1j*xbs+k7ZV*eNhGahBt_Q=@j0dZ ziKH*<73R+g506WFVWq`)B7v}H1Y49~TpVEVWYq4{DR|^C79Sk(zR{$>%wPW*llJs z$isu=2^nk1iBb42hSB_n02DO2*Pgu)y@ht`>cc8=Z<2}b`W0P`HSCuxi9$-V+X2tP zKTps`YJ~Z7c1f7(;H5UcKfW*~!?sJib7#D`K%e>nGBk~9I{+OPGxF1ntBR^$QxezD zLaY=$>6MB8_UW(Uo%~)N>V?R23P{I*89Ct3PvCFE%x+crU_idj+dH+~1MWDI5!RB& zCDf|JRuolhmAsvGKPT&hC-vhg|FmiglZa16`Tf^CWl4%@;5Bf?G)6CFX|Q*HY)aP- zx?395pAa&g1UrRW5zEYItHb+}TUfY0ST$mGZ4vOr-1ULy4%W+)B`b?w#vPMY5YM4z z9KjYU1A{ysGj{xi&xi44fTepv#C|M)A;FJCJ9mmEQp`;Pn9btSCyN(^97V=LerEM_ zBK|TI2-B1sG>Bv$M_^3Vi(vz38&4jjO!MpL>OT7#Fx3P8ax(V);-JUI!TH;avh_mQ z_qNxF*yao|O-DL0t@cw}jbQ-LP`tS<&%EP&wW)mSvl29?!3)WKQ6ESNnqg+3flV@< z7&<*kzr7H0`vd!XAU^Y zRLq*x+F~~xfE{K0x3`V$ksH=;*6Ec0>aRAp(bSlM^FN`05Yy;sKrm)}3)o6Ull48w z4D2cMlQ7PjERmG2X?H8AB@jW<3xo2vs0DfGi{3WU|oi`oOC8L$r zS=PNQ7Z%o3fD59gm`0Kgp3o;9!@>H5jN)r)X~}!>H*H^dl8-?W9&lNv&w0jTtRI^* zzv*6}+7rMG5mfGx;FS?9c-di}ZB0F+fORY=ZpU#zRKaDBohF11p0@6{gS+?cJr1ID ziuUd}W*|1rwH{nt#q+$-)&K^23U~1|DzLN1x8dTi$2~^C#!mytz%gQ%eS3N%`{q}H zu1yhMo1?P)KxmcdOw1Z#c_xf9NL;KipPJ1xpd0h&smr+&tZT|T4a3H5u-2X`?pxwM z%GI5uDvUrCJ@z`Rq*edur1YPpjR;Dz1vMjMO0^RANHCZ1NrZFYM4(60VD)P4`FA;< z$s?4>ls{qg%Zpy+HP?Rq{9};Y&sm_AyT97+Nm*M{RUvtbrz}2|4Co(|i~(8dJH4CX- z#I*w>lxc|cF?2tnAF(0z@YTWdyU!^3kT>m&(f2wH2}E<7rbB!Iee!ik%=niY`~tIf{xAkR{Vy!hy6fG zj#nsu(5lz*;$nz!wR#2pbCETEp98TxDJZ6~MESen!i9lM!iY3Qjx)&u>fPWr6ZaYP z!prx%ZQi)?HMZsfwxHc*oEb*PJedI&Jmq}Po?W*0y^9WJ%kuqne`q#snA4XYfB_-H ztZ*jrpmtuyuRRDvH@m|ejVrRD>fb*$rkP`(Z2$pNapF2X6l##MU}aG%k?FuN+TY3F zGm|uP6PY>O?^1?#Fp#Zemq)xJTn3m0M;8Hq~9LBu8T^Xg%Oq3o$BsYF-;6}9h2Y^ zn96Xirw?`TVxd7c45Fs$?%Hq zLk?-WG)U_mm8l6R85c2!Ulko2A|0&VWgg<(%YD@b7By4j-Q6I>GrW}QT3IOvPhApx zA?C_HPw_@`fOL`Z2BN(1DiSf)n715pRsXL%bZ-sgErhsZGS77@=@s;k^p3Y~)jvEj zg~#Mt{CeHq0%ii{Qgg$q;`P%C)ZreT<+>dmY!T(+^L`tY{vL(8DEJf@`N4mFfgEYC zuMj0dR>8Oz`3)A>KN;q4@Se`U76P_lk-L_?Q-Rodv{&kuAFlw>yqNl#cVPa?a?hBd z!QzsFGmTE~skqvHjROZq#O4qT&l987Z0`7PQNfc95c-p#rl1|)Fa(p}Zs}z&;usR5 z>c;4F!c23hHl&tk&Ym5vp?rN+&e{}SE%C|c>E>N)*W?$tKf1UjXkvI0mBgZ*NL|CN z)>Fp(2>j@P(_NJZuSJ2Xu<5-gP|%+T4}J0b^~Tp0fZW=mgd=LU1!D#TL4>5gx-8Y^ z3aen)^lG5x0+3jH($i1&W@bNT!0XX(&Sx!(a4E3*%hs{*4BG+&+q0hyZ}qc)tst>< zBblVXoqhjI^yH%zske#Ce6r z<{6#5RyOl2y!RW&(50ccM8A9k{GC7oS5W$RpKT{b!pG3%0(jA6ZK8}8PEYtUh|+BH zKb7;pTJ*ZIrt(gS`%k_4N8p(!^=>&LZ)h!?;#!FD?FJ;o3$;h^wX4LOM)a(JUpi~O zJ`ob>*XGcvgu(;Ev%SsF-()H#I5GkSFbZxopX+Dc_@P5u(DJG{BOW|IxyFTYvGM8q zW_#>q^21E#7>!NQ(N0lmfqo)odiAQ3Nd6+hGoei$f}TRZNd|A|%regE-t!xNu;)ic zQaAIeQM=#qYfwpJQ5ZkEf3IKwpraSD^+5`CVtRBZy((KU7tBt->H(5d_3ospaM1lOe(q1P0(Jq+7m62-lUArHsvLX~hf-th z;TCr9+GV)4MGvS4do~W_T@29Aox67l?zwdP_3bY$f8T<*5x7_T%1>U@ZTM(jdPa-~ z*9~g_(#GOHp#1lNv}NCiy$G7bDFMI0Y`LEtkH#fqsL_2^z07=)z7$88+9j|q9LX`1 zuEp1Fg5l%p&(2+^)j6{)<@1*^XlSOZ7G0|&aKt?xOsxz18$aiT(TDC`d@_p?)bNZ3*KGzXtanTJak>M5{?~l|#S4RjRI^9F?D}hRm zl850hchbaH$Hi|f)?%~BAQrQrBKFI8Jo53&mxtJ8i-tNUM+Ur#Gd*Ic#C`zm*fRWp zoK7>;VyM186Kc7bQ)Yf=x)ROBy!*%Wbiu`cDb76H*sbbRSVk$)r+&IPbT_Th-0137 z3y!`$+_puFkfu5HY!)p_r#=^M0|rL)2}BuqJSv`FiTz2pZ*QfKSd{Y(iul&cmmL|R zA(M{>y#vLnr(<=pnyr-C_yI29>w%TUqfO>AiA-pA=CN26g3JKM?FOczK##4Y>B+^+ zOu3N$Auw+O2q6zwALfKI7N0gQsNv|zHYg1&{*0!;0BG4l z@sHpz1$pcKVV(xaVeiK>$e0K~&h)`1G-%LaUpi*&ljR3!Uzc0UrP)K#&_N3(E~|33 za}xL=kfw-9SVl+6RRtia(@BOO5#PQB>%&oI6Y3^sMuIo!14CTc@{TZYmYASb;jn0t z3A>1e1iiaYuq+WKr@V8+fc_A{xg@8ix+21ivs!Q5(xEDpFVy z&D*x+IM!y6KgZY}3IP`3$J^8JB=QV*BWUJ_G)Fc+I{jZ-fMsoaTW-XSF@Hupy~ps= z=638t6lFT_4Wgk#w`L0R3H8|4)MpSXmO=RGFN9SSjsU^#oE|tN*_^Pinn{+mq_0d(tjeyQy z5CDluz$o)h4}Ax%#W40aV5}4=s6M^u&ya2-0D(ltmz1u?S$9T^!X$&pw3&EP1-cuF zLa)UA`A0{>$6(GtzUBMdc6!(lFuzgeV;u7;)~bIvYff#;^YQ`vvLhp+kiX8GgBNVL zc5PM2$u=ta1&1$s_f%6`-Hh^kD>Axuxwye>XA-wNr*0S0ZTD#T`}pS6Ekw#w)N{rd zE1h_SDKKAYF z*Inu}F)@FBPdU7aMn^@3*S$lriyBb#P5%tJZtql@;bag#%J-gxv!L{rO8xPS`<_}SjBK=I~ z@t+xOz!k40Gj12@$fg+?VG5$A=#Jg<)<2-!<&v&Kab;A8Oz`YKXwcIIomEs=@35!W zysy5W%B4y}qa;&c{sc%9$U38$dijJgb$oZ^BB8Dy(qZW>eeLBu6mxF|v$bH(DTunk zMCd>dp1pW+`VBaWaSZc_{Lhc;O{cM_=cT{)yP1&@pp_PFLkpGNG_c-4qVJe?YK{4MecrHv+#mRjKo#%E~2Ku@e|aPG)R|z$UXIYHH3{RzIMf z11IUV4DPW9Aogz11l)Cee0(6YHJ;%;peBZGzMY4z?#{}V`y|wTdKpSq&Xh2KkjPg2>JrhABmhS@_u<$WLCwLNJOjl6+RTimWR`0;s7Pjtmf#Eh?Um5&C5hl4ZIMzk(ipp^kMV9jk`5i=R&q1~fW6C?d3(RB z+oDaI%@Do*%ljG3SZtkkGu}`+*`Tz-)GVRlvi5yYt*L4HGctLD8Da2ULt4xmNl9k` z+)h0Cu&0kIQ%L-ovaVH8A1e?nBQrUL;}?-RB*C~jTw79>CG9v1Jp^uQ?1TxUc-L?8 z^QRrTHa~mRvZp?bO7h3J?Zmwde@}@xOR2c0&kgH)l$?}A$$P8el;J`A=a>xBPM&>n zJbEp~^r#+kVQSyc{C$bF|HPF(8Ei2^uHx@MVX8e%{`&md|2<)rJGbFq7hLzCSqVawNmwio6pHUc!GyA3P z|N4Zo=`uH@xK77$_@TzsR-5>$)z)l}@X+ms@W#ywlsXb=z7=cHo49Aj0Hi2p-F|R-ut9iEM>Z>5( z=;;Q%$wo5&oV*uApn9w4&)m+gB+lKT;ieI1SS9XBzYSg8N;9AlWvu2N_wDPWqqSj= zOdlqvazssIs!!v~?L6baBSSEZ?c2Y9ulFIm1(hjEGz}a!QwPdHgMT$erS^S4@Web+ zPFw3SyNSYS$@RvfL%6i6s1rEvS@fL5Ik_5KgGTK3r`r63o@wN|w_Gm+zBdtF(3l8Y z*Lqwaqs2R*D;6HgLIq8<118<1cDtLV<_D*t>qa{v8?;3lLtn53*`5T=)5AElOvD&l zwr*|6=tyH|NdkVz^Rxj-2^nI1ODR8U?>tVNWGZl*)=(C8-=S_L^;r97E?n5eZxQd9 zR^9EM%W3Y-`ce#HMpM!hFn#6;GfiQpQ$A9|Z!!+M0UM#Dpj6#r9A;WAK%>Z&k%>?! zEKk%NJ8Ja7_!iBZdm+@g!CL`Z8R6=B=~g*$3#X1Y;LS#0v3)UfnssGm?`Qgu1_QsZ zr!55B=m(cf;A~|wv@zq`zmk_W@KSiz+q&PqvE#zKDlxWUlfON-)8GbbfLRZdkJfoz zyW12hvK)vz77s@y(t8$jbX_a;i3Qz<1AVAa%E39%w4X~&L&GsEwOsRE$Yl?H(_|MOqh8Ya4mvbPYIgHMn5uBf6E8 zVoI%cJZ9i^QMjKjJ$vSiA!kCzmIB_2#Z;3fO=4zKJZ<)Vjfk}vTnwoHzL-h%8Z$~W zAwGtwI_lB}Ai7C_apENbZ}ArL)mW7>>pGx8bClO2&=@5z0IGTJ+_`xNoRD>OQERU9 z@~T@)6kj7)BOJ_P_G!hvNuuwbH=*n9Dt4 z9@)<+TR${Byw|g;pFhP7hwKyrj6Z`_;-x$334~yCZR_}rtUzfHCNxt}x)=vP| z=V$8@3`9J2uG%8&9B~GX^(dNDehFQ(7eJ>wr)3E~(xhoq8To>1pS5)u+ANAz=IBCb zZ%#}N|CQ_6!2YP~T6+F19TRCtnZ>7Y^3XD1_@QJ_Ix;s||DwpM`B^xu-~4+W%RWA9 zCX?R^8-DvmeZ6cPTMM(THuqwr8TL!e3TUC;6clWxddhnqY<1Oj9a5536kpAEyJz)E zsGhfAfj4okJ*E44%hRKImHq~PFT%My8tkSxIJf6#U8xCt?bCgNf;vHIuH)*CQ7;*H zxXiRFj0gLEI8?=e`Uz@vC}n5NoSDS#prAA1%Ahzg4bm6 zz8|1|mV05Vi#JBVB5GNJ!wuqsjjgQ`A9VV|R|FSb)YX51d>skuFOc~Wp0McF6t78E zBI9AZtfvjUo}8@Ajl`7{V0^TN?<450!}Cg37`=n>Oj)U$H*aQe_t>8KydUw%5-Ujm z9<*n?LMp~~{pM`cX;#U$hJjADV?D$Bu14 zzDT6RNWAIwgGIIlSvnMWPv7+?Ll1${5)`_oGQ$&&WCymW^*Dsykdcl7)jK_BGFJU~ z;Xocvqq63xMH&;Ziur1vQnZ7UBcF^NH}3YpC>}YI1z)E5UekufW$RA<^5A&1_(`!( z#PH3=#>NZf1~xdYnJiK&E~qY`r@u}Xc|fK>INFdw6y{>0pAJ)FCiN{?L<)e+Qa1dY z$ml_Qz3du=)9=f5_Pt44bV@mIt#Ia))R&eBL^Z9Fz1!Y^~O_PG<#TgEF zI$?HlPoG~~`}367D!`|2W@JR)|58;|6-MAuQ$r-$otW(pVmOvVSmY_nu{f-nX*W28 zU^=8tACSLYh)Pn$V^S7$k8a&YiVI8xCmK^uk485o1-mJVLuolo%^8oOMwfw*ah&z} z?&HUFIC>)~nvKfJ%LA^Km}u+iS)h3qM`ks(7`zoCFn4ZI!<2d*Lk3FKc6J`Nmu_?% zjfR|tVq^p((5o!~wt1&Az;_e7(PN#3aLDag+opMY%Tzg2Jw13({vi16u{UP?X{Pk90Awl( zzEYbUfFfuff|GDa(Cs3Y1C2wgR^7o5N>~CgOd<61#`Gnj zAmJgs<>xsj1*CEo;1n*oG*PXfMk-<4^C>&zXh^wMuERU^VEjp%Xe4QV`fI+9N5mW| zyk|V%fQo`QADRaq6|pP|a#iLTRNNl5O{e*V+~0*rG>z~f{g|9;Fsnfq(&1j(Wd;Wi zJuP38h43#7^)E(EyBCSHlmWZhMtL<^R}dQP*|n>Snp1oV9c0?7c?h*dcWT1&(s%zh znK&nOMci>~lucn)YHABFSYnjk2j_x)^b~=d77SW4v6_(~6&1`or1O=&)Z1GcO%_de z&eSt9!l$s8A`d)JO-)`hhq}iI#K6@7h{~YJfRgTNA$ui{syb-gIMkwFC!5#dp@(fOSm=-vc3b9YeehM&;EMH6!f=oPmZx6+i4f8t%ki z<<>0Z_K7EN7y8wl@dZ+RZ!uS+t{3D=-cB5t(L13^|3&l#-`mqegoO zU-X%6S;(+crn?`nJ3qD6+T#!;oHS@zFYM^gs~??41b&+*tx2|4j(^G^0bX zL4|i>##uFK+K?7&OgdWkI<@4{@bE2!V>xek{~$+I9IurEj5pCZbtQ8nOX%CTuOSth z=#y=!ffQb#n6L5o9|1)=nV~d}VfY2O zwZm(wt87W)SQNj7w$WJLL6?$;PGKZ;4BkW=>7S1f^Il}m;h;XO8?=gBIB*oJmvPt# za#?c@jk!A9?+J9pS*R*^C^gl>a8fE5OdSPZw22+BzUVAot13uI5)rLH!vD(Jh5{HJ z={!5mSs7G9tUqN+oz{I0*Dnqcr1*fPG{lBnhe9D$)y0b$<$ru3`g9vQ^f!opnxhTG z5%_d5(KwyPq6$m;_$;~~5-i5I+SPo2mat9h)txoRPE}k2I&-c5sYk!Q$L=b*M19RP zO1-zhMR;0?+j* z)upV+vy2mnNsPjaNYxF8En2vz?G$AA84dlWS-n@9oOU3qm&~RbQKJpG_atI!0|LY? z5xlri3r(v&9T~|MU$XS@^r~~Q^UWs(=_f*MyJ$TE(+seqhIB{pl(vkmQTlS}5B7dq zi&ZXj+Gg#yJY9pDaj9>@I2wucG)LztW>55xD~f)hk(| z?f8A>yft%8Bh2n&JfF!`|DLt;HIrcKONT}x1pN7jOJH5bvV7u!pzQNq(lUQnWWV3C zmu7D9%S$RO<#lM4W13|0vIpMac*xe8Rb*Ez%<6&W+(N^8Zo=ekzwmCuPo*#6__bwK zpL1D|BfwxS=9z?9|79sNhBh?VaR%23f7>vD z`IM8;nHcPK^k`R7Xt-9gagT1{@q3-mIv=QPOly-;#_Uxvoriz)pS995ROxX}B=yV`co_!>G| zYQYheU6&ImWt38u3^04aV6TphERv!cGtWXlFC6U_%hQ{^uR}Y*4PA$adcgU+^r;~% zFQLI=1{I-E^PkYTe+{8{w_Rn4aWmJ_(VHw!_nCaSzpk14nq5)O=OncDJre=3;#$ z(=)ASGx;2qpBCNG?ZO*GdOm2a5>rwdP*pcqp-q_->Adh5e5=GkHoP2L?z7UP{6lNG zH(rMw4+)XrnAmR?Jso47_8>y6UcFi!a$|Rsy#6{mjjDdT8{tlb2!uEC;+B}p=p9y+|JiUTDju{s>O0vin>Acrp3xj5ZJ%21c*x9X;@xWBhD?%Hp|1`ceEk*;co325x? zxSZ!4=n&&>>hU?i+VhckNyG$H!Ne*XcZ<9;{4=P=z=u@AGQgg6sR9dv4un4bnt?S9?=w>c1 zrTV%X!r%H$w}zl!hmZ?HixVn^G!$tEPl5E{7@0yJ8t{>IjuvS5tqylH(QemQTwS&H z=!q1|KnM2WwA`1J2m$%lTTgsjDyXgTH2^=2bX_GcL={wmR4O}n>}Uco(2;AK6GPET=VPYP^Lr`S@JVE7>pgGLj7vme@>L5kei|b;XO9M)v z6c(Y90uz@+A}w&%7R)8}A8q&cmUF=a#;rdj^BBVEQEh!Gdp{LrR&&}#jyBOg->D7?vIblC!L-j4DOCl8B zs9_ziFF+6-C1Rp4-!NJz`K(=8uIq>cgPOj6M@k{M_M1HA(w8}-I$%xx4z>Y3?l!QZ zUQSIfV2%=4{Ecz)Gj=Jza!`&oV1F`EWGOZiJ_Fb(0mI8kyv^IS+rKCXp@pb9Xz+{Q zCO5{%Oo_*CYH;iZwW}9ig^aX$kxjbx>nDCD!%@;}U2C`dvW3Cx8_u ztssF)gc%tER`dn5!H(Pxb?AQlE_ls-5iR!k6Uzt2PvSd1It@+)Du9%JGq1Cofk7v7 zz(`EdC>g@04MjP2BrtzhdNuS9inLcdNd$4aARe)>T&(wnw``i`(%A_7x^sIU(;zVqf%QdVxdg zThmNx#SB^4Eum=Sl${s2KsmDvs|GngXf$TEyovhcc3S$j(=K?c>lR%drLUs$V9j+- zLcob$L%r}xsG_NZYO(U^rR znhzV6p#P`?&=8H_!p9D*eQ^c!apB#o0FclXH>cLY{9!ZpFKF?Qg&RhQFO3&uts9ev5gmc%iBto<$v&>jiS` zs>owCsi_If5y)JKw>JT93^Q$`c%u}lOsbg)l*7h=yltyev<*QRr0e$g@Ocqo&1-N7Z=sO;uR$uW9|hIv}uE+tr*;*+Ka`0DLV z-1OeJZ=dru+S-_TcUAMhk*jqUKkv(gD2uNpx&deGM)EJiP+z)oWzpmGCr_q{F?+`h z&JhHJ7e5^%BLLwp;1c+%g;5K|;GJGbTa(0T55o%<3 zaL;NuWk42ZAHS@c+nhtM0-=}h%F>?$42k9}O-}(QjFy2$?8U>_GiP>DmZb4lquDtL zm)8#Ko>|sfWjB4cdPNzE#<+{e9LPw zGU~Aq#6)}r`j4M6WB=2SqZ3ZU(d-|xLK6(hm%atduI5$3}s<%Gx)qdtf{}Jw|EPg*JP)C{KRU@{n)b!+shl*8bD~ zfZF|^u%Lh4F#j8{P*Y|1o<8*muUAScDjFz+-r_aLQ;}U z{x*}BKMJ8qb<9s}9~#lq12b3IyA}95kzs}SO*r4A_WnWkf7X`xW!CJs1=N${+8%q3 zWREtuKs!Sh29hRrGw=%C_1V0$Sc5U#+KiZtr&?nsqo!$9=GlWsEO>Oh>EDzP(K(kU zC~h-HnfB%TE$3FYU9p<4E3>68Zpf-agxHukgTVVW8`td?d1O5tSoN2kp4Z_RsPohM zyR&29vT$x(*D-q4=giiy8Z7w+3h81s1B@$sQAc4N;SH@TE*zU8)$>2n*0!So#u{ZC zQQwY)^o_2vbVtkoO2)cI**=2upv%U_N_0V4<+M^H;on&9*IBHhMD#|^ zbt|y5wOx1Q$dSc`1j_9+_U+oWn|q}V%6gSVs;bvauMjJbKz_(mea{mX&XdAYMCRz5 z8q!{lU^dUi=iL92adj)Ohs?Qu|Ni2_q@*O?WX$2{X_0M=>Zz?qj64SoptPKzOO31^ zsI9~)M96_6$JJ&f(DV0+FjST!$7~sPt>#s6%Wi6Fb)?5pU~Y5F{0$p;8y9s9Y<($~ zbP%8qkd{*04sUo4nE{5K4BNNkVF(oZ<$L)e#dTN;-u6-eXL%+JzG8kAc5CNLETKTN zMpAqV?nvC91LB;v0&m>&PC1ST3m6}?ecw;h7|W3Q4|Qw((g5C(F-R(q;~6QO_E^OAaS)O|MIJzH>KPd$NV|ZD*p}4K5vLvCH-s|&x-;2H@3@@Wf||@eUAJ`Bk}CCtSPt@3!vwt<`xt}U8ONMpIUf8# z$K6m)%3#!|E`*~@JBalY9fIG-X4y!cy{Od@&NYFe!7HW?cbf#{#O3T>WQFYzj+;r0 zW(>SXEeccD4c775CAxQ!Tnjf!YI;jsy(zM9{s%~>1z5q>sasc!?}Q0vRQ4u!;Ij72 zLj1zo;aLvC%73rhq`gi(Y9XeF#s#^>UAkn$zIkyE1MU1DXAVR}Xc*M|bU}x#0GNCn zzaDS7>MBvrLrgU!c#^M`Qh&tbbkh#xS55=pbC0<7=JjhYHrG58Cptqp3?%g#lEvIZ z|Cv};lyrW?k)*Z)B%eFCfiGj3Ai6$0XHn$CPY6lm`9SUZ=g#eNE$6QgV#BsvfCY-2 zB|6O&AqxkYG$I}*Nt1_`SVkq?ob$k9FcaMbLJ#7%iE`GCkKK=zy5copOr7F_-d+H! zqUQiwf3SbN2%QN*Td2Qf5N7}2Woo?WowU|(_GFowP9=#PnQ&4 z%L9ZoT9)Te7=F$IIb<53VD-?1uW9FrU8iQnwcy!{cRqtCf@%?y>j34BAYO{p1Snn( zB~djQmbXvLYVPAkEJj?+_H1Tr(N@I-te}XLcMb*tT;@wno6B^QB3nPg4d7M=+7w>& zeQ!V#c^Kf6@c7u#(v|I0%&{45#tEBvb z)XL>k;|hSgdsCJ-K>Bjbd7{x7pjPzD9Rd5@_Lj58!K6CSiU;P-R4-csN3an=fJOU# zit9YeDR4_-qcrmy)f^RmCmzYu!9{s_8$r|Z0-tfNgJqDrVCq%G2*)Tcmtz)NH6T;EAA5NMniJQ6k}aimzvHUJMN%^l%wrtuFg~^ z=Rz#Wj^J#bdWO|@Lnz-*StoQ7IS+~G3l5TUe70Mkw&OSDvOz$h_AT#s;tW91ySlFn z3wtsszR5S*JTe~(oSjeKG{wV@YBlW(@QV?RD(pE(U8=>axcwBGIqZre%1eys^2}eGz1O1_*61S!z zO0i3NqgpMqvKI=h3Ed_V{{z0#!(UlWxu1KPGf@d@gL77VXKTRiV*oK=Fy=~)%!<*jS!Z8bHX zT>vG4akr*O0KPC0>|3`^9W2MkD1K4Ud6f_jXJyII`P-tR=#GUIaofG`aL&1quD~#J zY;C*3cf=ikhV@?{r?-z@O%pZcUjE~qC5s~2!p3370f_8J#c@q5Iec+xRC#x*-cOA2 z&IqXt4-Fj)H#wKeC~mVf;eT;tIz>qgvmLZMga#pv@r=1_B~z^2^M4Ycl3%`@#ZB~9 zbZ08v$Ou#@U`_bN8ey97nCr8=%J}lynu*v5bz_u`e)2%a==r|g7=t;ztQz&kF4*0? zb{s`Bp?xV{P8xPSRCcpcOvrr9CKxNmf)aRpqZ8V1AZS+99A9xP7n`}gl@ z%RDOXs;Pk>i+9QlB(Lh6gS*Qqp=!{xGUCnekc+DCMGu;Lh&~>;K|LjN$9vdGdm>NT z1w`}~r~~yqeqJ&x*PgH~B*Pyh7Qc<{M+W!@uR`D3G6!jDh^cmu9?FPzrd!$G%OC?W z+fa}EnSThfM8>{5=AgKt2vj}TlK0I@eoK7DHLw&C{#eUvo~ zz$fH3Zy$rpevxL$oAj|`GB)4murL`|0E*s@R$m2(2&`5{3@k5fhzZC7O<#znc!)?U3H2rBZ+lc$%)MG1n72& zNsH`!wQ8mD63NWCb1G3-s5-UFzxnWC3&>NrvKz3{av&ISBZR09cKs~M)KkUrRzKmk zQJI3HEAeQ?A0ASExb!qKoYC#QUZyOk7#e{yDdO#b!Q9_X0B(F+OYYfs{l4pOJo|6T z%C2N&2a5(xEE;S_BARw0Q@9L}{3&@3|yJi136p?n$Wzf61 z>GN5daZgVVUhv4uV(TwnHNnf%F1t&f<28k^=(H)KFe})W&W-V8nczd^+DM8Tth~1} z4rxE4hjymNpA@O7)Q}8@N42zdyS@10c#9t@yF6#wPv9t3?`nhp!Xmi@_QGjr@ef}H zq3YiMnfTQ)u%aoW_w5EOXihIt3^vXHTzlZqxPm8OQ&3?t-Xr6OutBiBO*}noMm*kg zo=XN*h{_JjEd0816 zu_hFN90s7m8ybzGl8Cm6uNd+4{I>=DeZeWWAb7<#qp|)Qzej6VO{^%2^Ld|L-O*d! zN&4RqQzxpR7f)^PnV?QM8XX<|C3gj(;+Ew#QtFGRe}Wzxp=2?4187Zp_)ur2YNg{+ zA^Qk2N5MPN?tX)qacLT?7q=9?&!<$}GoJ2_VkO+#ShslI=MN#Fj%)1yRIYRN#e$(^ zYSD8*m{DuX4h66E#dG_MbjQE_pJTuw!1|n^=DLYo1*}y|GIs zO^%4oJh&l-oVr&=WX!3?dZb7;Mw^y8haTPjX#^GZmKeTYsQ zsRu_=_ESvX88~$4&})k;{I<^0Xubc%X)v$#ADo8APgkZQZI}m< zaro*&&*}!^RmJH2`LrZ-i3ouA4_wry(=d-6bk&95@+_e;g^I9sH&n?RV!x!qFW$s(m1)tq!jxqkhEEB>QA9Odxp|9);x5j+Hdtm=vIUDTUN7&gG5 zr1iVQrVy=fzAF@uJOGY{mWUv18R_cU=>1m*4<39yEv*rLI*w84ee(0@V#O9%&XFb> z7=CmOJeVYjiG&Y<1y2INK7;s6B&d=4Tbi_A z&kLJ_)(d`RzxgumSUj_{e||AeBc5J0?9nQ=Gg0U({}JZ z$dH_u4e0P7=h+`ct7YqTQvWp13c81$p&Nr(%G)ZiiokyRijXHTFeKJ-)Jr#UP-}P& zwr!cSvm6)U@bpw5iDlXgeSMb=6*Q$XAZNd1PGC?_AJ&yA=~@(&Ojz+5#^3%$c*IGO zL?0RghsF9umZ8Z6mI{kkP8y{M`X{_jdKOtHEV#@&(H3UCTRE4KkfYt0zD? zPJLS$AtOqv+r}*UrE{lFeOSceNk0y0QBd#?Dyn407da#2Sbx~YVDyk(%4Ck!%tYQ}j(oHU0eBZ}?kn6>N@(b2W zii55|%@<_0)zJ;b{WBCK$>HWq?vp1sMm{V%+aM#O=fHu}6sZVZ{axVQ9-^ntADqxM zd&TnQSmBK3;0So$SsKgNHqL4r;~}T%gi@f?F>LQyup;LZY71?KGU!xtlFms^4-3Z)5mW{7gcg>ep3 zo*U$nZ*nU%!~3;ueK;iZ_3R!ult0pR6=}QtW~Z$k-Qu>j5wmgjEZf$C?`T5l@kq@0}2g8xCX z8ed-UH;QazW>^bauTJNMO#x)quMxnLhZ#Z$J7F5u2!79(<$7@?LElefhg6h5r6-`eN&%n6!&`d%2XIeUsCXA+^C60 JQ6p^D|9_ejL;C;# literal 0 HcmV?d00001 diff --git a/docs/en/manuals/images/automation/engine-service.png b/docs/en/manuals/images/automation/engine-service.png new file mode 100644 index 0000000000000000000000000000000000000000..ac0b2e8dbfa008849809657b54f718d3a38ee61a GIT binary patch literal 15020 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 NWF!>DD?|+f{}06ZX9)lR literal 0 HcmV?d00001 From 75513c44e2a2e1a133f449bcb34768eeb70bb6c8 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Mon, 3 Aug 2026 16:28:29 +0200 Subject: [PATCH 10/13] Improved and condensed automated testing manual --- docs/en/manuals/automated-testing.md | 104 ++++++++++++--------------- 1 file changed, 44 insertions(+), 60 deletions(-) diff --git a/docs/en/manuals/automated-testing.md b/docs/en/manuals/automated-testing.md index 0986ee2d..823ea4b3 100644 --- a/docs/en/manuals/automated-testing.md +++ b/docs/en/manuals/automated-testing.md @@ -5,11 +5,11 @@ brief: This manual explains how to design, run, and report deterministic Defold # Automated testing and verification -Automated testing verifies Defold code and content with explicit, machine-readable evidence. Use this manual to design tests that work with local scripts, CI runners, and coding agents alike. It covers module tests, running collections, browser tests, runtime automation, visual checks, headless builds, and provides useful good practices. +Automated testing verifies Defold code and content with explicit, machine-readable evidence. Use this manual to design tests that work with local scripts, CI (Continuous Integration) runners, and coding agents alike. It covers module tests, running collections, browser tests, runtime automation, visual checks, headless builds, and provides useful good practices. ## Verification levels -Begin with the narrowest and fastest check that can detect the problem, then add runtime or platform tests where needed: +Good automated testing levels follow the testing pyramid framework, which divides tests into three main layers: unit tests, integration tests, and end-to-end (E2E) tests. In Defold you can separate tests into specific collections that can be loaded at boostrap. Usually, it's good to begin with the narrowest and fastest check that can detect the problem, then add runtime or platform tests where needed. | Level | Suitable evidence | | --- | --- | @@ -21,13 +21,15 @@ Begin with the narrowest and fastest check that can detect the problem, then add | Platform test | Behavior and rendering from the actual target platform | | Build and bundle | Bob exit status, build report, archive, and bundle artifacts | -A successful compilation proves that the project builds; it does not prove gameplay behavior. A screenshot proves what one frame looked like; it does not prove a hidden state transition, calculation, or message exchange. Prefer deterministic assertions whenever the condition can be expressed directly. +A successful compilation proves that the project builds, but it does not prove correct gameplay behavior. A screenshot does not prove complex transitions, animations, interactions, or gameplay flow, but it can be used by modern multimodal solutions to inspect what one frame looked like and if shaders and visual layout is correct. For automated tests though prefer deterministic assertions whenever the condition can be expressed directly. -## Reusable and testable Lua +## Reusable and testable Lua code Keep reusable logic in Lua modules with minimal engine dependencies. Pure data transformations, rules, state machines, and calculations can then be exercised without constructing a complete game world. -Separate engine-facing code from the logic it invokes. A script can translate messages and component state into calls to a module, while tests call the module directly with controlled inputs. See the [Writing Code manual](/manuals/writing-code). +Separate engine-facing code from the logic it invokes. A script can translate messages and component state into calls to a module, while tests call the module directly with controlled inputs. + +See the [Writing Code manual](/manuals/writing-code) for more details. ## Tests in a running collection @@ -37,20 +39,20 @@ Each test should: 1. establish a known state; 2. execute one behavior; -3. assert the expected result; +3. assert and assess the expected result; 4. clean up created resources; -5. emit a structured result. +5. emit a structured result description. -Prefer isolated test collections over starting the entire game. A project can select a test bootstrap collection through a settings file or a temporary project setting: +Prefer isolated test collections for tests. A project can select a test bootstrap collection through a temporary project setting in `game.project`: ```ini [bootstrap] main_collection = /test/test.collectionc ``` -Do not leave a temporary test bootstrap in the project's normal configuration. In CI, prefer a dedicated settings file passed to Bob. +Do not leave a temporary test bootstrap in the project's normal configuration. In CI, prefer a dedicated settings file passed to Bob. CI can't change the state of the repository, it should only make temporary changes when needed. -For complex games, create small "development room" collections with predefined scenarios and simple blockouts. They make mechanics reproducible without navigating through unrelated game state. +For complex games, you can create small "development room" collections with predefined scenarios and simple blockouts. They make mechanics reproducible and make development easier for testing without navigating through unrelated game state and sections. ### Test frameworks @@ -58,11 +60,11 @@ Projects can implement a small runner or use a [community testing library](https For example, [DefTest](https://defold.com/assets/deftest/) is a unit-testing library based on Telescope. It supports suites, setup and teardown functions, assertions, name filtering, mocks for selected Defold APIs, and optional LuaCov coverage. Tests can run from a dedicated bootstrap collection, including in a headless bundle created with Bob. -A framework's normal console summary can be useful to developers, but an unattended controller still needs an explicit completion result. Add a small adapter around the framework callback or summary if necessary. - ## Structured test results -Human-readable logs help with diagnosis, while automation needs a stable result protocol. One simple protocol uses a unique prefix followed by one JSON object on each physical console line: +A framework's console/log summary can be useful to developers, but an unattended automatic controller still needs an explicit completion result. Add a small adapter around the framework callback or summary if necessary, for the controller to process the tests results easily. + +A simple results description can use a unique prefix followed by one JSON object on each physical console line: ```text TEST {"run":"8f13","event":"suite_start","tests":2} @@ -71,45 +73,29 @@ TEST {"run":"8f13","event":"case","name":"player_stops","status":"pass","duratio TEST {"run":"8f13","event":"suite_end","status":"pass","passed":2,"failed":0} ``` -Do not pretty-print one event across several log lines. A collector should process each line independently, find the `TEST` prefix, parse the JSON that follows, and ignore unrelated engine output. - -Include a unique run identifier so output from an old or concurrent process cannot complete the current run. Every suite must emit one unambiguous final event. +A collector should process each line independently, find the `TEST` prefix, parse the JSON that follows, and ignore unrelated engine output. -Report these outcomes separately: +Include a unique run identifier so output from an old or concurrent process cannot complete the current run. Every suite should emit one unambiguous final event (like `Pass`, `Failure`, `Crash`, `Timeout` etc). -| Outcome | Meaning | -| --- | --- | -| Pass | A matching final event reports success | -| Assertion failure | The suite completed and reported failed assertions | -| Crash | The engine process terminated unexpectedly | -| Timeout | The expected final event did not arrive before the deadline | -| Disconnected | The output channel closed while the process state remained uncertain | - -A crash, timeout, or disconnected stream is not an ordinary assertion failure and must never be inferred as a pass. +### Collecting console output -## Collecting console output +When a game runs from the editor, it provides both current console history and a continuous stream. Close the stream after a matching suite completion event, process termination, an error, or a configured timeout and line limit. -When a game runs from the editor, the [editor HTTP API](/manuals/editor-http-api/#reading-console-output) provides both current console history and a continuous stream: +Read more in the [editor HTTP API manual](/manuals/editor-http-api/#reading-console-output). -```sh -PORT="$(cat .internal/editor.port)" -BASE_URL="http://127.0.0.1:$PORT" +### Persisted logs -curl -sS "$BASE_URL/console" | jq -curl -N "$BASE_URL/console/stream" -``` +Defold can also persist the game log by enabling `Write Log File` in `game.project`. See [Game and system logs](/manuals/debugging-game-and-system-logs/). File logging is useful for packaged applications and for testing target devices where the editor console is unavailable. -Close the stream after a matching suite completion event, process termination, an error, or a configured timeout and line limit. - -Defold can also persist the game log by enabling `Write Log File` in `game.project`. See [Game and system logs](/manuals/debugging-game-and-system-logs/). File logging is useful for packaged applications and target devices where the editor console is unavailable. - -The project can use `print()` and `pprint()` or a [community logging library](https://defold.com/assets/?tag=logging). Keep diagnostic logging separate from the structured result prefix. +The project can use built-in `print()` and `pprint()` functions, or e.g. any other [logging library](https://defold.com/assets/?tag=logging) from our Asset Portal. ## Testing a running game through a runtime API -A runtime automation API can inspect and control a live debug engine. Use it when tests must find runtime objects, inject input, wait for visible state, or capture the rendered result. The [engine service manual](/manuals/engine-service/#automation-bridge-extension) explains how these routes differ from editor operations. +A runtime automation API can inspect and control a live debug engine. It can be used when tests must find runtime objects, inject input, wait for visible state, or capture the rendered result. -The following example uses the current Automation Bridge Python helper structure. The project must include a compatible version of the debug extension, expose an element with the given automation id, and publish the `screen` application state: +Read the [engine service manual](/manuals/engine-service/#automation-bridge-extension) for more details. + +The following example uses the [Automation Bridge](https://github.com/defold/extension-automation-bridge) Python helper structure. The project must include a compatible version of the debug extension, expose an element with the given automation id, and publish the `screen` application state: ```python from automation_bridge import editor @@ -135,7 +121,7 @@ Automation Bridge is an extension, not part of the core engine. Consult its [Pyt The editor can create and serve an HTML5 build through its current `build-html5` command, as described in the [editor HTTP API manual](/manuals/editor-http-api/#building-html5). Bob can also create an HTML5 bundle without the editor. -External browser automation can: +External browser automation tools such as Playwright, Puppeteer, Selenium, WebdriverIO or Cypress can: * wait for the Defold canvas and application readiness; * send keyboard, mouse, and emulated touch input; @@ -145,30 +131,28 @@ External browser automation can: Input directed at the canvas is processed through the project's normal input bindings and `on_input()` callbacks. Test both the game response and browser-specific integration points. -Keep browser tests bounded. Distinguish a page-load failure, missing canvas, JavaScript error, test timeout, and failed game assertion in the final report. +The most reliable approach is to expose an explicit JavaScript testing bridge in the custom `index.html`. On the Defold side, HTML5 builds can execute JavaScript using `html5.run()`, which makes communication with such a browser-side bridge possible. For commands travelling from JavaScript back into Defold, use a dedicated JavaScript-to-engine bridge. -## Editor previews and runtime screenshots - -The two image sources answer different questions: +Keep browser tests bounded. Distinguish a page-load failure, missing canvas, JavaScript error, test timeout, and failed game assertion in the final report. -| Image | Use it for | It does not prove | -| --- | --- | --- | -| [Editor preview](/manuals/editor-http-api/#rendering-scene-previews) | Loaded resource layout, static scene composition, editor rendering, and thumbnails | Runtime scripts, physics, input, dynamic objects, or target-platform rendering | -| Runtime screenshot | The rendered state of a running build after a controlled scenario | Hidden logic, complete interaction history, or state not visible in the frame | +## Editor previews and runtime screenshots for visual inspection -Need to inspect a `.collection` without starting the game? Use an editor preview. Need to verify dynamically spawned objects or post-processing after gameplay input? Use a runtime screenshot after deterministic setup and assertions. +One can create screenshot of the resource files in the default scene view in the open editor or in a game in runtime. -### Visual regression +| Method | Purpose | +| --- | --- | +| [Editor preview](/manuals/editor-http-api/#rendering-scene-previews) | Loaded resource layout e.g. level or GUI, atlas composition, tilemap inspection, static scene composition, editor rendering and shaders correctness, or making documentation thumbnails | +| [Runtime screenshot](/manuals/engine-service) | The rendered state of a running build in a controlled scenario | -For stable rendering, compare the produced image with an approved baseline. Fix the viewport, display settings, test content, frame or synchronization point, platform, and tolerance. Store the difference image and comparison metrics when a check fails. +You can use image comparison e.g. for regression tests. Store the difference image and comparison metrics when a check fails. -A multimodal model can evaluate semantic conditions that are difficult to express as pixels, such as clipped text, overlapping controls, unclear selection states, or content outside a safe area. Treat that evaluation as an additional signal with explicit criteria, not as a substitute for deterministic logic checks or image comparison. +A multimodal model can evaluate semantic conditions in visual inspection that are difficult to express otherwise, such as clipped text, overlapping controls, unclear selection states, or content outside a safe area. It is advised to treat that evaluation as an additional signal with explicit criteria, but not as a substitute for deterministic logic checks or image comparison. ## Headless tests and CI -Use [Bob](/manuals/bob) for editor-independent CI. +Use Bob the builder CLI tool for editor-independent CI. -A basic job can resolve dependencies, build an archive, and generate a JSON report: +Yoy can use it to resolve dependencies, build a game, an archive, or a standalone bundle, and generate a JSON report: ```sh mkdir -p build/reports @@ -193,13 +177,13 @@ java -jar bob.jar \ resolve build bundle ``` -Run the resulting executable with a platform-appropriate process controller. Capture its exit status and logs, enforce a timeout, and require the structured suite completion event. Headless builds do not provide graphical evidence, so run a separate graphical or platform test when rendering matters. +Run the resulting executable with a platform-appropriate process controller. Capture its exit status and logs, enforce a timeout, and require the structured suite completion event. -The Bob manual describes platforms, settings files, bundles, caches, native extensions, and build reports. +The [Bob manual](/manuals/bob) describes platforms, settings files, bundles, caches, native extensions, and build reports. ## Failure reports and artifacts -Retain enough evidence to reproduce and diagnose a failure: +Good test results should retain enough evidence to reproduce and diagnose a failure: * test name, run identifier, and assertion details; * elapsed time and classified outcome; @@ -210,4 +194,4 @@ Retain enough evidence to reproduce and diagnose a failure: * screenshots, baseline differences, recordings, or browser traces; * paths or links to all generated artifacts. -The same evidence format should be usable by a developer, local script, CI service, or [AI coding agent](/manuals/ai-agents). This keeps verification deterministic even when diagnosis or repair is delegated. +The same format should be usable by a developer, local script, CI service, or [AI coding agent](/manuals/ai-agents). This keeps verification deterministic even when diagnosis or repair is delegated. From 669b7c1e2d29b2781c49685672e256dc6a81f526 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Mon, 3 Aug 2026 17:11:18 +0200 Subject: [PATCH 11/13] Improved and condensed the ai agents manual. --- docs/en/manuals/ai-agents.md | 145 +++++++++++++---------------------- 1 file changed, 54 insertions(+), 91 deletions(-) diff --git a/docs/en/manuals/ai-agents.md b/docs/en/manuals/ai-agents.md index 66dd1372..11a040a8 100644 --- a/docs/en/manuals/ai-agents.md +++ b/docs/en/manuals/ai-agents.md @@ -5,76 +5,76 @@ brief: This manual explains how to connect model-neutral coding agents to Defold # Using AI coding agents with Defold -AI coding agents can inspect, modify, and verify Defold projects by calling the same model-neutral interfaces used by developers, local scripts, IDE integrations, and CI. Use an agent when the work requires investigation and adaptation; keep known build, test, validation, and deployment stages deterministic. +Coding agents utilising LLM and multimodal models can inspect, modify, and verify Defold projects by calling the same model-neutral interfaces used by developers, local scripts, IDE integrations, and CI. You can use an agent when the work requires investigation and adaptation. -Defold does not depend on a particular model provider or agent protocol. An agent environment only needs the specific capabilities granted for the task, such as reading project files, executing selected commands, calling local HTTP operations, parsing JSON, and inspecting images. +Defold does not depend on a particular model provider or agent protocol. Defold projects work well with either Claude Code, Codex, Cursor, or any other solution. An agent environment only needs the specific capabilities granted for the task, such as reading project files, executing selected commands, calling local HTTP operations, parsing JSON, or inspecting images. This is possible thanks to Defold's exposed automation interfaces for editor and a running game engine instance, and Defold project files being easy to parse text-based resource files. -## When an agent is appropriate +## When an AI agent is useful -Prefer an ordinary script or test when the sequence of operations is known. Stable generators, formatters, validation tools, builds, and regression tests should have predictable inputs, outputs, timeouts, and exit codes. - -An agent can be useful when a task requires these activities: +An agent can be useful when a task requires for example: * finding relevant resources and documentation; * selecting among possible implementations; -* changing related files whose locations were not known in advance; +* changing multiple related files; * interpreting build or test failures; * comparing a visual result with semantic acceptance criteria; * making a bounded repair attempt based on collected evidence. -The agent should not invent its own definition of success. Define acceptance criteria and the available verification steps before it begins changing the project. +Agents are powerful for non-deterministic develpoment, investigation and testing processes. They can help with creating diverse solutions and work very well with Defold. ## Model-neutral Defold interfaces -You can build an integration from the smallest set of supported interfaces needed for the task using any available model: +Defold offers several supported interfaces needed for the task to be performed using any available model: -* Project files and shell tools provide direct inspection and controlled text changes. -* [Editor scripts](/manuals/editor-scripts) provide project-specific resource operations and tools. -* The [editor HTTP API](/manuals/editor-http-api) provides editor commands, build results, console output, reference search, previews, preferences, and editor-script routes. -* The [engine service and runtime automation APIs](/manuals/engine-service) provide live debug-engine state, input, screenshots, and extension-defined operations. +* Project files and shell tools provide direct inspection and text changes. +* [Editor scripts](/manuals/editor-scripts) can provide project-specific resource operations and tooling. +* [Editor HTTP API](/manuals/editor-http-api) provides editor commands, build results, console output, reference search, previews, preferences, and editor-script routes. +* [Engine service and runtime automation APIs](/manuals/engine-service) provide live debug-engine state, input, screenshots, and extension-defined operations. * [Bob](/manuals/bob) provides command-line builds, reports, archives, and bundles. -* [Automated tests](/manuals/automated-testing) provide deterministic completion events and failure evidence. -A model available only through a chat interface can suggest code, but it cannot independently inspect the local project or verify a running result. The surrounding integration determines what the agent can actually observe and do. +A model available only through a chat interface can suggest code changes, but it cannot independently inspect the local project or verify a running result. The additional surrounding integration determines what the agent can actually observe and do. ## Integration layers -An integration layer connects an agent to local Defold operations. It can be a shell wrapper, command-line program, IDE extension, OpenAPI client, test controller, or protocol adapter. +An integration layer can be established to connect an agent to local Defold operations. It can be a shell wrapper, command-line program, IDE extension, OpenAPI client, test controller, or protocol adapter. + +Keep policy and credentials in this local layer. Each mutating operation should return structured results or lead to a deterministic verification step. -Keep policy and credentials in this local layer. Expose small, well-named operations rather than unrestricted access when possible. Each mutating operation should return structured results or lead to a deterministic verification step. +For editor operations, discover the current interface through `/openapi.json` instead of providing the agent a permanently hard-coded copy of an API. For runtime extensions, check their health, API version, and capabilities. + +It might be practical to separate tools by privilege level: + +| Level | Examples | +| ------------ | ----------------------------------------------------- | +| Read-only | Project inspection, OpenAPI, `/ref`, console, preview | +| Verification | Compilation, tests, HTML5 builds, image comparisons | +| Modification | File changes, resource transactions | +| Privileged | `/eval`, external commands, dependency changes | -For editor operations, discover the current interface through `/openapi.json`; do not give the agent a permanently hard-coded copy of an experimental API. For runtime extensions, check their health, API version, and capabilities. +Keeping the adapter separate from the engine and editor means that the supported Defold interfaces remain independent of a model provider or agent protocol. An adapter can expose only operations appropriate for its environment, and permission and confirmation policies remain with the application hosting the agent. ### Model Context Protocol -[Model Context Protocol](https://modelcontextprotocol.io/) (MCP) is one optional adapter between an agent and an integration layer. An MCP server can expose Defold operations as tools and selected documentation as resources. +[Model Context Protocol](https://modelcontextprotocol.io/) (MCP) is one optional adapter between an agent and an integration layer. An MCP server can expose Defold operations as tools and selected documentation as resources. -MCP is not required by Defold. Keeping the adapter separate from the engine and editor means that: +::: important +Do not give every model unrestricted shell and `/eval` access. +::: -* the supported Defold interfaces remain independent of a model provider or agent protocol; -* non-AI clients can use OpenAPI and command-line tools directly; -* an adapter can expose only operations appropriate for its environment; -* permission and confirmation policies remain with the application hosting the agent; -* the adapter can translate stable agent tools into version-specific editor or extension requests. +Defold does not currently require an MCP server because the core automation capabilities are already exposed through open, general-purpose interfaces. The editor provides a local HTTP API with an OpenAPI specification. Modern agents can call these interfaces directly or generate their own adapters. -Do not assume that installing an MCP server makes its operations official or safe. Review the adapter as executable third-party code. +An official MCP would therefore mostly duplicate the existing API surface and create another integration layer that Defold would need to maintain. A better long-term strategy is to keep the underlying HTTP and runtime automation APIs stable, discoverable, and well documented, while allowing the community or individual tool vendors to build lightweight MCP wrappers when needed. -## Privilege separation +Instead we provided an official [Automation Bridge extension](https://github.com/defold/extension-automation-bridge) for a running game to be controlled through an engine-side service. -Separate capabilities by risk and grant only the levels needed for the current task: +### Community MCP integrations -| Level | Examples | -| --- | --- | -| Read-only | Project inspection, OpenAPI, `/ref`, console, and editor previews | -| Verification | Builds, tests, HTML5 output, runtime observations, and image comparisons | -| Modification | File changes, resource transactions, and generated content | -| Privileged | `/eval`, arbitrary external commands, dependencies, signing, and publishing | +Community-created MCP integrations include: -::: important -Do not give every model unrestricted shell and `/eval` access. The editor token and broad command execution can provide control over the local development environment. -::: +* the [Fulviuus Defold MCP project](https://github.com/Fulviuus/defold-mcp); +* the [ChadAragorn Defold MCP project](https://github.com/ChadAragorn/defold-mcp). -The local integration layer can read `.internal/editor.token` when authorized to use `/eval`, but it should not place the token in model prompts, logs, or reports. +These projects are not developed, audited, maintained, or officially supported by the Defold Foundation. Before installing any community integration, inspect its current source, dependencies, permissions, network behavior, and compatibility with the Defold version in use. ## Project instructions @@ -90,92 +90,55 @@ A first file that many agents search for and read is a canonical file such as `A * operations that require approval; * platform assumptions and known limitations. -Keep the instructions up-to-date, specific, and short enough to review. You can store concise project-specific instructions in version control and manage their changes to increase performance of the workflows. - -Where an agent platform supports reusable skills or workflows, make them call the same canonical project scripts rather than duplicating build and test logic in provider-specific configuration. +Some solutions may rely on separate markdown files for specific actions, or so called "skills". One community example of Defold-oriented instructions and skills is available in the [Defold forum here](https://forum.defold.com/t/agent-config-collection-of-agents-md-and-skills/82387). +We recommend keeping your instructions in files such as AGENTS.md and skill definitions short, concise, easy to review and maintain, and keep them up to date. Project-specific instructions can be stored in version control, making changes traceable and helping improve workflow performance over time. + +It is also worth regularly testing how the latest models perform without these instructions. Newer models often no longer require guidance that was previously essential, and outdated skills or overly prescriptive instructions can sometimes reduce performance. + +Avoid building complex technical skills that require significant long-term maintenance. Instead, focus on developing tools and workflows that remain valuable regardless of how much the underlying models improve. + ## Documentation discovery -Agents perform best with accurate, current documentation. Gather current information from: +Agents perform best with accurate, up-to-date documentation. Gather current information from: * `/openapi.json` describes the current editor HTTP API. * `/ref` searches API documentation included with the running editor when that operation is available. * The [LLM documentation index](https://defold.com/llms.txt) links to official manuals, API namespaces, and examples. * The [full LLM documentation](https://defold.com/llms-full.txt) supports offline search and local indexing. -Retrieve only the relevant pages for the task. Use the full combined document for offline indexing or or [Retrieval-Augmented Generation (RAG)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation). Again, the complete file should not normally be included in every model request in order to save tokens. +Retrieve only the relevant pages for the task. It is recommended to use the full combined document for offline indexing or [Retrieval-Augmented Generation (RAG)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation) only. Again, the complete file should not normally be included in every model request in order to save on tokens and don't pollute the context with unnecessary informations. ## Bounded change and verification loops Agents should follow the same [inspect, change, verify, evaluate loop](/manuals/automation/#the-automation-loop) as any other automation. -Before changing files, define: - -* the acceptance criteria; +Before changing files, it is good to define the acceptance criteria and optionally also: * the permitted files and operations; * the build and test commands; * required logs, reports, state, or images; * a timeout for every asynchronous step; * a maximum number of repair attempts. -Compile or build after each coherent group of changes, then run the narrowest relevant test. A failed build should produce structured issues. A runtime suite should produce an explicit completion event. A timeout or crashed process must be classified separately from an assertion failure. - An agent may diagnose and repair a deterministic CI failure, but the CI stage itself should remain reproducible without the agent. +Good practices on automated testing and verification are desrcibed in [this manual](/manuals/automated-testing). + ## Multimodal evaluation An agent with image input can inspect [editor previews](/manuals/editor-http-api/#rendering-scene-previews), runtime screenshots, visual differences, and browser captures. Use multimodal evaluation for semantic questions such as clipped labels, overlapping controls, unclear selection states, composition, or content outside a safe area. Define the expected viewport and criteria in advance. -Do not use a screenshot as the only proof for logic that can be asserted deterministically. An editor preview also cannot verify runtime scripts, physics, dynamic objects, or platform-specific rendering. See [Editor previews and runtime screenshots](/manuals/automated-testing/#editor-previews-and-runtime-screenshots). - -## MCP integrations - -[Model Context Protocol](https://modelcontextprotocol.io/) is one possible communication protocol between an AI agent and an integration layer. An MCP server can expose Defold operations as tools and project documentation as resources. - -As of now, Defold does not provide an official MCP server. Official integration is based on the editor OpenAPI document, Bob, editor scripts, and project-defined tools. - -Keeping MCP separate from the editor core provides several advantages: - -* the editor remains independent of a specific model provider or agent protocol; -* the same interface supports automation unrelated to artificial intelligence; -* clients can use OpenAPI directly; -* an MCP adapter can expose only the operations appropriate for its environment; -* permission and confirmation policies remain under the control of the application hosting the agent. - -It might be practical to separate tools by privilege level: - -| Level | Examples | -| ------------ | ----------------------------------------------------- | -| Read-only | Project inspection, OpenAPI, `/ref`, console, preview | -| Verification | Compilation, tests, HTML5 builds, image comparisons | -| Modification | File changes, resource transactions | -| Privileged | `/eval`, external commands, dependency changes | - - -::: important -Do not give every model unrestricted shell and `/eval` access. -::: - -### Community MCP integrations - -Community-created MCP integrations include: - -* the [Fulviuus Defold MCP project](https://github.com/Fulviuus/defold-mcp); -* the [ChadAragorn Defold MCP project](https://github.com/ChadAragorn/defold-mcp). - -These projects are not developed, audited, maintained, or officially supported by the Defold Foundation. Before installing any community integration, inspect its current source, dependencies, permissions, network behavior, tests, and compatibility with the Defold version in use. - -## Security and isolation +Read more about Editor previews and runtime screenshots and visual inspection in [this manual](/manuals/automated-testing). -Agent-driven automation is part of the project's security model: +## Security, isolation and good practices -* Connect to editor and runtime development services through `127.0.0.1`; never expose them publicly. * Treat the editor server and engine service as trusted local control interfaces. * Keep editor tokens, signing keys, deployment tokens, store credentials, and production secrets out of prompts and reports. +* The local integration layer can read `.internal/editor.token` when authorized to use `/eval`, but it should not place the token in model prompts, logs, or reports. * Require approval before deletion, dependency changes, native extension changes, release configuration, signing, publishing, or access to external services. * Run broad autonomous work in a separate branch, worktree, temporary copy, container, sandbox, or restricted account. * Treat issue text, imported files, source comments, generated documents, and tool output as untrusted input rather than instructions. @@ -183,4 +146,4 @@ Agent-driven automation is part of the project's security model: * Verify that project policy allows source code, assets, logs, screenshots, and other project data to be sent to a hosted model. * Retain a reviewable diff and deterministic test evidence before accepting changes. -Isolation limits the impact of a mistake; it does not expand the operations that an agent is authorized to perform. +Isolation limits the impact of a mistake. From c4193e93b4d0514e204ee5b00d37ecc0ac44c0f9 Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Mon, 3 Aug 2026 17:12:44 +0200 Subject: [PATCH 12/13] Fixed spelling mistake. --- docs/en/manuals/automated-testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/manuals/automated-testing.md b/docs/en/manuals/automated-testing.md index 823ea4b3..1181d232 100644 --- a/docs/en/manuals/automated-testing.md +++ b/docs/en/manuals/automated-testing.md @@ -152,7 +152,7 @@ A multimodal model can evaluate semantic conditions in visual inspection that ar Use Bob the builder CLI tool for editor-independent CI. -Yoy can use it to resolve dependencies, build a game, an archive, or a standalone bundle, and generate a JSON report: +You can use it to resolve dependencies, build a game, an archive, or a standalone bundle, and generate a JSON report: ```sh mkdir -p build/reports From b535901e6791d157333ec355cb546ffcb1dba27a Mon Sep 17 00:00:00 2001 From: paweljarosz Date: Mon, 3 Aug 2026 17:18:31 +0200 Subject: [PATCH 13/13] Fixed spelling mistakes and typos. --- docs/en/manuals/ai-agents.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/manuals/ai-agents.md b/docs/en/manuals/ai-agents.md index 11a040a8..3dc5f5ca 100644 --- a/docs/en/manuals/ai-agents.md +++ b/docs/en/manuals/ai-agents.md @@ -20,7 +20,7 @@ An agent can be useful when a task requires for example: * comparing a visual result with semantic acceptance criteria; * making a bounded repair attempt based on collected evidence. -Agents are powerful for non-deterministic develpoment, investigation and testing processes. They can help with creating diverse solutions and work very well with Defold. +Agents are powerful for non-deterministic development, investigation and testing processes. They can help with creating diverse solutions and work very well with Defold. ## Model-neutral Defold interfaces @@ -109,7 +109,7 @@ Agents perform best with accurate, up-to-date documentation. Gather current info * The [LLM documentation index](https://defold.com/llms.txt) links to official manuals, API namespaces, and examples. * The [full LLM documentation](https://defold.com/llms-full.txt) supports offline search and local indexing. -Retrieve only the relevant pages for the task. It is recommended to use the full combined document for offline indexing or [Retrieval-Augmented Generation (RAG)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation) only. Again, the complete file should not normally be included in every model request in order to save on tokens and don't pollute the context with unnecessary informations. +Retrieve only the relevant pages for the task. It is recommended to use the full combined document for offline indexing or [Retrieval-Augmented Generation (RAG)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation) only. Again, the complete file should not normally be included in every model request in order to save on tokens and don't pollute the context with unnecessary information. ## Bounded change and verification loops @@ -124,7 +124,7 @@ Before changing files, it is good to define the acceptance criteria and optional An agent may diagnose and repair a deterministic CI failure, but the CI stage itself should remain reproducible without the agent. -Good practices on automated testing and verification are desrcibed in [this manual](/manuals/automated-testing). +Good practices on automated testing and verification are described in [this manual](/manuals/automated-testing). ## Multimodal evaluation