FINANÇAS COMPORTAMENTAIS · PSICOLOGIA ECONÔMICA

Pitch: Fiz um futebol de botão online em TypeScript: física determinística, bot sem IA treinada e uma campanha feita só de config

Quem cresceu no Brasil provavelmente jogou futebol de botão na mesa da cozinha. Eu queria esse jogo no celular, online…

Quem cresceu no Brasil provavelmente jogou futebol de botão na mesa da cozinha. Eu queria esse jogo no celular, online e com cartas de poder (Super Chute, Congelamento, Paredão, Bomba de Várzea…). Daí saiu o Peteleco Cards, e aqui conto as decisões técnicas que mais me ensinaram.

A regra de ouro: o app nunca decide o resultado

Monorepo em TypeScript com quatro partes:

  • core: regras, cartas e o simulador de chute em Matter.js. Não importa Phaser nem DOM, então roda igual no navegador e no Node.
  • app: Phaser 3 + Vite (e Capacitor no Android). Só desenha e lê o toque, não roda física.
  • server: Node + Socket.io, rodando o mesmo MatchRunner do core como autoridade. API em Hono, Postgres com Drizzle.
  • admin: painel próprio com métricas, replays e ajustes do jogo.

O app manda uma intenção (“botão 3, nessa direção, com essa força”) e o core devolve uma gravação do chute, quadro a quadro. O Phaser só toca a gravação. Online, isso roda no servidor; contra o computador, o mesmo código roda no navegador.

Física determinística

Para validar partidas e rever replays antigos, o mesmo chute precisa dar sempre o mesmo resultado:

  1. Passo fixo, fora da tela: o chute inteiro é simulado de uma vez em passos de 1/60 s, antes da animação. O FPS do celular não muda nada.
  2. Aleatoriedade só com seed: nada de Math.random na partida.
  3. simulatorVersion: qualquer mudança que altere um resultado incrementa a versão, e cada gravação guarda a sua.

O bônus: numa partida contra o computador, o app manda só a seed, os times e as jogadas. O servidor não confia no placar: joga a partida de novo e só marca como verificada se bater.

A física (quique, freio, peso, força) fica em inteiros numa versão de “ajustes” que o painel publica sem deploy. Cada partida guarda os ajustes com que começou, então o replay não quebra.

Um bot sem rede neural

Não tenho partidas suficientes para treinar nada, então o bot faz o que um bom jogador de botão faz: testa na cabeça antes de chutar. Só que a cabeça dele é o próprio simulador.

  1. Gera ~60 chutes candidatos (botões perto da bola, mirando no gol ou em direções aleatórias, três forças).
  2. Simula cada um com o mesmo simulateShot da partida.
  3. Dá nota: gol, gol contra, bola avançada, rival perto da bola depois.
  4. Testa os melhores de novo com cada carta que pode jogar.
  5. Erra de propósito, conforme o nível (Fácil: 12° de mira e 20% de força; Difícil: 1° e 3%).

O planejamento é dividido em tarefas pequenas para não travar celular fraco.

Desafio do dia que nunca sai impossível

Jogo online com pouca gente tem o problema de você entrar e não ter com quem jogar. O desafio do dia dá um motivo para voltar: todo dia, uma jogada montada, até 5 chutes, ranking por menos chutes.

  • A seed sai de um hash da data, então servidor e admin geram a mesma jogada.
  • Antes de publicar, o próprio bot resolve a jogada sem erro de mira. Se precisa de mais de 3 chutes, descarta; se resolve em 1, descarta por ser fácil demais.
  • O app manda os chutes, não o resultado. O servidor re-simula e só então grava no ranking.

Uma campanha de 48 missões sem código por missão

A Rota do Brasil atravessa o país do Norte ao Sul, e cada vitória libera o time que você venceu. Cada parada é uma linha de config:

{ region: 'nordeste', rival: 'timbu', field: 'gramado', objective: 'gol_com_carta', level: 'medio', card: 'super_chute' }

Cada objetivo vira um MatchSetup que muda o ponto de partida: gol único, começar perdendo de 1 a 0, jogar sem cartas, rival com energia cheia, 90 segundos sem gol de ouro. O MatchRunner nem sabe que existe campanha.

Os campos terrão e molhado não têm simulador próprio: são porcentagens sobre os ajustes de física (terrão: freio da bola a 240%; molhado: 60%). Como o campo entra nos ajustes da partida, o servidor re-simula igual sem nenhuma linha nova de validação.

Testes e deploy

Vitest no core (regras, cartas, simulador, replay, bot, desafio) rodando num hook de pre-push. Vários testes vieram de relatos de testadores, como a bola que atravessava a quina do campo.

Deploy numa VPS pequena com Docker Compose + Caddy, imagens buildadas no GitHub Actions e todos os workflows manuais. Um workflow de teste de carga com robôs jogando partidas reais definiu o teto de salas.

Conclusão

A decisão que mais simplificou tudo foi manter física e regras num core determinístico e compartilhado: online, offline, bot, replay, validação, desafio do dia e campos da campanha são o mesmo simulador usado de jeitos diferentes.

Dá para jogar de graça no navegador: https://petelecocards.com.br

Se jogar, me conta qual carta mais usou ou o que te fez perder para o computador no Difícil. Críticas técnicas também são muito bem-vindas.

Perguntas frequentes

Respostas institucionais sobre esta cobertura, fontes e limites editoriais.

Sobre o que trata “Pitch: Fiz um futebol de botão online em TypeScript: física…”?
Quem cresceu no Brasil provavelmente jogou futebol de botão na mesa da cozinha. Eu queria esse jogo no celular, online e com cartas de poder (Super Chute, Congelamento, Paredão, Bomba de Várzea...). Daí saiu o Peteleco…
O que a matéria explica sobre “A regra de ouro: o app nunca decide o resultado”?
Monorepo em TypeScript com quatro partes:core: regras, cartas e o simulador de chute em Matter.js. Não importa Phaser nem DOM, então roda igual no navegador e no Node.app: Phaser 3 + Vite (e Capacitor no Android). Só desenha e lê o toque,…
O que a matéria explica sobre “Física determinística”?
Para validar partidas e rever replays antigos, o mesmo chute precisa dar sempre o mesmo resultado:Passo fixo, fora da tela: o chute inteiro é simulado de uma vez em passos de 1/60 s, antes da animação. O FPS do celular não muda…
O que a matéria explica sobre “Um bot sem rede neural”?
Não tenho partidas suficientes para treinar nada, então o bot faz o que um bom jogador de botão faz: testa na cabeça antes de chutar. Só que a cabeça dele é o próprio simulador.Gera ~60 chutes candidatos (botões perto da bola, mirando…
O que a matéria explica sobre “Desafio do dia que nunca sai impossível”?
Jogo online com pouca gente tem o problema de você entrar e não ter com quem jogar. O desafio do dia dá um motivo para voltar: todo dia, uma jogada montada, até 5 chutes, ranking por menos chutes.A seed sai de um…
Quem edita o conteúdo do Estrato Mente?
A cobertura é produzida e revisada pela equipe editorial do Estrato Mente, com editor-chefe responsável pela linha editorial. Conheça a redação em https://mente.estrato.cc/equipe/.
Quais fontes o Estrato prioriza?
Priorizamos fontes primárias (órgãos oficiais, balanços, estudos revisados, documentos públicos) e cruzamos informações antes da publicação, conforme a política editorial.
Como solicitar correção de uma matéria?
Envie o pedido pela página de Correções (https://mente.estrato.cc/correcoes/) ou Contato (https://mente.estrato.cc/contato/). Erros materiais são corrigidos com registro da atualização.
WhatsApp X LinkedIn
Compartilhar: LinkedIn
Bruno Leite

Bruno Leite

Bruno Leite integra a equipe editorial do Estrato Mente, vertical da rede Estrato, na função de Repórter de Aprendizado. O escopo permanente de cobertura inclui estudo, memória e foco, com atenção ao leitor brasileiro que busca contexto factual, datas oficiais e implicações práticas. Na produção diária, prioriza fontes primárias (órgãos públicos, balanços, papers e documentos oficiais), cruza pelo menos duas referências independentes quando o tema é contestado e evita manchetes que prometam certeza onde há incerteza. Critérios de qualidade: lead com o fato principal, atribuição clara de autoria da equipe Estrato, atualização com selo quando há mudança material e linguagem acessível sem simplificar demais o risco ou o contexto. Trabalha sob revisão da mesa editorial e do editor-chefe do portal. Matérias YMYL recebem segunda leitura antes da publicação e podem ser atualizadas quando surgem novos dados oficiais. Limites: este perfil descreve o papel editorial na marca Estrato. O conteúdo publicado é informativo e não constitui aconselhamento médico, financeiro, jurídico ou profissional personalizado. Transparência ao leitor: metodologia em /metodologia/, ética em /etica-editorial/, correções em /correcoes/, equipe em /equipe/ e canal em /contato/ ([email protected]). Na página-mãe da rede, a bio ampliada e o arquivo de matérias ficam em estrato.cc/blog/, com link para o arquivo do autor em cada portal.

Deixe um comentário