Kinds de conexão: execution e data, um grafo completo
Acompanhe um grafo de alavanca que consulta estado por dados tipados e executa ações por conexões ordenadas.
Objetivo
Ative uma alavanca quando seu estado inicial for off e mostre uma mensagem original ao participante que disparou o evento. O ramo falso desativa. Este documento demonstra os dois valores aceitos de edge.kind.
Estes JSONs descrevem o subdocumento Blueprint v2 armazenado pelo host. São fixtures para desenvolvimento: não são módulo instalável, projeto completo do Builder ou arquivo de campanha. Recrie os nós no editor ou use os arquivos em testes isolados de contribuição ao host. Este guia não presume um botão de importar JSON no editor de Objetos Inteligentes.
Baixe o pacote completo de exemplos ou o validador. Todos os exemplos usam dados sintéticos originais. O avaliador Python interno serve ao desenvolvimento do código-fonte; módulos de navegador devem usar o SDK público.
Recrie os dois tipos de conexão
Crie uma Lever como no exemplo de alavanca. Abra On interaction.
Adicione Get property: Current state → Compare state: Deactivated → Check state: Test. Essas são conexões de data. Get property e Compare state são nós puros de valor.
Conecte On interaction → Check state. True → Change state: Activated → Show message, texto “The mechanism is active.” e público Trigger. False → Change state: Deactivated. Essas são conexões de execution.
Simule uma vez com off e outra com on. A primeira lê valores e executa estado/mensagem; a segunda executa só a ação de estado.
| edge.kind | Chaves obrigatórias além de kind | Conexão concreta |
|---|---|---|
| execution | from, to, output | start.next → branch |
| data | from, to, output, input | compare.result → branch.test |
{
"kind": "execution",
"from": "start",
"to": "branch",
"output": "next"
}{
"kind": "data",
"from": "compare",
"to": "branch",
"output": "result",
"input": "test"
}JSON completo
{
"version": 2,
"kind": "lever",
"states": {
"off": {
"appearance": "inherit"
},
"on": {
"appearance": "inherit"
}
},
"graphs": {
"interact": {
"nodes": [
{
"id": "start",
"type": "event",
"x": 40,
"y": 80,
"event": "interact"
},
{
"id": "read",
"type": "property",
"x": 300,
"y": 300,
"property": "state"
},
{
"id": "compare",
"type": "compare",
"x": 560,
"y": 300,
"state": "off"
},
{
"id": "branch",
"type": "condition",
"x": 560,
"y": 80,
"state": "off"
},
{
"id": "on",
"type": "state",
"x": 820,
"y": 40,
"targetState": "on"
},
{
"id": "message",
"type": "showMessage",
"x": 1080,
"y": 40,
"audience": {
"scope": "trigger"
},
"text": "The mechanism is active."
},
{
"id": "off",
"type": "state",
"x": 820,
"y": 220,
"targetState": "off"
}
],
"edges": [
{
"from": "start",
"to": "branch",
"output": "next",
"kind": "execution"
},
{
"from": "branch",
"to": "on",
"output": "true",
"kind": "execution"
},
{
"from": "on",
"to": "message",
"output": "next",
"kind": "execution"
},
{
"from": "branch",
"to": "off",
"output": "false",
"kind": "execution"
},
{
"from": "read",
"to": "compare",
"output": "value",
"kind": "data",
"input": "value"
},
{
"from": "compare",
"to": "branch",
"output": "result",
"kind": "data",
"input": "test"
}
]
}
}
}Resultado esperado
Com off, o caminho exato é start → branch → read → compare → on → message. Um valor puro é calculado quando a condição em execução precisa dele; por isso o caminho lista branch antes dos valores consultados. As ações são state:on e showMessage. Com on, o caminho termina em off e a única ação é state:off.
Execute a fixture em uma instalação de desenvolvimento
Extraia o pacote de exemplos em data/blueprint-examples, dentro de um checkout descartável da versão documentada. Na raiz do checkout, execute:
uv run --locked python data/blueprint-examples/check-examples.py --host .O verificador configura banco em memória, bloqueia consultas ao banco e chama as funções reais clean_blueprint e evaluate_graph. Ele valida os quatro tipos de objeto, os dois tipos de conexão e os 44 tipos de nó, incluindo requestRoll e setQuestStatus. Confere as duas visibilidades de rolagem, os seis status de missão e a continuação da execução sem rolar dados nem alterar diários. Isso verifica o formato e as ações previstas. Use também Test behavior para conferir alvos reais, autorização e a cadeia completa no servidor.
import json
from pathlib import Path
from gravewright.maps.blueprints import clean_blueprint, evaluate_graph
raw = json.loads(Path("data/blueprint-examples/execution-data.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 result["trace"] == ["start", "branch", "read", "compare", "on", "message"]
assert [a["type"] for a in result["actions"]] == ["state", "showMessage"]Ordem e conexões rejeitadas
Fan-out de execução segue a ordem das conexões em profundidade. Sequence usa then1, then2, then3, then4 nessa ordem. Um descendente compartilhado executa uma vez por evento.
Nós puros de valor não têm portas de execução. Uma conexão de execução para read, ou saindo de read.next, falha na validação.
Cada entrada de dados tem uma fonte. Duas fontes para branch.test falham; uma saída pode alimentar várias entradas compatíveis.
State, boolean, number, text, element e referências de recursos têm tipos. Compare state emite result:boolean: conecte a Test, não a uma entrada de estado.
A saída salva de Element reference ainda se chama door e tem tipo element. Ela também serve a outros elementos compatíveis: não renomeie a porta serializada.
Todas as conexões, até ramos de rascunho desconectados, precisam ser acíclicas. Use sinais/timers pelo runtime suportado para recorrência, sem formar um ciclo de cabos.
Teste como GM e jogador
Use Simulate para inspecionar um evento local. Depois use Test behavior para ensaiar pelo servidor; as alterações desse ensaio são revertidas. Gere ou atualize a cena como GM e teste uma cena sintética com GM e jogador autorizado. Confira que streamer não consegue gravar. Ao editar novamente o projeto, use Update scene antes de esperar mudanças no comportamento da mesa.
Na primeira interação do jogador, o público da mensagem é trigger. Outro jogador na mesma cena não deve receber essa mensagem privada. Confira Automation como GM: valores, decisão booleana e ordem precisam corresponder à simulação. Uma cena com automação pausada não deve executar ações do blueprint.
Erros comuns
Um nó visível sem caminho de execução não executa. Um cabo de dados não inicia uma ação. Simulação correta não prova que um alvo exista na mesa nem que o jogador possa alterá-lo. Ao comparar o estado depois de uma ação anterior no mesmo evento, lembre que Get property lê o retrato inicial.
Como usar a IA para adicionar uma entrada tipada
Estenda execution-data.json para Gravewright 0.3.1 acrescentando uma segunda exigência booleana via getVariable(scope=element, name=ready, valueType=boolean, default=true). Combine-a com o compare existente por all nas entradas a/b. Confira data_inputs/data_outputs e os validadores reais. Mantenha nós puros fora dos cabos de execução, preserve uma fonte por entrada e mostre JSON completo e caminhos para off/on e ready true/false. Não diga que dados executam ações.