Game Dev 04 de setembro de 2026• 9 min de leitura• Rafael Guimarães

GGBoard: Criando um Jogo de Tabuleiro em 3D

Os bastidores do GGBoard: tabuleiro descrito em JSON, casas especiais com teleporte e dado par ou ímpar, multiplayer peer-to-peer com PeerJS, câmeras em Three.js e um editor que encontra as casas sozinho na imagem.

GGBoard: Criando um Jogo de Tabuleiro em 3D

GGBoard: como fizemos um jogo de tabuleiro 3D multiplayer que roda no navegador

Jogo de tabuleiro é reunião: todo mundo em volta da mesa, esperando a sua vez, torcendo pelo dado. O GGBoard tenta levar isso para o navegador. Cada jogador entra de onde estiver, escolhe um personagem e anda por um tabuleiro 3D cheio de casas que mandam voltar, pular a vez ou tentar a sorte no dado.

Este artigo explica as três partes que fazem o jogo funcionar: como o tabuleiro é descrito, como os jogadores ficam sincronizados sem um servidor de jogo e como o mundo 3D é montado. No fim, o editor que usamos para criar tabuleiros novos.

Como se joga

  • Você escolhe um nome e um personagem. Há sete modelos 3D, de tanques a um baú.
  • Quem cria a sala recebe um código e um link de convite para mandar aos amigos. A página do jogo fala em até 8 jogadores.
  • Na sua vez, você clica em Rolar Dado e seu personagem anda casa por casa, com um pulinho a cada passo.
  • Algumas casas têm efeitos: avançar ou voltar para outra casa, voltar ao início, perder a próxima vez, jogar de novo ou rolar o dado mais uma vez para decidir o caminho.
  • Em encruzilhadas, o jogo pergunta qual caminho você quer seguir.
  • Vence quem chegar primeiro à chegada.

Um painel lateral mostra a vez de quem, em que casa cada um está e um histórico das últimas jogadas.

Nomes de jogadores: o que vale testar

O nome escolhido no início acompanha o jogador na sala. Em uma partida com amigos, isso parece um detalhe; em uma interface multiplayer, o apelido precisa continuar reconhecível no painel lateral e no histórico, inclusive em telas pequenas.

É possível experimentar letras diferentes em um nome de exibição, mas há uma distinção técnica: a fonte tipográfica definida no layout não é a mesma coisa que os caracteres Unicode digitados ou colados pelo jogador. Alguns símbolos podem não ter um glifo disponível em determinado aparelho; outros ocupam mais espaço do que parecem. Isso não significa que o GGBoard tenha esses problemas hoje — é uma proposta de verificação para futuras versões.

Um teste editorial e de experiência do usuário pode comparar quatro exemplos no fluxo de entrada, no painel da sala e no histórico:

  • Ana e João: nomes comuns, incluindo acento da língua portuguesa;
  • João em composições Unicode diferentes: conferir se grafias visualmente iguais são tratadas de modo consistente;
  • ★Luna★: observar se os símbolos ficam legíveis sem apertar os elementos da interface;
  • um nome com caractere invisível: verificar se a identificação não se torna ambígua para os demais jogadores.

Para montar amostras de teste, uma coleção de símbolos para copiar pode fornecer exemplos como ★, ♡ e ✦; copiar um caractere não garante que o jogo o aceite ou apresente corretamente. Em ambientes que exigem identificação única, também vale considerar o alerta do Unicode Consortium sobre caracteres visualmente confundíveis.

A proposta não é aumentar a quantidade de estilos no jogo, mas definir, documentar e testar quais caracteres fazem sentido para o campo de nome, preservando desempenho, clareza e acessibilidade.

O tabuleiro é um arquivo de dados

A decisão mais importante do GGBoard foi separar o jogo do tabuleiro. O código não sabe nada sobre semáforos, patos ou obras na pista. Ele só sabe ler um arquivo JSON que descreve as casas e o que cada uma faz.

O tabuleiro padrão, o Mapa Urbano, é um arquivo com uma imagem de fundo de 1200 por 900 e uma lista de 90 casas. Cada casa tem uma posição, um tipo e as casas para onde se pode ir a partir dela:

{
  "id": 14,
  "x": 412, "y": 238,
  "type": "special",
  "connections": [15],
  "message": "Semáforo fechado! Fique uma rodada sem jogar.",
  "action": { "type": "SKIP_TURN" }
}

(Exemplo ilustrativo do formato; os campos são os que o jogo lê.)

Os tipos de casa são cinco:

TipoO que é
starta saída
normaluma casa comum
specialuma casa com efeito
roundaboutuma rotatória, ponto em que o caminho se divide
enda chegada

E as casas especiais usam um conjunto pequeno de ações:

AçãoEfeito
MOVEleva o jogador direto para outra casa
MOVE_TO_STARTvolta para o início
SKIP_TURNperde a próxima vez
EXTRA_TURNjoga de novo
FORCE_STOPpara o movimento ali, mesmo que o dado mande andar mais
CONDITIONAL_DICErola o dado de novo; o resultado par ou ímpar decide o que acontece
EVEN_ODD_BIFURCATIONrola o dado; par vai para um caminho, ímpar para outro

No Mapa Urbano, das 90 casas, 20 são especiais e 12 são rotatórias. Os temas vêm da cidade: semáforo, viatura de polícia, faixa de pedestres, patos atravessando, obras, uma árvore caída, trem e posto de gasolina.

Por que isso importa

Com o tabuleiro em dados, criar um tabuleiro novo não exige mexer no código. Basta outra imagem e outro arquivo JSON. Quem cria a sala pode inclusive carregar um arquivo de tabuleiro próprio antes de começar a partida.

Isso também deixa as regras fáceis de testar: sete ações bem definidas, combinadas de formas diferentes, rendem muitos tabuleiros possíveis.

Multiplayer sem servidor de jogo

O GGBoard não tem um servidor que calcula a partida. Os navegadores dos jogadores se conectam diretamente, por WebRTC, usando a biblioteca PeerJS.

O host manda

Um dos jogadores é o host: quem criou a sala. O código da sala é, na verdade, o identificador do navegador dele na rede do PeerJS. Quem recebe o link conecta direto nesse navegador.

O host guarda o estado oficial da partida: onde está cada jogador, de quem é a vez, quem está preso. Os outros jogadores não mexem no estado; eles só fazem pedidos:

// Um jogador que não é o host, quando clica em "Rolar Dado"
host.send({ type: 'ROLL_DICE_REQUEST' });

// No host
if (state.activePlayerId === senderId &&
    state.gameState === 'playing' &&
    !state.isMoving) {
  rollDice();
  broadcast({ type: 'GAME_STATE_SYNC', state: serialize() });
}

O host confere três coisas antes de aceitar: é mesmo a vez de quem pediu, a partida está em andamento e ninguém está se movendo naquele momento. Um pedido fora de hora é simplesmente ignorado. A escolha de caminho numa encruzilhada passa pela mesma checagem: o host só aceita um caminho que esteja entre as opções daquela casa.

Depois de cada mudança, o host manda o estado completo para todos. Assim, mesmo que alguém perca uma mensagem, a próxima corrige tudo.

Quem cai, volta

Se um jogador perde a conexão no meio da partida, o host o marca como desconectado e pula a vez dele, para que o jogo não trave esperando. Quando ele volta, reassume o lugar. Também dá para entrar numa partida que já começou.

O custo do peer-to-peer

Sem servidor de jogo, o GGBoard não tem custo de servidor por partida, e a latência entre amigos costuma ser baixa. O preço é que a partida depende do host: se quem criou a sala fechar a aba, a sala fecha para todos. Para um jogo de tabuleiro, em que as partidas são entre conhecidos e por turnos, essa troca vale a pena.

O mundo em 3D

O GGBoard usa Three.js para desenhar o tabuleiro em 3D. A arte do tabuleiro é uma imagem estendida no chão; por cima dela ficam as casas, como círculos, e as ligações entre elas, como linhas semitransparentes.

Luz e sombra

São duas luzes: uma ambiente, que clareia tudo por igual, e uma direcional, que funciona como o sol e projeta sombras. As sombras usam um mapa de 2048 por 2048 com bordas suaves. Elas parecem um detalhe, mas são o que faz os personagens parecerem apoiados no tabuleiro, e não flutuando sobre ele.

O jogo também limita a resolução em telas de altíssima densidade a 2× para não pesar em placas de vídeo mais simples.

Os personagens

Os sete personagens são modelos OBJ com materiais MTL e texturas PNG, arquivos entre 36 KB e 174 KB. No saguão, o personagem escolhido gira devagar numa prévia 3D.

O movimento casa a casa leva 450 ms por casa. A posição vai de uma casa à outra em linha reta, e a altura segue uma curva de seno, o que cria o pulinho:

// t vai de 0 a 1 durante o passo
piece.position.lerpVectors(from, to, t);
piece.position.y = 3 + 35 * Math.sin(t * Math.PI);

Uma linha de código e o peão deixa de deslizar para "pular" de casa em casa, como uma peça de verdade.

As câmeras

A tecla V alterna entre uma câmera em perspectiva, que segue o jogo de perto, e uma ortográfica vista de cima, que mostra o tabuleiro inteiro sem distorção. Um segundo botão escolhe o que a câmera acompanha: o seu personagem, quem está jogando agora, a câmera livre ou qualquer outro jogador. Arrastar o mouse gira a câmera em volta do ponto que ela está olhando.

Seguir automaticamente quem está jogando é o que torna a espera interessante: mesmo fora da sua vez, você vê o peão do amigo cair numa casa de "volte ao início".

O dado

O dado é um número de 1 a 6 sorteado pelo host. Na tela, uma caixa troca de número 16 vezes, a cada 75 ms, antes de parar no resultado. Como o sorteio acontece só no host, ninguém consegue "escolher" o próprio dado.

O editor de tabuleiros

Montar 90 casas à mão, uma por uma, seria lento. Por isso o GGBoard tem um editor, uma página separada, que trabalha em 2D sobre a imagem do tabuleiro:

  1. Você carrega a imagem de fundo.
  2. O botão Auto-Detectar Casas varre os pixels da imagem procurando círculos claros e cria uma casa em cada um.
  3. Com as ferramentas Adicionar, Conectar, Remover e Editar, você ajusta o que a detecção errou, liga as casas na ordem do caminho e define o tipo e a ação de cada uma.
  4. As setas do teclado movem a casa selecionada 5 pixels, ou 1 com Shift, para alinhar no lugar certo.
  5. No fim, o editor exporta o arquivo JSON do tabuleiro, pronto para o jogo carregar.

A detecção automática é o que torna o editor prático: a arte do tabuleiro já tem as casas desenhadas, e o editor só precisa descobrir onde elas estão.

Resumo

  • Tabuleiro descrito em JSON: 5 tipos de casa e 7 ações; o Mapa Urbano tem 90 casas
  • Multiplayer peer-to-peer com PeerJS; o host valida os pedidos e envia o estado a todos
  • Three.js com luz direcional e sombras suaves, câmeras em perspectiva e de cima
  • Peões que pulam casa a casa com uma curva de seno
  • Editor com detecção automática de casas na imagem do tabuleiro

Jogar o GGBoard

Texto técnico original: Rafael Guimarães dos Santos. Colaboração editorial nesta atualização: Sophie Ale.

Continue lendo

RG

Rafael Guimarães

Criador do Guima Games Portal & Game Developer

Ver mais artigos