Protocolo de depuração

Esta página foi traduzida automaticamente e pode conter erros. Encontrou um problema? Use o link "Edit this page" para ajudar a corrigir.

O Protocolo de Depuração Remota (Remote Debug Protocol) é um servidor JSON-RPC 2.0 leve embutido em todo build de jogo Turian que vincula o módulo debug. Ele expõe a Camada de Introspecção em Runtime via TCP para que ferramentas externas — a CLI, o servidor MCP e scripts personalizados — possam consultar e (opcionalmente) modificar o estado ativo do engine.


Formato de transmissão

Um objeto JSON por linha (terminado em \n). Sem cabeçalhos Content-Length.

Requisição:

{"jsonrpc":"2.0","id":1,"method":"entity.inspect","params":{"name":"Player"}}

Resposta de sucesso:

{"jsonrpc":"2.0","id":1,"result":{...}}

Resposta de erro:

{"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"Entity not found"}}

Métodos

Cena

Método Parâmetros Descrição
scene.list Todas as cenas carregadas
scene.inspect name? Entidades em uma cena (cena ativa se omitido)

Entidade

Método Parâmetros Descrição
entity.find name?, component? Filtra entidades por nome ou tipo de componente
entity.inspect name ou index Detalhes de Transform + componentes

Componente

Método Parâmetros Descrição
component.get entity, component Valores dos campos do componente

Assets

Método Parâmetros Descrição
asset.list Todos os assets do projeto (guid, path, type)
asset.inspect guid guid / path / type de um asset específico

Diagnósticos

Método Parâmetros Descrição
snapshot Snapshot completo da cena (todas as entidades + métricas)
schema Catálogo de tipos de componentes nativos
metrics Contadores de desempenho de runtime
profiler.capture Frame mais recente do profiler (contadores + zonas)
memory memory_bytes + allocation_count
errors Entradas recentes de warn/err de std.log (as mais recentes primeiro)
ping Teste de funcionamento (health check); retorna "pong"
auth token Autenticar (necessário quando o servidor possui um token configurado)

Mutações (apenas no modo de leitura-escrita)

Métodos de mutação retornam { "ok": bool, "message": string }. Eles requerem que o servidor tenha sido iniciado no modo de leitura-escrita (allow_write / CLI --rw); caso contrário, retornam READONLY. No Studio, toda mutação é roteada pela pilha de desfazer (undo stack) do editor, de modo que edições por IA/CLI podem ser desfeitas e são consistentes com a UI.

Método Parâmetros Descrição
component.set entity, component, field, value Define um campo de componente
transform.set entity, channel, value ([x,y,z]) Define posição/rotação/escala
entity.spawn name Cria uma nova entidade vazia
entity.destroy entity Remove uma entidade
asset.reload guid Executa o hot-reload de um asset

Sessões e eventos

Método Parâmetros Descrição
session.readonly Descarta os direitos de escrita desta conexão (não é possível reatribuir)
subscribe event (ou "*") Inscreve-se em eventos de runtime
unsubscribe event (ou "*") Cancela o recebimento de um evento

Clientes inscritos recebem notificações JSON-RPC (sem id) à medida que os eventos são disparados:

Evento Quando
entity.created Uma entidade foi criada
entity.destroyed Uma entidade foi removida
scene.loaded Uma cena se tornou ativa / concluiu o carregamento
scene.unloaded Uma cena foi descarregada
resource.reloaded Um asset sofreu hot-reload
fps.changed O valor inteiro da faixa de FPS (FPS bucket) mudou

No Turian Studio, scene.loaded / scene.unloaded são disparados conforme você abre, altera ou fecha as abas de cenas, e fps.changed é derivado do tempo de frame do próprio editor — portanto ele oscila enquanto você edita, e não apenas no modo Play.


Códigos de erro

Código Nome Significado
-32700 PARSE_ERROR JSON inválido
-32600 INVALID_REQUEST Campos obrigatórios ausentes
-32601 METHOD_NOT_FOUND Método desconhecido
-32602 INVALID_PARAMS Parâmetros ausentes ou incorretos
-32603 INTERNAL_ERROR Erro de serialização ou falha interna
-32000 NOT_FOUND Entidade/cena/componente não encontrado
-32001 READONLY Tentativa de mutação em uma sessão somente leitura
-32002 RATE_LIMITED Limite de requisições por conexão excedido (rate limit)

Iniciando o servidor de depuração

const debug = @import("debug");

var srv = debug.Server.init(allocator, .{
    .port = 7777,
    .localhost_only = true,
    .auth_token = "",            // vazio = sem autenticação
    .allow_write = false,        // true para permitir mutações/escrita
    .max_clients = 8,
    .rate_limit_per_sec = 0,     // 0 = ilimitado
    .max_outbound_queue = 2048,  // limite de backlog de eventos por cliente
    .max_outbound_bytes = 16 << 20,
    .max_inbound_queue = 4096,   // requisições pendentes entre todos os clientes
});
defer srv.deinit(io);
try srv.start(io);          // apenas gera o loop de aceite (accept loop)

// Uma vez por frame, na thread principal:
srv.pump(world, applier);   // executa leituras/escritas enfileiradas contra o estado ativo

O loop de aceite (accept loop) roda em uma thread de segundo plano, mas cada requisição é executada na thread principal dentro de pump — assim, as leituras são livres de condições de corrida (race-free) e as escritas podem modificar o estado ativo do engine sem bloqueios (locking). Múltiplos clientes são suportados simultaneamente. As mutações são aplicadas por meio de um MutationApplier fornecido pelo host; os eventos são emitidos com srv.emit(...). Chame srv.stop(io) para desligar de forma limpa.

Respostas grandes e contrapressão (backpressure)

Um snapshot completo de uma cena grande é serializado bem além de 64 KiB. As mensagens são delimitadas por quebras de linha, mas não são limitadas a 64 KiB — tanto o cliente quanto o servidor aumentam o buffer de leitura na heap até um teto máximo de 16 MiB, de modo que respostas grandes chegam intactas em vez de falharem.

A fila de eventos de saída de cada conexão é delimitada (max_outbound_queue / max_outbound_bytes). Um assinante que parar de ler terá seus eventos mais antigos descartados (eventos são passíveis de perda por natureza) em vez de aumentar a memória do servidor sem limites; um cliente que ficar muito atrasado para receber uma resposta pendente será desconectado. A fila de entrada compartilhada é delimitada por max_inbound_queue; uma vez cheia, novas requisições são rejeitadas com um erro claro de "servidor ocupado".

Exposição de rede. Definir localhost_only = false vincula a porta a 0.0.0.0 e não há TLS — o auth_token (e todo o tráfego) é enviado de forma aberta (em texto limpo) e é a única barreira de proteção. Use isso apenas em uma rede LAN confiável por trás de um firewall/VPN; nunca exponha o servidor de depuração à internet pública.


Utilizando a partir do turian-cli

turian-cli debug connect
turian-cli debug scenes
turian-cli debug inspect Player
turian-cli debug snapshot
turian-cli debug schema
turian-cli debug metrics
turian-cli debug assets
turian-cli debug errors
# mutações (o servidor precisa estar em modo leitura-escrita):
turian-cli debug set Player Light intensity 2.5
turian-cli debug spawn Crate
turian-cli debug destroy Crate
# eventos e sessões:
turian-cli debug watch entity.created fps.changed
turian-cli debug record session.jsonl
turian-cli debug replay session.jsonl

Consulte turian-cli debug --help para ver a lista completa de subcomandos.


Porta padrão

7777. Substitua por --port tanto no servidor quanto no cliente.


← Toda a documentação Editar esta página