HomeDeveloper docsBlueprint kind door: open, close and preserve a lock
Examples by kind 4 min read

Blueprint kind door: open, close and preserve a lock

A complete v2 door graph that opens a closed door, closes an open door and leaves a locked door unchanged.

Goal

Create a toggle for a native door while keeping lock handling explicit. The graph starts at interact, checks the current state and requests exactly one supported state action. It has no image, light or audio dependencies.

These JSON files describe the stored Blueprint v2 subdocument. They are development fixtures, not an installable module, a complete Builder project or a campaign archive. Recreate the nodes in the editor, or use the fixtures in isolated contributor tests. This guide does not assume a JSON import button in the Smart Object editor.

Download the complete example bundle or the validator. Every example uses original synthetic data. The host's internal Python evaluator is for source development; browser modules must use the public SDK.

Build it in the editor

  1. Draw a Door in Map Builder, name it Example Gate and choose Closed as its initial state.

  2. Double-click the door to open Smart object. Select On interaction. Connect it to Check state: Opened.

  3. Connect True to Change state: Closed. Connect False to a second Check state: Closed.

  4. Connect the second condition’s True to Change state: Opened. Leave its False branch disconnected; a Locked door reaches that branch and has no authored state action.

  5. Keep Default appearance by state on Native appearance. Closing shows the native door image; opening uses the native open presentation.

Complete JSON

Download door-toggle.json

json
{
  "version": 2,
  "kind": "door",
  "states": {
    "closed": {
      "appearance": "inherit"
    },
    "open": {
      "appearance": "inherit"
    },
    "locked": {
      "appearance": "inherit"
    }
  },
  "graphs": {
    "interact": {
      "nodes": [
        {
          "id": "start",
          "type": "event",
          "x": 40,
          "y": 80,
          "event": "interact"
        },
        {
          "id": "isOpen",
          "type": "condition",
          "x": 300,
          "y": 80,
          "state": "open"
        },
        {
          "id": "close",
          "type": "state",
          "x": 560,
          "y": 40,
          "targetState": "closed"
        },
        {
          "id": "isClosed",
          "type": "condition",
          "x": 560,
          "y": 220,
          "state": "closed"
        },
        {
          "id": "open",
          "type": "state",
          "x": 820,
          "y": 220,
          "targetState": "open"
        }
      ],
      "edges": [
        {
          "from": "start",
          "to": "isOpen",
          "output": "next",
          "kind": "execution"
        },
        {
          "from": "isOpen",
          "to": "close",
          "output": "true",
          "kind": "execution"
        },
        {
          "from": "isOpen",
          "to": "isClosed",
          "output": "false",
          "kind": "execution"
        },
        {
          "from": "isClosed",
          "to": "open",
          "output": "true",
          "kind": "execution"
        }
      ]
    }
  }
}

Expected result

Initial statePredicted actionsExpected live state
closedstate → openopen
openstate → closedclosed
lockednonelocked

Run the fixture in a development installation

Extract the example bundle to data/blueprint-examples inside a disposable checkout of the documented host. From the checkout root, run:

sh
uv run --locked python data/blueprint-examples/check-examples.py --host .

The checker configures an in-memory database, blocks database queries and calls the real clean_blueprint and evaluate_graph functions. It validates all four object kinds, both connection kinds and all 44 node types, including requestRoll and setQuestStatus. It checks both roll visibilities, all six quest statuses and continuing execution without drawing dice or changing journals. This verifies document shape and predicted actions. Test behavior is still needed to check real targets, authorization and the complete server chain.

To inspect this recipe in the development Django shell after extracting the files:

sh
uv run --locked python manage.py shell --no-imports
python
import json
from pathlib import Path
from gravewright.maps.blueprints import clean_blueprint, evaluate_graph

raw = json.loads(Path("data/blueprint-examples/door-toggle.json").read_text(encoding="utf-8"))
blueprint = clean_blueprint(raw, asset_ids=set(), light_ids=set(), track_ids=set())
result = evaluate_graph(blueprint, "interact", "closed")
print(result["trace"])
print(result["actions"])
assert [action["targetState"] for action in result["actions"]] == ["open"]

Test as GM and player

Run Simulate to inspect one local event. Then use Test behavior to rehearse through the server; its changes are rolled back. Generate or update the scene as GM, then test a synthetic scene with a GM and an authorized player. Verify that a streamer cannot write. After editing the project again, use Update scene before expecting different live behavior.

As GM, run the three rows above and inspect Automation. As player, test an ordinary closed door and then a locked one: this example does not grant lock/unlock actions. Disable player interaction and verify direct player clicks are refused; the GM remains able to test. Hidden geometry and unrelated objects must not be disclosed to the player.

Common failures

  • “It opened once but never closed”: both branches need their own Change state action; an event does not toggle automatically.

  • “The locked branch did nothing”: that is the intended result. Do not add players: true simply to suppress a permission error.

  • “The state changed but a custom image stayed”: a previous Change sprite override is separate live state. Use an explicit Change sprite action when a custom sprite must also change.

How to use AI to adapt this example

text
Using Gravewright 0.3.1 source 0e91fef, extend the supplied door-toggle.json with an original message after a successful opening. Preserve locked → no state action. Inspect blueprints.py for node fields, execution ports and the audience contract. Return the complete v2 document, editor steps and closed/open/locked GM-player checks. Do not add private browser calls, an import button or implicit state-change events.

All Blueprint kinds · execution/data connections · All 44 node examples