side_amongus
Modo de jogo · Lua e React
O cliente nunca decide quem morreu, quem tem qual papel, quantos votos alguém recebeu ou quem venceu.
- Lua
- 8.476 linhas
- TypeScript e React
- 3.849 linhas
- Minigames de tarefa
- 10
- Partidas simultâneas
- isoladas entre si
Fonte verificada no repositório interno em 08/09/2026
O que faz
Em uso
Um modo de dedução social completo rodando dentro de um servidor de roleplay: papéis ocultos, dez minigames de tarefa, sabotagens, reunião com votação, modo espectador, câmeras, dutos e recuperação de estado depois de queda de conexão.
A dificuldade não está nas mecânicas — está em rodar isso num ambiente onde o jogador controla o próprio cliente e várias partidas acontecem ao mesmo tempo, no mesmo servidor, sem que uma enxergue a outra.
Evidência
Como o sistema aparece
Capturas da interface real, renderizada com payload de demonstração derivado dos contratos do resource — organizações, cargos, pessoas e identificadores são sintéticos. Onde não existe interface, entra visualização técnica, rotulada como tal.
Interface do sistema Lobby: salas abertas, mapa, lotação e configuração da partida.
Interface do sistema Reunião na fase de votação. Quem morreu aparece riscado — mas quem conta o voto é o servidor.
Interface do sistema Fase de discussão, antes de a votação abrir.
Interface do sistema Escolha de personagem: cor já tomada aparece bloqueada antes do clique — o servidor recusaria de qualquer forma.
Por dentro da engenharia
Decisões de implementação
Um bloco por decisão de implementação. Abra o que interessa.
Servidor autoritativo para o estado da partida
Problema
Num servidor de FiveM, todo evento vindo do cliente está sob controle de quem quer trapacear. Um modo de dedução social é o pior caso possível: quem consegue afirmar "terminei a tarefa" ou "aquele ali morreu" ganha o jogo sem jogar.
Solução
Tudo o que chega do cliente atravessa uma camada única de validação antes de virar estado. Quem morreu, quem tem qual papel, se uma tarefa terminou, quantos votos alguém recebeu e quem venceu são decididos apenas no servidor. O evento do cliente é tratado como pedido, nunca como fato.
Por que foi feito assim
É a regra da própria documentação da plataforma, e é a única premissa que sobrevive a um jogador adversarial. Toda alternativa depende de o jogador escolher não mentir.
Isolamento entre partidas
Problema
Duas partidas rodando ao mesmo tempo no mesmo servidor veriam os jogadores uma da outra — e o restante da cidade veria as duas. Filtrar visibilidade à mão, evento por evento, é a solução que parece funcionar até a primeira que alguém esquece.
Solução
Cada partida recebe um contexto de roteamento próprio, alocado quando ela começa e devolvido quando termina, com a população do mundo desligada lá dentro.
Por que foi feito assim
Isolamento como primitiva do motor vale mais do que isolamento como disciplina do programador: não existe evento novo que esqueça de aplicá-lo.
Limite de frequência por jogador e por ação
Problema
Um limite único por jogador recusa o voto de alguém porque a pessoa acabou de abrir o tablet. O sintoma que chega ao suporte é "o servidor engoliu meu clique" — e a causa é praticamente impossível de rastrear a partir disso.
Solução
A chave do limite é o par jogador e ação. Abrir um painel não consome o orçamento de votar; votar não consome o de interagir.
Por que foi feito assim
O limite existe para impedir inundação de uma ação específica, não para impedir a pessoa de jogar. Quando ele erra o alvo, o custo aparece como bug de jogo e não como defesa funcionando.
Stack
O que foi usado
Servidor
- Lua
- FiveM
- vRP
Interface
- React
- TypeScript
- Vite
Estado
- Contextos de roteamento por partida
- Máquina de estados no servidor
- Recuperação após queda de conexão