Estudo de caso
MovieTQ
Um jogo de navegador multijogador em tempo real em que os jogadores disputam para dizer o nome dos filmes primeiro. Crie ou entre em salas, jogue em vários modos de jogo, dispute nos rankings e mantenha sua progressão com contas, conquistas, moeda do jogo e cosméticos.
Dois modos no ar
Bomb-It
Os jogadores se revezam para dizer o nome de um filme que combine com a dica antes que o cronômetro da bomba acabe. Errou, perde uma vida — vence o último a ficar de pé.
Trailer Quiz
Um trailer é exibido e todos disputam para dizer o nome do filme antes que o cronômetro da rodada termine. A resposta e os pontos chegam juntos no apito final.
Hoje há dois modos no ar, com mais a caminho.
Por dentro do jogo
Multijogador em tempo real
Salas com autoridade no servidor mantêm cada jogador no mesmo frame, sincronizados em menos de um segundo. O servidor decide; os clientes apenas renderizam.
Progressão persistente
Contas, níveis e XP que acompanham as pontuações das partidas — além de rankings globais e conquistas concedidas automaticamente conforme você joga.
Uma economia dentro do jogo
Ganhe Popcorn jogando e gaste em uma loja de cosméticos — avatares, títulos, planos de fundo — com pacotes opcionais e níveis de assinatura via Stripe.
Moderação embutida
Um console de administração com logs de sistema auditados, denúncias de jogadores e de trailers e as ferramentas habituais de banimento, silenciamento e bloqueio mantêm as salas civilizadas.
Por dentro
Em linguagem simples por padrão — mude para o detalhe de engenharia.
Um loop de jogo com autoridade no servidor
O servidor roda a partida inteira como uma máquina de estados em uma batida de um segundo, então pontuação e tempo não podem ser falsificados por um cliente.
Uma máquina LOBBY → STARTING → IN_ROUND → BETWEEN_ROUNDS → FINISHED avança a cada batida de um setInterval; toda requisição percorre primeiro uma cadeia ordenada de middlewares do Express — CORS, CSRF, rate-limit, validação, autenticação.
Sincronização em tempo real
Todos em uma sala veem o mesmo trailer no mesmo instante; o servidor é a única fonte da verdade.
A presença na sala é rastreada no servidor e toda ação do jogador é validada por um cliente service-role do Supabase que fica acima do row-level security — o estado do cliente é descartado.
Trailers sem a conta de banda
Os trailers são transmitidos direto da CDN do YouTube, e o player é recortado para esconder seus controles sem violar as regras do YouTube.
O embed é renderizado dentro de um wrapper escalado e com overflow recortado — um recorte por bounding box — para que permaneça tecnicamente visível; vídeos quebrados são detectados pelos códigos de erro do embed (100/101/150) e instantaneamente trocados por um reserva.
Contas, economia e pagamentos
Os perfis preservam níveis, moeda e cosméticos, e o Stripe cuida dos pacotes e das assinaturas.
Excluir ou banir um usuário se propaga em cascata por partidas, inventário e conquistas; os níveis de assinatura ficam em um pacote compartilhado como única fonte da verdade, e uma API de estatísticas de administração informa os custos operacionais ao vivo.
Uma única base de código em TypeScript
Frontend, backend e tipos compartilhados ficam em um único repositório, tipados de ponta a ponta.
React + Vite no front, Node 22 + Express no back, Supabase (PostgreSQL) para os dados; o TypeScript do servidor compila para JavaScript ao lado em tempo de build.
A camada social
Construído com
- TypeScript
- React
- Vite
- Node.js
- Express
- Supabase
- PostgreSQL
- Stripe
Toda a stack, construída internamente
Frontend, backend, banco de dados, multijogador em tempo real, contas e pagamentos — projetados, construídos e operados de ponta a ponta.