1

Pitch: Como fiz um júri cego de memes que não dá pra comprar com seguidor (Bradley-Terry, Next.js e Stripe)

Há alguns meses comecei um projeto com uma pergunta simples: dá pra fazer uma competição de humor em que seguidor não ajuda? Em toda rede social, quem tem mais alcance ganha mais curtida, e isso não diz nada sobre quem é engraçado de verdade.

O resultado é o Fame War, um jogo diário de memes. Quero compartilhar as decisões técnicas, porque algumas foram menos óbvias do que eu esperava.

A mecânica

  • Todo dia às 12h (horário de Brasília) sai um tema.
  • Até as 20h, cada pessoa posta um meme (imagem, texto ou vídeo de até 60s).
  • Um júri avalia os memes um por vez, sem nome e sem perfil: 😐, 🔥 ou 🤣.
  • Às 23h sai o ranking nacional e cada um recebe seu percentil (top X%).

Problema 1: transformar "notas" em ranking justo

A média de notas não funciona. Tem jurado que dá 🔥 pra tudo e jurado que só dá 😐, e cada meme é visto por um subconjunto diferente de pessoas.

A solução foi tratar as notas como comparações. Dentro dos votos de cada jurado, um meme com nota maior "vence" os de nota menor (🤣 vence 🔥, que vence 😐). Com isso, quem marca tudo igual não gera comparação nenhuma, então não influencia o resultado, por construção, sem precisar de regra especial.

Essas vitórias alimentam um modelo Bradley-Terry, ajustado pelo algoritmo

P(i vence j) = s_i / (s_i + s_j)

a cada iteração:
s_i ← W_i / Σ_j ( n_ij / (s_i + s_j) )

W_i  = vitórias ponderadas de i
n_ij = comparações entre i e j

Dois detalhes que fizeram diferença:

  1. Prior pequeno: um "empate virtual" contra um meme médio impede que quemu) vá para o infinito.
  2. Duas passadas: na primeira, calculo o consenso. Depois, meço quanto cada jurado concordou com ele e transformo isso num peso (de 0,5 a 1,5). Na segunda passada, o voto de quem
    vota no aleatório pesa menos.

Por que três botões e não dois? Simulei as duas opções: com três níveis, 8 dosem no top 10; com dois, só 5. O 🤣 é o que separa o bom do genial no topo.

Problema 2: fraude

Num jogo com ranking, alguém sempre tenta combinar voto. As defesas que mais a

  • Pares de controle: de vez em quando aparece um "meme" propositalmente ruiado naquele Drop.
  • Voto rápido demais vale zero.
  • Várias contas no mesmo aparelho dividem um único voto.
  • Grupos na mesma rede que empurram o mesmo meme contra o consenso do resto do júri têm os votos anulados e revisados.

Problema 3: moderação de conteúdo gerado por usuário

Toda imagem, texto e quadro de vídeo passa por um modelo de linguagem (Claude Haiku) com saída estruturada antes de entrar no júri.

Uma lição: no começo eu pedia { allow, reason }, e o modelo às vezes recusava por motivos que eu tinha proibido explicitamente no prompt ("a foto não prova que a pessoa cumpriu o desafio"). O que resolveu foi trocar por um enum fechado de categorias. Se, o modelo não consegue recusar por ele. Restringir a saída funcionou melhor do que insistir na instrução.

Problema 4: dinheiro sem virar aposta

Eu queria que as pessoas pudessem ganhar dinheiro sem transformar o jogo em aposta. A regra que adotei: dinheiro nunca compra voto nem chance de vitória. Ele só circula em três lugares:
- Desafios pagos: um fã paga pra alguém fazer um desafio. A cobrança e o re Connect, e o valor fica retido até a prova. Se o fã contesta, um júri cegodecide: o criador ou o fã recebe 70%, a plataforma 20% e os jurados que votaram com a maioria 10%. - Presentes entre usuários.

  • Fundo do Júri: 10% da parte da plataforma é dividido toda semana entre quem julgou, na proporção dos votos úteis (que passaram nos controles).
    Testar isso me deu mais trabalho do que o resto. Tenho uma suíte que confere centavo por centavo cada fluxo: reembolso parcial, estorno, chargeback e semana paga duas vezes. Também tenho testes ponta a ponta que rodam contra produção com contas temporárias apagadas

Stack

  • Next.js 16 (App Router) como PWA, MongoDB Atlas, S3
  • Stripe com Connect
  • Claude Haiku para moderação
  • Resend para e-mail
  • ffmpeg no container, para converter vídeo e gerar automaticamente o vídeo "T
  • Tudo em Docker Compose numa instância EC2, com Caddy na frente

O que eu ainda não resolvi

Partida a frio. Um jogo de júri precisa de gente pra postar e gente pra julgar no mesmo dia. Meu atalho foi:

  • encurtar a janela de postagem;
  • criar contas oficiais identificadas ("Equipe Fame War") que postam memes, ma.

Pensei em bots que se passassem por pessoas e descartei: num lugar com dinheiro real envolvido, isso seria enganar quem joga.
Se você tiver experiência com partida a frio em produto social, ou críticas aoto ouvir.

O projeto está em famewar.com.br/?utm_source=tabnews&utm_medium=community

Carregando publicação patrocinada...
1

hard sign-in é loucura kkk. eu desisti na hora.

acho muito mais interessante deixar o usuário experimentar o jogo primeiro e só depois pedir pra criar uma conta para não perder o progresso. a conversão de visitantes → jogadores provavelmente seria bem maior.

  1. user joga
  2. progride
  3. cadastra pra não perder o progresso
  4. você ganha jogadores e atividade dentro da plataforma
  5. novos jogares visivelmente veem outros jogadores. FOMO aumenta.

isso ainda ajuda no problema do cold-start: quem entra depois já consegue ver que existem outras pessoas jogando ou que jogaram naquele dia.