Arquitetura de software · parte 6 de 6
MMORPG: arquitetura para 1 milhão de jogadores simultâneos
Como projetar um MMORPG para 1 milhão de jogadores simultâneos na AWS: rede UDP, partição espacial, combate autoritativo, economia e tolerância a falhas.
avançadoPublicada em · 35 min de leitura
Esta nota é uma aula profunda sobre engenharia de software e infraestrutura para jogos online massivos. O objetivo é que, ao terminar esta leitura, você seja capaz de projetar do zero a arquitetura completa de um jogo MMORPG capaz de suportar 1 milhão de jogadores simultâneos (1M ) na nuvem da AWS, compreendendo as limitações físicas de rede, algoritmos de partição espacial, modelos de concorrência de física, integridade econômica e tolerância a desastres.
Os conceitos são ilustrados com arquiteturas consagradas da indústria como World of Warcraft, EVE Online, Guild Wars 2 e New World. Todas as figuras foram geradas e renderizadas pelo ArchFlow (veja MCP), com fontes em diagramas vetoriais na pasta de assets. Os dados técnicos de serviços da AWS refletem a documentação oficial consultada em outubro de 2026.
Mapa da aula
| Parte | Seções | Pergunta que responde |
|---|---|---|
| 1. Fundamentos e a escala brutal | 1 a 3 | O que torna um MMORPG o desafio mais difícil da computação distribuída? |
| 2. Física, e transporte | 4 a 6 | Como sincronizar o movimento de 1 milhão de pessoas sem virar um show de slides? |
| 3. Divisão de mundo e espaço | 7 a 9 | Como fatiar um mundo contínuo entre servidores sem telas de carregamento? |
| 4. Economia, dados e integridade | 10 a 12 | Como impedir duping de itens e colapsos de estoque em bancos de dados? |
| 5. Serviços sociais e metagame | 13 a 15 | Como gerenciar chat global, leilões web e moderação sem poluir a simulação? |
| 6. Telemetria, segurança e custos | 16 a 18 | Como barrar cheats em tempo real e sobreviver à conta de rede da AWS? |
| 7. Alta disponibilidade e prática | 19 a 22 | O que fazer quando um nó explode, exercícios práticos e glossário técnico |
Parte 1: Fundamentos e a escala brutal
1. O que é um MMORPG para a computação
Se você perguntar a um jogador o que é um MMORPG, ele falará sobre espadas brilhantes, dragões e guildas. Se você perguntar a um engenheiro de sistemas distribuídos, a resposta será um pesadelo: trata-se de um sistema distribuído em tempo real, com estado mantido em memória, no qual dezenas de milhares de clientes com conexões instáveis tentam alterar simultaneamente as mesmas variáveis compartilhadas em frequências de 30 a 60 vezes por segundo.
Em sistemas web corporativos convencionais, quando o tráfego atinge 1 milhão de requisições por segundo, a receita tradicional é empilhar nós sem estado (stateless) atrás de balanceadores de carga, colocar um cache na frente do banco e abrir uma garrafa de café. No mundo dos MMORPGs de ação, esse modelo simplesmente não funciona. A posição do seu avatar depende da posição do monstro, que depende da magia de atordoamento lançada por outro jogador 50 milissegundos atrás. Não dá para colocar a posição de combate de 1 milhão de entidades em um banco de dados relacional e fazer SELECT com lock pessimista 30 vezes por segundo.
O estado do mundo precisa viver na memória volátil da CPU. A física de colisão precisa rodar sem travas externas. E cada decisão precisa chegar a todos os espectadores interessados antes que o cérebro humano perceba um atraso maior que 100 milissegundos.
A figura acima resume a espinha dorsal de um MMORPG moderno operando na AWS para 1 milhão de jogadores simultâneos. Observe a separação fundamental entre duas grandes metades:
- A camada de tempo real (Stateful): os jogadores de PC e console conectam via pacotes UDP diretos através do AWS Global Accelerator para eliminar saltos na internet pública. Os pacotes chegam aos clusters de borda (Edge Gateways), que terminam a encriptação e entregam os dados limpos para os nós de simulação de mundo (World Nodes) rodando em instâncias de computação pesada C7g na AWS.
- A camada de metagame (Stateless): login, serviços de chat, correio, leilão e dados persistentes rodam em containers gerenciados (ECS e EKS), conversando com microsserviços via gRPC interno e persistindo dados críticos em Amazon DynamoDB, Aurora e filas Amazon SQS.
2. A matemática de 1 milhão de jogadores simultâneos (1M CCU)
Para projetar a infraestrutura de suporte, precisamos traduzir 1 milhão de usuários conectados em grandezas de engenharia de redes e sistemas operacionais. Suponha que seu jogo rode a um tick rate moderado de 30 Hz (30 ciclos de simulação por segundo):
- Taxa de pacotes de entrada: se 1.000.000 de clientes enviam dados de controle (teclado, mouse, analógicos) a cada tick de 33,3 milissegundos, seus gateways de rede receberão exatamente 30.000.000 de pacotes por segundo (PPS). Para efeito de comparação, uma porta de rede gigabit comum engasga com menos de 1,5 milhão de pacotes pequenos por segundo devido a overheads de interrupções de hardware (softIRQs).
- Taxa de pacotes de saída: se o servidor precisa atualizar cada cliente com o estado dos objetos ao redor com uma média enxuta de 40 KB/s de dados compactados, a saída agregada de rede será de 40 Gigabytes por segundo, o equivalente a 320 Gigabits por segundo (Gbps) sustentados saindo dos data centers da AWS.
- Custo de saída de dados (Data Transfer Out): na AWS, 1 GB transferido para a internet custa entre 0,05 e 0,09 dólares dependendo do volume. 40 GB/s sustentados ao longo de 30 dias representam cerca de 103 Petabytes de dados transferidos por mês. Uma implementação ingênua sem compactação de bits pode gerar uma fatura de rede de centenas de milhares de dólares antes mesmo do fim do primeiro mês de operação.
A primeira lição do arquiteto de jogos é que economia de bits é sobrevivência financeira. Não há JSON, XML ou texto plano no loop de simulação de um jogo desse porte; cada coordenada, velocidade e ângulo de rotação é compactado em nível de bit.
3. O problema fundamental: a explosão quadrática O(N²)
Existe uma razão matemática pela qual você nunca vê 1 milhão de jogadores correndo juntos no mesmo metro quadrado do mapa: o problema do broadcast de visibilidade.
Imagine uma praça de uma capital virtual onde $N$ jogadores decidem se encontrar para comemorar o abate de um chefe de invasão. Se cada jogador se move, o servidor precisa avisar esse movimento para todos os outros presentes. O número de mensagens que o servidor precisa gerar e despachar a cada tick segue a fórmula de combinações de pares:
$$M = N \times (N - 1)$$
Se temos 10 jogadores na sala, o servidor gera $10 \times 9 = 90$ mensagens por tick. A 30 ticks por segundo, são 2.700 mensagens por segundo, algo trivial. Se reunirmos 2.000 jogadores na mesma batalha campal, a fórmula produz:
$$M = 2.000 \times 1.999 = 3.998.000 \text{ mensagens por tick}$$
A 30 ticks por segundo, isso equivale a quase 120 milhões de mensagens por segundo concentradas em uma única máquina. Nenhuma CPU comercial existente no planeta consegue processar essa carga em um único loop de thread.
O gráfico acima ilustra essa catástrofe assintótica. A curva vermelha mostra o crescimento quadrático $O(N^2)$ do broadcast ingênuo. A linha tracejada em 50.000 mensagens por tick marca a capacidade de saturação de um nó moderno de simulação. Com apenas 224 jogadores agrupados no mesmo ponto, o servidor cruza o limiar crítico e entra na zona de congelamento permanente, acumulando atraso em cascata.
A curva verde representa a salvação arquitetural: a introdução de particionamento espacial com filtragem por raio de interesse (Area of Interest, ou ). Em vez de ouvir o mundo inteiro, o cliente só recebe dados dos $K$ vizinhos mais relevantes ou mais próximos espacialmente. O custo por jogador passa a ser limitado a uma constante $K$, transformando a complexidade global em $O(N)$. Com AoI e estruturas espaciais em grade (Quadtrees), 2.000 jogadores podem coexistir no mundo sem que a máquina derreta.
Parte 2: Física, tick rate e transporte
4. O orçamento estrito do tick loop
O coração de um servidor de simulação de jogo é um laço infinito executado em cadência fixa. Chamamos cada iteração desse laço de “tick”. Em um servidor calibrado para 30 Hz, o tempo total concedido à CPU para realizar todos os cálculos de um ciclo é rigorosamente:
$$T_{\text{budget}} = \frac{1000 \text{ ms}}{30} \approx 33,33 \text{ ms}$$
Em jogos de tiro ou combate em tempo real com esquiva de alta precisão (como New World ou Albion Online), muitos servidores rodam a 50 Hz ou 60 Hz, reduzindo essa janela para míseros 16,6 milissegundos.
Durante essa janela temporal, o servidor não pode se dar ao luxo de fazer chamadas bloqueantes de rede ou disco. Todo o trabalho deve caber com folga no orçamento.
A figura acima detalha a fatia de tempo consumida por cada etapa interna de um tick em um servidor com cerca de 2.500 entidades ativas em memória:
- Ingestão de inputs (3 ms): o servidor esvazia os buffers de rede do sistema operacional, descompacta os comandos recebidos e enfileira as intenções dos jogadores.
- Simulação de física e colisões (12 ms): é a etapa mais pesada da rotina. O motor precisa mover os corpos no espaço tridimensional, validar superfícies navegáveis (navmeshes) e checar se ataques em arco atingiram alvos válidos.
- Combate e inteligência artificial (8 ms): cálculos de buffs, debuffs, redução de dano por armadura, processamento da árvore de comportamento dos monstros (NPCs) e verificação de condições de morte.
- Consulta espacial de interesse (5 ms): atualização da Quadtree e cálculo das listas de visibilidade para saber quem deve enxergar quem.
- Serialização delta e despacho (4 ms): montagem dos pacotes binários contendo apenas as variações em relação ao tick anterior e envio assíncrono para os sockets de rede.
Somando essas etapas, chegamos a 32 milissegundos de trabalho em um cenário de pico. Isso nos deixa com uma margem de segurança de apenas 1,33 milissegundo antes de estourar o limite de 33,33 ms. Se o tempo de execução ultrapassar o orçamento, o servidor é obrigado a adiar a simulação do próximo tick. Quando isso acontece de forma recorrente, os relógios do cliente e do servidor se dessincronizam, e os jogadores começam a testemunhar o temido efeito de teletransporte (rubberbanding).
5. Por que TCP não serve: a anatomia da camada UDP
Uma dúvida comum entre desenvolvedores de aplicações corporativas é: por que os jogos não usam WebSockets ou TCP puro para a movimentação em tempo real? Afinal, o TCP já entrega ordenação garantida e tratamento de perda.
A resposta está em um mecanismo intrínseco do TCP chamado bloqueio de cabeça de fila (). O protocolo TCP foi desenhado sob a premissa de que a integridade de um fluxo contínuo de bytes é mais importante do que a sua contemporaneidade. Se um pacote com a posição do seu avatar no tick 100 for descartado por um roteador congestionado, a pilha de rede do sistema operacional reterá em buffer os pacotes dos ticks 101, 102 e 103 até que o pacote 100 seja retransmitido com sucesso.
Para um jogo em tempo real, isso é letal. A informação de que você estava na coordenada X no tick 100 perde todo o valor quando o relógio já atingiu o tick 104. O que o cliente precisa é da coordenada mais recente agora, e não da coordenada velha com 200 milissegundos de atraso.
Para contornar essa barreira, todos os grandes MMORPGs implementam protocolos proprietários ou bibliotecas consolidadas (como RakNet, KCP, ENet ou WebTransport) operando diretamente sobre datagramas UDP.
Conforme demonstrado no diagrama acima, o tráfego UDP do jogo é fatiado internamente em canais lógicos:
- Canal não confiável sequenciado (Unreliable Sequenced): utilizado para dados contínuos e efêmeros, como vetores de movimento, aceleração e rotação de câmera. Se o pacote 3 se perder no caminho, o cliente simplesmente o descarta quando o pacote 4 chegar, aplicando o delta mais novo sem qualquer interrupção.
- Canal confiável ordenado (Reliable Ordered): reservado para transações de alta relevância que não podem desaparecer, como a conjuração de uma magia, a abertura de um baú ou o recebimento de dano crítico. Esse canal implementa um sistema enxuto de confirmação seletiva (ACK) e retransmissão de janela deslizante sem travar o processamento dos dados de movimento.
6. O combate autoritativo: predição, reconciliação e
Se o servidor dependesse de receber a confirmação de cada botão pressionado para só então exibir o resultado na tela do jogador, o jogo pareceria incrivelmente travado. Se você clica para andar e precisa esperar 80 milissegundos de ida e volta para ver o personagem dar o primeiro passo, a experiência fica pesada.
Para resolver isso, os jogos usam um trio de algoritmos: autoridade estrita do servidor, predição no cliente e compensação de lag.
- Autoridade estrita: o cliente nunca decide se causou dano, se pegou um item ou se desviou de um golpe. O cliente apenas envia sua intenção (“pressioneionei a tecla de ataque no timestamp T com vetor de mira V”). O servidor executa a simulação canônica e dita o que realmente ocorreu.
- Predição do cliente (): quando você pressiona a tecla de movimento para frente, o seu cliente local imediatamente move o avatar e dispara a animação sem aguardar a resposta da rede. Ele anota esse movimento em uma fila local vinculada ao identificador do tick.
- Reconciliação do servidor (): quando a confirmação do servidor chega, o cliente compara a sua coordenada prevista com a coordenada autoritativa validada pelo servidor. Se houver divergência (porque outro jogador empurrou seu personagem no mesmo instante), o cliente descarta a previsão errada e corrige a posição do avatar suavemente via interpolação.
A figura acima ilustra a técnica de compensação de lag (Lag Compensation / Server Rewind) durante um ataque. Quando o jogador A com ping de 70 ms desfere um golpe no tick 100, esse pacote só alcança o servidor no tick 104. No tick 104, o inimigo B já se moveu para outro local.
Se o servidor validasse a hitbox no tick atual (104), o golpe acertaria o ar vazio, criando a frustração de atirar em alguém e o tiro atravessar o corpo. Para corrigir isso com justiça, o nó do mundo mantém um buffer circular com o histórico de posições dos últimos 1.000 milissegundos. Ao processar o comando com carimbo T100, o servidor rebobina o relógio das entidades, verifica se no tick 100 a vítima estava dentro do raio de alcance do golpe e aplica o dano com precisão histórica.
Parte 3: Divisão de mundo e espaço
7. Modelos de partição: instâncias, zoneamento e mundo contínuo
Dividir 1 milhão de jogadores exige escolher como o espaço geográfico do jogo é mapeado na infraestrutura de servidores da nuvem. Historicamente, a indústria explorou três abordagens:
- Zoneamento estático com telas de loading: o mapa é recortado em províncias fixas. Cada província roda em um processo dedicado. Cruzar de uma floresta para uma montanha exige atravessar um portal e esperar uma barra de carregamento carregar os assets. Essa era a abordagem clássica de jogos como EverQuest e as primeiras versões de World of Warcraft.
- Instanciamento e sharding dinâmico: o mundo físico é duplicado em cópias idênticas chamadas instâncias ou shards. Se 10.000 pessoas viajam para a mesma cidade, o cluster cria automaticamente 5 cópias da cidade com 2.000 pessoas cada, agrupando membros do mesmo grupo ou guilda no mesmo shard. World of Warcraft adotou camadas dinâmicas (layering) a partir de expansões modernas.
- Particionamento espacial contínuo (Seamless World): o objetivo supremo do design de jogos. O mundo é um continente gigantesco e ininterrupto, sem nenhuma tela de loading. Múltiplos nós de computação na nuvem cuidam de diferentes quadrantes geográficos, e as entidades transitam entre servidores de forma completamente invisível para o usuário. Essa é a arquitetura adotada em New World e em tecnologias modernas de computação espacial.
8. A fronteira invisível e o
Fazer um jogador cruzar a fronteira de um servidor para outro sem que o jogo congele ou desconecte é um dos problemas mais sofisticados da computação distribuída.
Se o nó A cuida do território de latitude 0 a 100 e o nó B cuida de 100 a 200, o que acontece quando dois jogadores lutam exatamente na coordenada 99,9? O jogador A está sob a autoridade da máquina A, mas sua espada atinge o jogador B que está na máquina B.
A solução padrão é criar uma margem de replicação (Replication Margin ou Ghost Zone) ao longo de todas as bordas territoriais.
Conforme detalhado no diagrama acima, o processo de migração ininterrupta (Seamless Handoff) funciona em cinco etapas coordenadas:
- Entrada na margem de replicação: quando o jogador atinge 50 metros de distância da fronteira do setor Norte, o nó A detecta a proximidade e avisa o nó B através de um link interno de altíssima velocidade via VPC Peering da AWS.
- Criação da entidade fantasma (): o nó B instancia em sua memória local uma cópia espelho (ghost) do jogador, alimentada pelos dados replicados do nó A a cada tick. O nó B já passa a simular as colisões locais preventivamente.
- Notificação do coordenador espacial: o nó A registra a transição iminente no Amazon MemoryDB / Redis, que atua como o registro autoritativo de leases espaciais.
- Troca atômica de custódia (Authority Handover): quando o avatar cruza a linha matemática divisória, o nó B promove a entidade fantasma a mestre autoritativo. O nó B notifica o gateway de borda UDP para que os novos inputs do cliente sejam redirecionados imediatamente para o seu socket.
- Limpeza de rastros: o nó A transforma o seu antigo mestre em um fantasma temporário e, após alguns segundos de afastamento, remove a entidade da sua memória de trabalho. O jogador não experimentou um único quadro de travamento.
9. O caso extremo: a dilatação temporal de EVE Online
Nenhum estudo sobre arquitetura de MMORPGs é completo sem examinar o caso extremo do jogo espacial EVE Online. Diferente da maioria dos jogos que fragmenta os jogadores em instâncias separadas quando há superlotação, EVE Online opera em um universo único e compartilhado (Single-Shard Universe).
Quando duas frotas rivais de corporações decidem declarar guerra pelo controle de um sistema estelar estratégico, até 6.000 jogadores reais com suas respectivas naves, drones e mísseis saltam para o mesmo setor solar, gerenciado por um único nó de processamento bare-metal.
Com 6.000 entidades atirando mísseis e calculando rotas orbitais simultaneamente, a complexidade computacional explode muito além do orçamento de 1 segundo de tick do jogo. Em vez de permitir que o servidor caísse por estouro de memória ou descartasse pacotes aleatoriamente, a equipe de engenharia da CCP Games inventou o mecanismo de dilatação temporal (Time Dilation, ou TiDi).
Quando a fila de simulação de um nó ultrapassa o limite seguro de processamento, o servidor reduz deliberadamente a velocidade do tempo físico dentro daquele sistema específico para até 10% da velocidade normal (1 segundo no jogo passa a levar 10 segundos no relógio da vida real). Os clientes recebem a instrução e desaceleram a física local em sincronia. A batalha parece correr em câmera lenta extrema, mas nenhum comando de tiro é perdido e o servidor mantém a integridade matemática da física sem sofrer um crash catastrófico.
Parte 4: Economia, dados e integridade
10. O pesadelo do e o modelo de transação
Em um jogo multiplayer massivo, a economia interna é tão delicada quanto o sistema bancário de um país. Se um grupo de jogadores descobre uma falha de duplicação de itens (dupe exploit), eles podem gerar bilhões de moedas do nada, quebrar o mercado de leilões e forçar os desenvolvedores a tomar a decisão drástica de executar um rollback geral do servidor, apagando o progresso legítimo de toda a comunidade.
O bug clássico de duplicação ocorre quase sempre pela desconexão descoordenada entre a memória de jogo e o banco de dados persistente. Considere o cenário ingênuo:
- O jogador A transfere uma Espada Lendária para o jogador B através da janela de troca direta.
- O servidor do jogador B salva com sucesso a nova espada no banco de dados.
- O servidor do jogador A sofre uma falha inesperada de energia ou crash de processo antes de persistir a remoção da espada do inventário de A.
- Quando o servidor reinicia, o jogador A ainda tem a espada em seu backup recente, e o jogador B também tem a espada gravada. O item foi duplicado.
Para impedir esse desastre, qualquer modificação de posse de itens ou valores monetários deve ser tratada sob as propriedades estritas de transações ACID (Atomicidade, Consistência, Isolamento e Durabilidade).
A figura acima esquematiza a arquitetura transacional à prova de dupes implementada com serviços nativos da AWS:
- Desacoplamento da simulação: os nós de combate em tempo real não conversam diretamente com o banco relacional para trocar itens. Eles delegam a requisição para um microsserviço dedicado de coordenação de trocas (Trade Coordinator).
- Trava de sessão bidirecional: ambos os jogadores entram em estado de bloqueio de inventário enquanto a janela de confirmação mútua é validada.
- Transações atômicas no Amazon DynamoDB: a gravação final utiliza a funcionalidade de transações atômicas nativas
TransactWriteItems. Em uma única chamada atômica, o DynamoDB executa uma operação multitable com checagem condicional: remove o item do inventário de A (verificando se o hash de versão do item ainda bate com o estado atual) e insere o item no inventário de B. Se qualquer uma das partes falhar, a operação inteira sofre rollback imediato no nível do cluster de armazenamento. - Livro-razão imutável (Audit Ledger): o evento concluído é despachado para uma fila Amazon SQS FIFO com garantia rigorosa de ordenação e deduplicação, permitindo que robôs de conciliação auditem desvios de riqueza no metagame de forma contínua.
11. Arquitetura de armazenamento em camadas na AWS
Manter 1 milhão de jogadores ativos exige balancear latência de microssegundos para o combate com persistência segura e duradoura para o patrimônio digital dos usuários. Nenhum banco de dados sozinho atende a todas essas pontas com viabilidade econômica. A solução reside em uma hierarquia de armazenamento em três níveis:
| Nível | Tecnologia AWS | O que armazena | Latência de acesso | Estratégia de consistência |
|---|---|---|---|---|
| Nível 1: Memória volátil de nó | Memória RAM local (C++ / Rust) | Coordenadas XYZ, velocidade, alvos de aggro, buffs temporários | < 5 nanossegundos | Eventual local (canônico no tick atual) |
| Nível 2: Cache distribuído | Amazon MemoryDB / ElastiCache Redis | Sessões ativas, listas de presença, coordenadas para AoI, snapshots de recuperação rápida | 200 microssegundos a 1 milissegundo | Gravação síncrona Multi-AZ com réplicas de leitura |
| Nível 3: Banco transacional NoSQL | Amazon DynamoDB | Inventário persistente, fichas de personagens, histórico de conquistas | 2 a 8 milissegundos | Consistência forte e transações ACID via TransactWriteItems |
| Nível 4: Banco relacional | Amazon Aurora PostgreSQL | Casas de leilão complexas, contratos de guildas, árvores genealógicas | 5 a 15 milissegundos | Transações com isolamento serializável e réplicas globais |
O segredo dessa pirâmide é a política de escrita: coordenadas de movimento nunca tocam o Nível 3 ou 4. Elas vivem no Nível 1 e são refletidas no Nível 2 a cada intervalo de segurança. Somente eventos de mutação estrutural (ganho de experiência, saque de ouro, compra de equipamentos) acionam gravações no Nível 3.
Parte 5: Serviços sociais e metagame
12. O desafio de comunicação: 1 milhão de pessoas conversando
Se o leitor acha que sincronizar monstros é difícil, espere até ver a caixa de chat global. Em um MMORPG, os jogadores esperam contar com diversos canais de texto e voz com escopos totalmente distintos:
- Chat de proximidade (Say / Yell): deve alcançar apenas os avatares situados a um raio físico de 20 a 50 metros no mapa 3D.
- Chat de grupo e guilda (Party / Guild): independe do mapa. O seu amigo pode estar na masmorra mais profunda de outro servidor e precisa receber a mensagem instantaneamente.
- Canais globais de comércio e mundo (Trade / Global): o canal que todo desenvolvedor sonha em desligar. Centenas de milhares de jogadores transmitindo ofertas de compra e venda simultaneamente.
Executar essa lógica dentro do processo que calcula a física dos monstros é receita certa para derrubar o frame rate da simulação. O subsistema social deve ser completamente desacoplado da grade de física.
A figura acima ilustra a malha de mensageria escalável montada com o Amazon Managed Streaming for Apache Kafka (Amazon MSK) e clusters de Redis:
- Conexões dedicadas: os clientes mantêm conexões leves via WebSockets diretamente em gateways de chat rodando no AWS ECS com containers Fargate. Essas conexões não competem pelos canais UDP do combate.
- Particionamento por canal: quando uma mensagem é postada no canal global de comércio, o gateway a publica em um tópico específico no Amazon MSK, particionado pelo identificador da sala ou região geográfica.
- Moderação assíncrona com inteligência artificial: antes de ecoar a mensagem pelo mundo, uma cópia assíncrona é despachada para workers de auditoria que aplicam filtros de linguagem imprópria, expressões regulares anti-spam e modelos de processamento de linguagem natural (NLP) para bloquear golpistas vendendo ouro por dinheiro real.
- Fan-out veloz: o cluster Redis recebe os eventos consolidados e distribui as mensagens apenas para os nós de borda que possuem membros daquela guilda conectados, minimizando o tráfego desnecessário de rede.
13. O metagame e a coexistência entre gRPC e GraphQL
Nem tudo em um MMORPG acontece dentro do cliente 3D do jogo. Os títulos modernos contam com ecossistemas ricos de aplicações satélites: aplicativos móveis para gerenciar leilões enquanto o usuário está no trabalho, portais web de ranqueamento competitivo (Armory) e APIs públicas para comunidades de criadores de conteúdo.
No núcleo desses serviços, a equipe de engenharia precisa selecionar os protocolos certos para os problemas certos:
- gRPC interno para throughput máximo entre microsserviços de backend: a comunicação entre o Game World Node e o Inventory Service exige milissegundos de um dígito, serialização binária ultra-eficiente via Protocol Buffers e suporte nativo a fluxos contínuos (streaming).
- GraphQL para clientes públicos, web e mobile: as telas de um aplicativo companion mudam com frequência. O jogador pode querer carregar apenas a foto do personagem e o ouro na tela inicial, mas querer a árvore inteira de talentos e itens equipados na tela de perfil. GraphQL oferece a flexibilidade de consulta sob demanda sem exigir a criação de dezenas de rotas REST redundantes.
A figura acima apresenta essa convivência elegante:
- O nó do mundo (Game World Node) se conecta ao microsserviço de inventário (
InventoryService) utilizando gRPC binário puro. O métodoEquipItemé invocado como chamada unária de alta velocidade, enquantoStreamItemUpdatesmantém um canal bidirecional aberto para injetar alterações no inventário em tempo real. - O aplicativo de smartphone do jogador consulta o
Metagame GraphQL Gateway. Na tela de leilão, ele executa uma consulta (query playerProfile), envia um lance (mutation bidAuction) e assina um stream de eventos em tempo real (subscription auctionUpdates) para ser notificado no instante em que seu lance for superado. - Ambos os caminhos convergem com segurança sobre o Amazon Aurora PostgreSQL, que atua como a fonte canônica da verdade relacional para os bens transacionáveis do jogo.
Parte 6: Telemetria, segurança e custos
14. O pipeline de telemetria anti-cheat em tempo real
Em um jogo multiplayer online, se o cliente tem controle sobre o código executável na máquina local, esse código será atacado. Hackers usam ferramentas como Cheat Engine para injetar DLLs na memória do processo, alterar multiplicadores de velocidade do personagem (speedhack), congelar o relógio de recarga de habilidades (cooldown hack) ou teleportar diretamente para o baú do tesouro.
A primeira linha de defesa é nunca confiar no cliente para cálculos definitivos. No entanto, clientes podem tentar ludibriar a validação do servidor forjando pacotes de inputs com timestamps distorcidos.
Para identificar trapaceiros com segurança sem gerar falsos positivos que frustram jogadores legítimos com conexões instáveis, a arquitetura precisa de um pipeline analítico de telemetria operando em paralelo à simulação de jogo.
O diagrama acima detalha esse pipeline de detecção em fluxo contínuo:
- Emissão contínua de telemetria: a cada tick de simulação, o nó do mundo despacha um resumo compacto com o vetor de velocidade, coordenadas de impacto e cadência de comandos para um stream central no Amazon Kinesis Data Streams / Amazon MSK.
- Análise analítica com Apache Flink: uma aplicação gerenciada de processamento em fluxo (Amazon Managed Service for Apache Flink) consome o stream aplicando janelas deslizantes de 5 segundos. O algoritmo calcula a velocidade média real percorrida pelo avatar:
$$V_{\text{real}} = \frac{|\vec{P}{t} - \vec{P}{t-\Delta t}|}{\Delta t}$$
Se $V_{\text{real}}$ exceder a velocidade máxima permitida pela classe do personagem acrescida de uma tolerância calculada para latência de rede, uma anomalia física é registrada. 3. Aplicação do castigo (Enforcement): após acumular três flags de anomalia matemática consistente no intervalo de 1 minuto, o serviço anti-cheat emite um comando de interrupção imediata via gRPC para o nó do mundo, desconectando o trapaceiro da sessão e movendo sua conta para uma lista de banimento preventivo. 4. Repositório de dados para aprendizado de máquina: todo o histórico de telemetria é depositado em formato colunar Parquet no Amazon S3 através do Amazon Kinesis Data Firehose, alimentando modelos de machine learning que refinam a identificação de padrões de comportamento de bots autônomos.
15. A fatura da nuvem: gestão de custos de Data Transfer Out (DTO)
Construir uma arquitetura impecável que roda a 60 Hz não adianta nada se a empresa for à falência ao receber a fatura da AWS no encerramento do primeiro trimestre.
O grande vilão financeiro de um jogo multiplayer massivo não é o custo de instâncias EC2 ou bancos de dados; é o tráfego de saída de dados para a internet pública (Data Transfer Out, ou DTO). A computação é paga por hora de uso de máquina, mas cada byte que cruza os roteadores de borda da AWS em direção à casa do jogador é cobrado no taxímetro.
Considere a economia comparativa de um jogo com 1 milhão de jogadores simultâneos conectados durante 20 horas por dia:
Cenário A (Ingênuo - JSON / structs sem compactação):
Tamanho médio do pacote: 400 bytes por tick
Frequência: 30 ticks por segundo
Banda por jogador: 400 * 30 = 12.000 bytes/s (12 KB/s)
Taxa global: 1.000.000 * 12 KB/s = 12.000.000 KB/s = 12 GB/s
Volume mensal (20h/dia): 12 GB/s * 3600s * 20h * 30 dias ≈ 25.920.000 GB = 25,92 Petabytes
Custo mensal aproximado na AWS (a US$ 0,07/GB): US$ 1.814.400 / mês
Cenário B (Engenharia de precisão - Delta compression, bitpacking e AoI):
Tamanho médio do pacote: 40 bytes por tick (redução de 90%)
Frequência: 30 ticks por segundo
Banda por jogador: 40 * 30 = 1.200 bytes/s (1,2 KB/s)
Taxa global: 1.000.000 * 1,2 KB/s = 1.200.000 KB/s = 1,2 GB/s
Volume mensal (20h/dia): 1,2 GB/s * 3600s * 20h * 30 dias ≈ 2.592.000 GB = 2,59 Petabytes
Custo mensal aproximado na AWS (a US$ 0,07/GB): US$ 181.440 / mês
A aplicação rigorosa de compressão de bits e algoritmos de delta encoding economiza mais de 1,6 milhão de dólares todos os meses para a mesma base de usuários. Boas práticas fundamentais para manter esse controle incluem:
- Compressão com quantização: um vetor de rotação no espaço precisa de 3 floats de 32 bits (96 bits no total) se enviado no formato bruto. Mas os ângulos de guinada, inclinação e rotação podem ser mapeados com precisão excelente para inteiros normalizados de 8 ou 16 bits (quantização), reduzindo o payload para menos de 32 bits.
- Baseline Delta Compression: o servidor nunca envia o estado completo do mundo em todos os ticks. Ele envia apenas a diferença (delta) em relação ao último tick que o cliente confirmou explicitamente ter recebido via ACK.
- Roteamento pelo AWS Global Accelerator: além de reduzir o jitter e a perda de pacotes ao injetar o tráfego nos cabos de fibra submarina privados da própria AWS no ponto de presença (Edge POP) mais próximo do usuário, o Global Accelerator oferece acordos de tarifação unificada mais previsíveis para grandes operações de gaming.
Parte 7: Alta disponibilidade e prática
16. O que acontece quando um nó de jogo explode
Em um ambiente de nuvem com milhares de servidores EC2 rodando em paralelo, a única certeza estatística é a falha. Instâncias de computação sofrem falhas de hardware no data center, processos sofrem crashes por estouro inesperado de memória (OOM), e manutenções de infraestrutura acontecem sem aviso.
Se um nó que abriga 2.500 jogadores no meio de uma batalha campal falhar, a pior resposta possível é desconectar todo mundo, reiniciar o processo do zero e jogar os avatares de volta na tela de login com perda de itens.
A arquitetura moderna exige failover transparente em nível de sessão de jogo.
A figura acima mapeia a sequência de auto-cura coordenada por orquestradores de contêineres de jogos (como o Agones, projeto open-source construído sobre o Kubernetes / Amazon EKS):
- Falha catastrófica: o processo do World Node A sofre um crash súbito e deixa de responder aos batimentos cardíacos (heartbeats) da rede.
- Retenção de socket na borda: o Edge UDP Gateway percebe a ausência de ticks de simulação vindos do nó A, mas não encerra a conexão UDP com os 2.500 jogadores. O gateway segura os sockets abertos em buffer temporário por até 5 segundos, exibindo um indicativo visual de reconexão sutil no cliente.
- Detecção e alocação pelo orquestrador: o controlador do Agones no EKS identifica 3 falhas consecutivas de heartbeat (1,5 segundo) e declara o nó A como morto, provisionando imediatamente uma réplica pré-aquecida (Node C Standby).
- Restauração de snapshot de memória: o novo nó C se conecta ao Amazon MemoryDB e recupera o último snapshot de estado consolidado daquele setor geográfico, gravado periodicamente a cada 10 segundos. Ele cruza os identificadores de inventário com o DynamoDB para assegurar que nenhum item foi corrompido durante o intervalo.
- Redirecionamento transparente: o nó C avisa o Edge UDP Gateway que assumiu o comando do setor. O gateway redireciona o fluxo de datagramas UDP para o novo endereço IP interno do nó C. O fluxo de simulação é retomado, e os 2.500 jogadores voltam a se mover normalmente sem passar por telas de carregamento ou filas de login.
17. Erros comuns e antipadrões em arquiteturas de MMORPG
Ao longo de décadas de história do desenvolvimento de jogos massivos, diversos erros clássicos foram cometidos repetidas vezes por estúdios de grande e pequeno porte. Conhecer essas armadilhas é essencial para evitá-las:
- Colocar o game loop atrás de um Application Load Balancer (ALB) HTTP: balanceadores de carga HTTP foram feitos para conexões com protocolo de enlace cliente-servidor de requisição e resposta. Tentar encapsular simulação de ação em túneis HTTP/REST gera latências inaceitáveis e custos exorbitantes de processamento de cabeçalhos.
- Confiar no relógio do cliente para cooldowns: se você permite que o cliente declare que 10 segundos se passaram para recarregar uma magia poderosa, um jogador mal-intencionado alterará a frequência do relógio do sistema operacional para disparar tempestades de meteoros a cada milissegundo. O relógio de cooldowns é sempre do servidor.
- Gravação direta no banco a cada abate de monstro: se 1 milhão de jogadores matam 5 monstros por minuto, isso gera mais de 80.000 gravações por segundo no banco de dados. Fazer isso de forma síncrona derrubará qualquer cluster de banco. Os ganhos de experiência e moedas devem ser acumulados em memória e consolidados no banco de dados de forma assíncrona em bateladas periódicas ou momentos-chave (troca de mapa, logout, abertura de baú).
- Subestimar a gravidade do problema de concentração: projetar o servidor para suportar uma densidade uniforme de 10 jogadores por quilômetro quadrado e esquecer que os jogadores invariavelmente se aglomerarão no portão do castelo da cidade principal. O sistema deve prever limites adaptativos de visibilidade na Quadtree para quando a densidade espacial atingir níveis anômalos.
18. Exercícios práticos de cálculo e dimensionamento
Consolide o seu conhecimento aplicando a matemática da aula para resolver os seguintes desafios de projeto de infraestrutura:
Exercício 1: Cálculo de largura de banda e dimensionamento de cluster
Um novo jogo MMORPG de ação roda a uma taxa de simulação de 50 Hz (50 ticks/s). Graças à compactação eficiente de bits, o tamanho médio do payload de saída enviado para cada cliente é mantido em 35 bytes por tick.
- Calcule a taxa de dados de saída gerada por um único jogador em Kilobytes por segundo (KB/s).
- Se o jogo alcançar o pico de 1.000.000 de jogadores simultâneos conectados, qual será a largura de banda agregada de saída em Gigabits por segundo (Gbps)?
- Quantas instâncias EC2 do tipo
c7g.16xlarge(capacidade de rede nominal de 25 Gbps por nó) serão necessárias na camada de gateways de rede para garantir que o tráfego não ultrapasse 60% da capacidade teórica das placas de rede?
Resposta guiada para conferência:
- 1 jogador: $35 \text{ bytes} \times 50 \text{ ticks/s} = 1.750 \text{ bytes/s} = 1,75 \text{ KB/s}$.
- 1 milhão de jogadores: $1.750.000 \text{ KB/s} \approx 1,75 \text{ GB/s} = 14 \text{ Gbps}$ sustentados.
- Cada nó a 60% entrega: $25 \text{ Gbps} \times 0,60 = 15 \text{ Gbps}$ úteis. Portanto, apenas 1 nó seria suficiente para a banda líquida calculada com essa compressão extrema, mas para suportar o throughput de interrupções de pacotes (PPS) e alta disponibilidade, a equipe deve distribuir essa carga entre um cluster mínimo de 10 a 16 nós menores (como
c7g.2xlarge) em múltiplas Zonas de Disponibilidade.
Exercício 2: O ponto de saturação da Quadtree
Uma arena de evento do jogo possui 1.200 jogadores reunidos. O servidor tem capacidade de despachar no máximo 36.000 mensagens de visibilidade por tick antes de começar a perder frames de física.
- Se não houver nenhum sistema de filtragem de interesse (broadcast ingênuo), quantas mensagens serão geradas por tick?
- Quantas vezes a capacidade do nó foi ultrapassada nesse cenário?
- Para manter o servidor estável dentro do limite de 36.000 mensagens por tick, qual deve ser o número máximo $K$ de vizinhos visíveis configurado no filtro de Area of Interest (AoI) para cada jogador?
Resposta guiada para conferência:
- Broadcast ingênuo: $1.200 \times (1.200 - 1) = 1.200 \times 1.199 = 1.438.800$ mensagens por tick.
- Fator de sobrecarga: $1.438.800 / 36.000 = 39,96$ vezes acima do limite suportado. O servidor congelaria instantaneamente.
- Configuração do AoI: queremos que $1.200 \times K \le 36.000$. Logo, $K \le 36.000 / 1.200 = 30$. Cada jogador só poderá enxergar e receber atualizações dos 30 personagens mais relevantes (por proximidade e prioridade de combate) ao seu redor.
19. Glossário técnico de sistemas de jogos
- CCU (Concurrent Users): número de jogadores conectados simultaneamente ao sistema no mesmo instante temporal.
- Tick rate: a frequência com que o laço de simulação do servidor executa seus cálculos matemáticos de física e combate, expressa em Hertz (Hz).
- AoI (Area of Interest): conjunto de técnicas algorítmicas (geralmente baseadas em árvores espaciais Quadtree ou Octree) que determinam quais entidades do mundo são relevantes para um observador específico.
- Client-Side Prediction: algoritmo no qual o cliente local simula e exibe o resultado das ações do jogador antes mesmo de receber a validação canônica da rede.
- Server Reconciliation: processo de correção em que o cliente desfaz previsões locais errôneas e ajusta o estado do avatar ao receber o snapshot autoritativo do servidor.
- Lag Compensation (Server Rewind): técnica onde o servidor rebobina temporariamente o histórico posicional do mundo para validar tiros e ataques no momento exato em que o jogador disparou no passado.
- Head-of-Line Blocking: gargalo inerente a fluxos TCP em que a perda de um único pacote retém a entrega de todos os pacotes subsequentes no buffer do sistema operacional.
- Seamless Handoff: transição imperceptível de autoridade sobre uma entidade entre dois nós de simulação física distintos sem exigir telas de carregamento.
- Ghost Entity: representação réplica em memória de uma entidade mantida em um nó vizinho para garantir continuidade visual e física nas bordas de mapa.
- Dupe Exploit: vulnerabilidade na lógica de persistência que permite clonar itens ou moedas através de desconexões forçadas ou transações concorrentes não isoladas.
- Bitpacking: técnica de compactação binária de baixo nível que agrupa dados no nível individual de bits, dispensando o preenchimento padrão de bytes.
Fontes e referências
- Valve Developer Community. Source Multiplayer Networking and Lag Compensation Architecture. Consulta realizada em outubro de 2026.
- CCP Games Engineering Team. EVE Online Architecture: Time Dilation and the 6,000-pilot battles. Devblog oficial, consultado em outubro de 2026.
- Amazon Web Services. AWS Game Tech: Building Scalable Multiplayer Game Servers on AWS with Agones and Amazon EKS. AWS Architecture Center, outubro de 2026.
- Glenn Fiedler. Gaffer on Games: Physics for Game Programmers, Networking Models and UDP Protocol Design. Artigos canônicos consultados em outubro de 2026.
- ArenaNet Engineering. Guild Wars 2: The Megaserver System and Dynamic Map Sharding. Relatório técnico da Game Developers Conference (GDC).
Relacionados
- Arquitetura orientada a eventos
- Idempotência
- concorrência
- Big O
- CDN
- MCP