GG Wars: um servidor, dois jogos — tanques e naves no mesmo multiplayer
O GG Wars começou como uma arena de tanques e virou dois jogos: o GG Wars, com tanques, e o GG Wars 2, uma batalha espacial em 3D. Os dois são multiplayer em tempo real, rodam no navegador e conversam com a mesma infraestrutura de servidor.
Este artigo explica as decisões por trás dos dois modos: por que o servidor é quem decide tudo, como a nave voa, o que acontece quando um asteroide é atingido e por que existem bots numa sala de multiplayer.
Por que o servidor decide
Em jogos de tiro em tempo real, a pergunta "acertei ou não?" precisa ter uma única resposta. Se cada navegador calculasse a própria partida, um jogador veria o tiro acertar e o outro veria errar.
No GG Wars, a partida é calculada num servidor Node.js, hospedado no Google Cloud Run, e os navegadores se conectam a ele por Socket.IO. O navegador manda o que o jogador quer fazer, e o servidor devolve o que aconteceu:
// O navegador envia só a intenção
socket.emit('input', { thrust: 1, yaw: -1, pitch: 0, fire: true });
// E recebe o estado da partida
socket.on('update', (state) => render(state));(Formato simplificado; no modo espacial a entrada tem exatamente thrust, yaw e pitch.)
Esse modelo se chama servidor autoritativo. Ele tem duas vantagens. A primeira é a justiça: só existe uma partida, a do servidor. A segunda é a proteção contra trapaça: o navegador não diz "estou aqui" nem "acertei", só "apertei para a frente". Mexer no código do navegador não dá velocidade extra a ninguém.
Constantes compartilhadas
Os dois lados precisam concordar sobre os números do jogo: tamanho do mundo, raio dos tanques, velocidade dos tiros. Por isso essas constantes ficam num arquivo compartilhado entre o servidor e os clientes. Alguns valores:
| Constante | Valor |
|---|---|
Taxa de atualização (FPS) | 60 |
| Mundo dos tanques | 1600 × 1200 |
| Velocidade do tanque | 2 por tick |
| Rotação do tanque | 10° por tick |
| Velocidade do tiro | 12 por tick |
| Intervalo entre tiros | 800 ms |
O intervalo de 800 ms entre tiros é uma regra de design, não só técnica: obriga o jogador a mirar, em vez de segurar o botão.
Quando a conexão cai
Os dois jogos reconectam sozinhos se a internet oscilar e, ao voltar, entram de novo na sala. Se o servidor não responder ao entrar, o jogo tenta mais uma vez depois de um segundo antes de avisar que não conseguiu conectar.
Modo tanques
No GG Wars, cada jogador comanda um tanque numa arena. Ao entrar, você escolhe um nome e um de sete modelos, do tanque padrão a versões de Natal e em forma de pirâmide.
O mundo é desenhado em 3D com Three.js, e a tecla V troca entre duas câmeras:
- De cima, com uma câmera ortográfica, sem perspectiva. Parece um jogo 2D clássico, e é a melhor visão para enxergar a arena inteira.
- De perseguição, atrás do seu tanque, em perspectiva. Menos visão do todo, mais imersão.
No celular, um joystick virtual e um botão de tiro aparecem na tela. Quando a partida acaba, o jogo mostra o vencedor, ou "Empate!".
Modo espacial: o GG Wars 2
O GG Wars 2 tira a gravidade e acrescenta uma dimensão. As naves voam num espaço 3D de 18.000 unidades de largura, e controlar uma delas é bem diferente de dirigir um tanque.
Como a nave voa
A nave não para quando você solta o acelerador. Ela tem inércia: o motor empurra, e a velocidade vai diminuindo aos poucos. São três números que definem a sensação de voo:
const SHIP_ACCELERATION = 1.8;
const SHIP_DAMPING = 0.96; // fica com 96% da velocidade a cada tick
const SHIP_MAX_SPEED = 14;
velocity += thrust * SHIP_ACCELERATION;
velocity *= SHIP_DAMPING;
velocity = Math.min(velocity, SHIP_MAX_SPEED);O amortecimento de 0,96 é o coração do controle. No espaço real a nave não frearia nunca, o que seria realista e muito difícil de jogar. Com 0,96, a nave desliza depois que o motor desliga, mas perde velocidade rápido: depois de 60 ticks sem acelerar, sobra menos de 10% (0,96⁶⁰ ≈ 0,09). Ela fica com peso sem fugir do controle.
Os controles
- W acelera.
- A e D giram a nave para os lados.
- O mouse inclina o nariz para cima e para baixo. Clicar na tela trava o cursor dentro do jogo, para que o mouse controle só a nave.
- V troca entre a visão de perseguição, atrás da nave, e a de cabine, de dentro dela.
Os tiros do modo espacial são mais rápidos e mais frequentes que os dos tanques: velocidade 22 e um a cada 600 ms. A arena é muito maior, e um tiro lento não acertaria nada.
Asteroides que se partem
O espaço tem asteroides de três tamanhos, e eles resistem a vários tiros:
| Tamanho | Raio | Tiros para destruir | Ao ser destruído |
|---|---|---|---|
| Grande | 400 | 8 | vira 3 médios |
| Médio | 180 | 4 | vira 3 pequenos |
| Pequeno | 80 | 2 | desaparece |
Destruir um asteroide grande até o fim exige 38 tiros e espalha 12 pedaços pelo caminho. Isso muda a partida: o asteroide é cobertura para se esconder, mas atirar nele espalha pedaços pela arena. Asteroides destruídos voltam depois de 15 segundos, para o espaço nunca ficar vazio.
De tempos em tempos, entre 15 e 60 segundos, aparece também uma vida extra flutuando, o que vale uma corrida até ela no meio do combate.
Bots: multiplayer mesmo sem gente
Um jogo multiplayer tem um problema clássico: se você entra e a sala está vazia, não há com quem jogar. O GG Wars 2 resolve isso com bots. Antes de começar, quem monta a sala escolhe de 0 a 5 bots (o padrão é 3) e a velocidade deles, de 1% a 100% (o padrão é 45%). Cada bot tem 5 vidas.
A velocidade ajustável funciona como nível de dificuldade: bots lentos para quem está aprendendo a voar, rápidos para quem quer desafio. A escolha fica salva no navegador.
Se você chegar numa sala com a partida já em andamento, o saguão avisa quantos jogadores estão lá e oferece entrar na partida, com a configuração travada até a próxima.
As quatro naves
Há quatro naves para escolher. Para que cada modelo apareça na posição e no ângulo certos, existe um editor de naves, uma ferramenta interna em que cada modelo é ajustado em posição e rotação e o resultado vira uma tabela que o jogo usa. Sem isso, um modelo exportado de lado apareceria voando de lado.
O que os dois modos ensinaram
- Inércia é design. Um único número, o amortecimento, decide se a nave parece pesada, escorregadia ou controlável.
- Limitar o tiro cria estratégia. 800 ms nos tanques e 600 ms no espaço fazem cada disparo contar.
- Bots salvam salas vazias. Um jogo multiplayer precisa ser jogável quando só uma pessoa aparece.
- O servidor decide. É mais trabalho do que deixar cada navegador calcular, mas é o que torna a partida justa.
Resumo
- Servidor Node.js com Socket.IO no Cloud Run; o navegador envia só a intenção
- Tanques em Three.js com câmera de cima ou de perseguição
- Naves com aceleração, amortecimento de 0,96 e velocidade máxima
- Asteroides de três tamanhos que se partem em três
- De 0 a 5 bots com velocidade ajustável
Jogar o GG Wars · Jogar o GG Wars 2
Continue lendo
- GG Pacman multiplayer: movimento suave com a rede atrasada
- GGBoard: um jogo de tabuleiro 3D multiplayer no navegador
