Guia de consumo da API

Documentação docs-2026-10-16.3, API 0.1.0, contrato journal-v1. Os exemplos usam regras mission-4860209-v1 e repertório de teste, br-test-v1. A revisão e os hashes de cada pacote ficam em manifest.json, na raiz distribuída. A licença permanece de uso interno do projeto.

Consultar e executar

Consulte a referência em https://docs.gamerspelobrasil.tech/ ou /docs/ na própria API. As chamadas usam https://api.gamerspelobrasil.tech, conforme o servidor anunciado no contrato; baixe o contrato canônico ou leia este guia. A referência não executa operações nem pede credenciais. As 11 operações incluem saúde.

Nas seis operações POST, o exemplo de Origin é https://api.gamerspelobrasil.tech. Clientes curl enviam esse cabeçalho; o navegador o fornece ao executar na origem da API. Usar a origem dos docs nesse cabeçalho retorna 403.

Para consultar o pacote recebido, extraia o arquivo e execute na raiz extraída:

python3 -m http.server 8090 --bind 127.0.0.1 --directory .

Abra http://127.0.0.1:8090/docs/. Também funciona sob um subdiretório HTTP. Não use file://. Consulta requer apenas navegador e servidor estático, sem Go, Node, PostgreSQL ou internet. Esse servidor serve arquivos; as chamadas dos clientes usam a API HTTPS indicada acima ou uma instância local com banco. O pacote não fornece proxy da API.

Executar contra uma API local (opcional)

A partir dos fontes, siga o README do backend (documento no repositório; consulte o responsável pelo backend) para subir a API. Para execução local, use uma origem loopback exata configurada em PUBLIC_ORIGIN e informe --base http://localhost:8080 ao cliente curl. Não alterne localhost e 127.0.0.1. A consulta estática aos docs não inicia chamadas de negócio.

Início rápido com curl

O cliente publicado usa sh, curl e Python 3 (biblioteca padrão). No pacote, entre em docs/examples/; no repositório, entre em backend/api/examples/:

sh curl.sh --base https://api.gamerspelobrasil.tech --scenario manual --probes

Leia curl.sh, seu orquestrador Python e os cenários compartilhados. Mantenha os arquivos no mesmo diretório. O cliente cria sessão, consulta jogador, emite e escolhe uma opção, abre partida, confirma eventos, consulta o terminal, finaliza, consulta ranking e reconsulta identidade/resultado. O resultado impresso contém IDs e dados sintéticos de teste; nenhuma credencial é impressa. Cookie jar temporário tem permissão 600 e é removido ao sair. Cada execução cria outra sessão, pois o jar não é conservado.

O cenário manual elimina um swarm e sai explicitamente: score oficial esperado 550, conforme a versão de regras indicada. --probes também demonstra lacuna, reenvio idêntico e conflito sem acrescentar eventos conflitantes ao diário. Outros cenários: splitter, partial, depleted, projectile, contact, victory. Eles são diários fabricados coerentes; não simulam física nem comprovam antifraude. Tempos são aguardados pelo cliente antes do envio, com relógio monotônico.

Início rápido com fetch

Abra https://api.gamerspelobrasil.tech/docs/ e o console do navegador nessa mesma origem. Importe o módulo e invoque explicitamente:

const client = await import('/docs/examples/fetch.mjs');
const completed = await client.runExample({scenario: 'manual', probes: true});
console.log(completed.result);

O módulo é inerte até a chamada. Usa URLs relativas, credentials: 'same-origin' e timeout; o navegador fornece Origin e cookie HttpOnly. Não defina esses headers manualmente. O domínio docs.gamerspelobrasil.tech serve para consulta e download; importe a cópia servida pela API para executar. Não há CORS nesta versão.

Para consultar após reload, na mesma sessão válida, conserve o run_id devolvido:

const client = await import('/docs/examples/fetch.mjs');
const recovered = await client.recoverRun('SUBSTITUA_PELO_RUN_ID_RECEBIDO');
console.log(recovered.run.result);

Nenhum módulo recupera ações locais perdidas no reload. Se houver partida aberta, o cliente interrompe o início automático: consulte recoverRun() e decida a próxima ação. Uma saída manual posterior é uma nova ação explícita do jogador.

Sessão e nome

Identidade é player_id ligada à sessão; nome de exibição pode repetir e não é credencial. Criação de sessão devolve 201; cookie válido recupera com 200 sem renovar prazo. Nome pode estar ausente. Use as três opções emitidas e confirme seu option_id real; IDs ilustrativos no contrato não são referências utilizáveis. Repetir a mesma escolha é idempotente; outra opção após confirmação conflita. Opções substituídas ou vencidas exigem nova emissão se o nome ainda não foi escolhido. Não há nome livre.

Consulte prazos, cotas e respostas nas respectivas operações do contrato. Sessão expirada cria outra identidade; o nome anterior não recupera a sessão antiga. Repertório e combinações aguardam aceite editorial antes de publicação pública.

Partida, diário e publicação

Conserve run_id, stage_id, rules_version, contract_version, snapshot, last_accepted_seq e a fila de eventos. Snapshot do servidor fornece entidades, alvos e regras adotadas naquela partida. A abertura não aceita score ou nome livre. Apenas uma partida fica aberta por sessão. Nome confirmado é pré-condição.

Cada evento tem seq contíguo a partir de 1 e elapsed_ms não decrescente desde a abertura. Conserve o conteúdo já enviado e remova itens da fila somente após ack do servidor. Um ack não reconstrói o conteúdo de eventos que o cliente perdeu. O lote é atômico: falha não confirma uma parte. Prefixo idêntico pode ser reenviado; mesma sequência com outro conteúdo conflita. Não troque sequência para esconder erro.

Terminal (ready_to_finalize) vem de saída manual, defesa esgotada ou vitória. Consulte confirmação/terminal e envie finish com last_seq confirmado e client_score diagnóstico. Conserve essa entrada para reenvio idêntico. O servidor recalcula score, composição e divergência; published confirma a publicação salva. No ranking, use fase e versão da partida e localize por run_id, pois nomes repetem.

Quando emitir cada evento

Os envelopes e limites completos estão no contrato, na operação de eventos e nos seis schemas Event_*. Pré-condições abaixo são dependentes do diário:

Evento Acontecimento e pré-condições
enemy_eliminated Entidade viva da onda atual eliminada com crédito. Laser não envia target_id. Contato com jogador também pontua; fora da invulnerabilidade exige alvo vivo, durante ela proíbe target_id. Splitter eliminado cria filhos com IDs do pai acrescidos de /c0 e /c1, que só podem ser removidos depois do pai.
enemy_breached Entidade viva invade um alvo vivo: remove sem crédito nem filhos, inclusive splitter. Não confundir invasão com eliminação.
projectile_fired Atirador vivo, respeitando intervalos e capacidade do snapshot/contrato. Identidade do disparo é p/<seq> daquele evento; mantenha-a para o acerto.
projectile_hit Consome um projétil conhecido. Causa target exige alvo vivo. Causa player exige target_id apenas fora da invulnerabilidade lógica; durante ela o campo é proibido. Um projétil já consumido não pode acertar novamente.
wave_advanced Todos os inimigos removidos, incluindo filhos, e intervalo após última remoção cumprido. Transição intermediária gera próxima onda e limpa projéteis; a última produz vitória.
manual_exit Ação explícita que encerra a partida. Payload vazio. Deve ser confirmada antes de finish e também é elegível para publicação. Não fabricar saída como recuperação automática de ações perdidas.

scenarios.json explicita contexto, eventos, tempos, score e motivo esperados. Cada cenário começa em partida nova. contact demonstra contato com e sem invulnerabilidade; projectile espera o primeiro disparo; victory remove filhos antes de avançar ondas. O reducer não recebe integridade ou dano arbitrários do cliente. Fórmulas e autoria ficam nas regras do projeto (documento no repositório; consulte o responsável pelo backend); o contrato e snapshot são a referência disponível também no pacote autocontido.

Falhas e recuperação

Operação/sintoma Ação do consumidor
Nome com resposta perdida Consultar jogador; se confirmado, usar o nome salvo. Se não, repetir a mesma opção enquanto aplicável.
Abertura com resposta perdida Consultar jogador/sessão e open_run_id, depois a partida. Não criar uma segunda partida.
Eventos com timeout ou 503 Resultado da escrita é desconhecido. Consultar partida e reenviar o mesmo conteúdo; ack e reenvio idêntico confirmam estado, sem duplicar efeitos.
Finish com resposta perdida Consultar resultado salvo ou repetir exatamente last_seq e client_score. Não recalcular a entrada do retry.
MISSING_EVENTS Conferir expected_seq, ack e fila conservada; enviar o prefixo ausente. Sem a fila, interromper e informar perda local.
EVENT_CONFLICT / FINISH_CONFLICT Parar automação e diagnosticar conteúdo; não corrigir trocando IDs/seq.
Limite de tentativas Respeitar Retry-After e limitar novas tentativas. Os clientes fazem até três tentativas; também param se a consulta de recuperação falhar.
JSON, mídia ou origem inválidos Corrigir o chamador; retry idêntico não resolve. Mutação curl envia Origin e JSON, sem compressão.
Partida expirada / sessão ausente Não tentar reconstruir identidade pelo nome. Resultado finalizado pode continuar consultável enquanto a sessão for válida.

fetch e curl fazem leitura antes de repetir uma mutação de resultado desconhecido. Emissão de opções pode substituir um conjunto perdido; os clientes só escolhem uma referência devolvida por emissão confirmada. Erros de conflito interrompem o fluxo. Reload conserva o cookie do navegador, mas perde filas e entradas de finish apenas em memória: guarde-as se a aplicação precisar reenviar após reload.

Versões e limites da prova

Compare manifesto, versão da API, journal-v1 e regras do snapshot antes de integrar. Incompatibilidade deve ser comunicada com operação, versão e reprodução sintética, sem cookie ou conexão de banco. Contrato de schema não cobre todas as restrições de estado; os ensaios executam os clientes publicados e conferem PostgreSQL separadamente.

A referência Phaser ainda não envia eventos a esta API. Testes documentais não são aceite do frontend, aprovação editorial, implantação pública ou prova de física.