Blueprint kind torch: turn the mechanism and set the flame
A composed torch example with independent state and flame actions in both toggle branches.
Goal
Turn a normal torch 90 degrees and light its flame; on the next interaction return it and extinguish the flame. Mechanism and flame are separate properties. This recipe intentionally changes both with two actions in each branch.
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
Place an Object image and select Panels → Selection → Behavior → Torch. The Builder creates the linked native light. Use Torch components to configure optional particles or a shader.
Set Mechanism to Normal and Flame lit to false. Leave state appearances on Native appearance.
Open Edit behavior. Connect On interaction → Check state: Normal.
Connect True → Change state: Turned → Set flame: enabled. Connect False → Change state: Normal → Set flame: disabled.
Inspect the linked light’s own enabled setting. Set flame restores only components configured as enabled; it does not overwrite their brightness, radius or other native settings.
Complete JSON
Download torch-turn-flame.json
{
"version": 2,
"kind": "torch",
"states": {
"off": {
"appearance": "inherit"
},
"on": {
"appearance": "inherit"
}
},
"graphs": {
"interact": {
"nodes": [
{
"id": "start",
"type": "event",
"x": 40,
"y": 80,
"event": "interact"
},
{
"id": "isNormal",
"type": "condition",
"x": 300,
"y": 80,
"state": "off"
},
{
"id": "turn",
"type": "state",
"x": 560,
"y": 40,
"targetState": "on"
},
{
"id": "lightFlame",
"type": "flame",
"x": 820,
"y": 40,
"enabled": true
},
{
"id": "return",
"type": "state",
"x": 560,
"y": 220,
"targetState": "off"
},
{
"id": "extinguish",
"type": "flame",
"x": 820,
"y": 220,
"enabled": false
}
],
"edges": [
{
"from": "start",
"to": "isNormal",
"output": "next",
"kind": "execution"
},
{
"from": "isNormal",
"to": "turn",
"output": "true",
"kind": "execution"
},
{
"from": "turn",
"to": "lightFlame",
"output": "next",
"kind": "execution"
},
{
"from": "isNormal",
"to": "return",
"output": "false",
"kind": "execution"
},
{
"from": "return",
"to": "extinguish",
"output": "next",
"kind": "execution"
}
]
}
}
}Expected result
| Starting mechanism | Action order | Expected outcome |
|---|---|---|
| off (Normal) | state on, flame true | Turned; enabled components emit |
| on (Turned) | state off, flame false | Normal; components stop emitting |
Turning adds 90 degrees to the authored orientation. Off/on encode the mechanism, not the flame.
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:
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:
uv run --locked python manage.py shell --no-importsimport json
from pathlib import Path
from gravewright.maps.blueprints import clean_blueprint, evaluate_graph
raw = json.loads(Path("data/blueprint-examples/torch-turn-flame.json").read_text(encoding="utf-8"))
blueprint = clean_blueprint(raw, asset_ids=set(), light_ids=set(), track_ids=set())
result = evaluate_graph(blueprint, "interact", "off")
print(result["trace"])
print(result["actions"])
assert [(a["type"], a.get("targetState", a.get("enabled"))) for a in result["actions"]] == [("state", "on"), ("flame", True)]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, verify the image, linked light and optional effects move together when the mechanism turns. Verify the light stops on the second interaction. As authorized player, double-click the public torch on Game and confirm the same visible result without exposing graph or component ownership data. Test an independently disabled component: lighting the flame must not re-enable that component’s own configuration.
Common failures
“Changing state did not light the flame”: state and flame are independent; connect the flame action.
“Set flame did nothing on a door”: Self must be a torch, or Target must point to a composed torch. A light is a resource, not blueprint kind light.
“Light is still absent when flame is true”: inspect component enablement, hidden state appearance and dynamic lighting. Simulate only reports actions; inspect the live native light through Test behavior and playtest.
How to use AI to adapt this example
Extend torch-turn-flame.json for Gravewright 0.3.1 so the first branch also opens a chosen door after turning and lighting. Keep torch off/on separate from flame. Inspect reference output door → state input target, and preserve player lock rules. Return complete v2 JSON using a clearly marked synthetic UUID, editor target-binding steps and GM/player tests including missing target and disabled light. Do not invent blueprint kind light.All Blueprint kinds · execution/data connections · All 44 node examples