Metroidvania Studio Docs1.3.2GitHub

Editing API

The editing API is shared by Lua, the command line, MCP, and the web studio. It works on map JSON without an engine, graphics window, filesystem, or network connection.

Each request contains an API version and an ordered batch. Room and object operations use explicit IDs. A successful batch returns one complete document; a failed or canceled batch returns no edited document. The web studio commits a successful batch as one undoable edit.

json
{
  "apiVersion": 1,
  "operations": [
    { "op": "room.add", "id": "east", "name": "East Hall", "x": 40, "y": 0, "width": 24, "height": 12 },
    { "op": "tiles.rectangle", "roomId": "east", "layer": "foreground", "materialId": "terrain", "x": 0, "y": 0, "width": 24, "height": 2 },
    { "op": "camera.set", "ppu": 16, "width": 320, "height": 180 }
  ]
}

Use bounded tile queries to inspect existing terrain without transferring a full map. Use the operation reference for fields and behavior. The JSON Schema describes the complete request envelope. AutomationEngine.Describe() returns the same schema with operation descriptions, coordinates, capabilities, and limits.

Calling from .NET

Reference metroidvania-studio/automation/MetroidvaniaStudio.Automation.csproj.

csharp
using System.Text.Json;
using MetroidvaniaStudio.Automation;

using var request = JsonDocument.Parse(requestJson);
AutomationResult result = AutomationEngine.Apply(mapJson, request.RootElement, cancellationToken);
string updatedMap = result.DocumentJson;
JsonElement inspection = AutomationEngine.Inspect(updatedMap, cancellationToken);
JsonElement capabilities = AutomationEngine.Describe();

AutomationResult contains:

FieldMeaning
DocumentJsonValidated map JSON in format version 2.
CreatedIdsCreated room and object IDs, in creation order.
OperationCountNumber of operations processed, including valid no-ops.
ChangedWhether the normalized document changed.

Apply never mutates the caller's string or stores a global document. Callers decide when to save or commit the result. Concurrent editors must compare the original document revision before committing; a pure batch does not resolve competing writes by itself.

Coordinates and resources

Room x and y are world tile coordinates. Tiles use integer coordinates relative to their room's bottom-left corner. Positive Y points upward. Object coordinates and dimensions are local tile units and can contain fractions. Source tiles remain 16 by 16 pixels; camera PPU and reference resolution are separate document settings.

Use resource catalog IDs for materialId and definitionId. The API stores these IDs and never downloads or opens resource files. It does not create textures or infer engine asset paths. A host or engine adapter resolves the IDs against its catalog.

Validation and compatibility

API version 1 and map format version 2 are separate contracts. Existing format version 1 maps use the core's migration to version 2. Custom data belongs in the document, room, object, or styleground properties lists. Unrelated properties, stylegrounds, groups, and supported resource IDs are retained. Unknown JSON fields are rejected rather than silently discarded, matching the map loader.

IDs are case-sensitive and globally unique across rooms, objects, groups, and stylegrounds. Explicit IDs make generated content repeatable. Omitted creation IDs receive generated values. Room duplication derives copied object IDs from the explicit new room ID and source object IDs, so repeating an identical batch against identical input produces identical copies.

Locked rooms reject edits. Locked groups include their locked ancestors; painting, erasing, object changes, room deletion, resizing, and rotation cannot modify their contents. Room movement preserves local contents and can move an unlocked room containing locked groups. Automation does not expose an operation to unlock content.

Malformed requests throw ArgumentException, with the zero-based operation index for operation failures. Invalid document data throws InvalidDataException. Cancellation throws OperationCanceledException. No partial result is returned for these failures.

Limits

LimitMaximum
Request JSON8 MiB UTF-8
Input or output map JSON32 MiB UTF-8
Operations per batch1,024
Visited tile cells per batch1,048,576
Work units per batch8,388,608
Rooms per document1,024
Room width or height1,024 tiles
Objects per room16,384
Nodes per object4,096

Work includes indexed tile changes, hierarchy and object lookups, property merging, and the document snapshots required by room transformations. Large repeated room transformations can hit the work limit before the operation limit. Split such work into smaller batches and inspect each result.

Tile writes share a cached dictionary for each room/layer throughout the batch, avoiding a scan of all existing tiles for every new cell. Cancellation is checked before and after document processing and during bounded edit loops. Parsing, core validation, and an individual core room transformation are synchronous; hosts that need a strict deadline should run work outside the UI thread and enforce their own timeout.

Inspection

Inspect returns apiVersion, formatVersion, tileSize, name, camera settings, document properties, and room summaries. A room summary contains roomId, name, bounds, visibility, lock state, foreground/background counts, properties, and object summaries with objectId and definitionId.

The minimap object contains world tile bounds and shared room-edge connections. Each connection has roomAId, roomBId, vertical, coordinate, start, and end. truncated reports whether the connection limit was reached. These are layout connections; the renderer determines the visible openings and outline styling. Inspection does not change selection or move the editor camera.

Metroidvania Studio 1.3.2 · Offline guides are available through Help → Documentation in the studio.