Biblioteca

Partidas, IS blob e espectadores

Como iniciar partidas com o estado inicial correto e sincronizar quem entra depois.

Iniciar uma partida no bonk.io exige mais do que apertar "start": o host envia o estado inicial da física (o IS blob) e as configurações do jogo. A biblioteca cuida do envio, mas você precisa fornecer o blob certo.

Iniciar e parar

ts
room.startGame({ is: isBlob, gs: { bal: { 0: 0, 5: 1, 7: 2 } } });
room.stopGame();
OpçãoO que é
isO estado inicial da física (uma string LZ-String).
gsAjustes das configurações do jogo (Partial<GameSettings>), como bal.

O servidor ecoa o blob sem alterar para todos os clientes. Um blob vazio faz a engine de física não iniciar: os jogadores não aparecem em campo e o jogo parece travado no carregamento.

O IS blob

O IS blob codifica as posições de spawn, rotações e quais corpos existem na partida. Ele depende de dois fatores:

  • O mapa. Um blob capturado em um mapa não serve em outro.
  • O número de jogadores ativos. O blob de 1v1 (2 jogadores) não serve para 2v2 (4 jogadores).

Blobs padrão

Para o mapa de football padrão e alguns modos, a biblioteca traz blobs prontos:

ts
import { getFootballDefaultBlob, getGamemodeDefaultBlob } from 'bonktools';

getFootballDefaultBlob(2);              // 1v1
getFootballDefaultBlob(4);              // 2v2
getGamemodeDefaultBlob('football', 2);  // por modo de jogo

Para mapas que variam por sala (classic, arrows, etc.), use o cache por mapa.

Cache por mapa

ts
import { MapBlobCache } from 'bonktools';

const cache = new MapBlobCache('./map-blob-cache.json');

const blob = cache.getForMap(room.currentMap, 4);   // blob deste mapa para 4 jogadores
if (!blob) { /* capture um (veja abaixo) */ }
cache.setForMap(room.currentMap, 4, capturedBlob);

Capturar um blob

O jeito confiável é capturar de uma sessão real. A biblioteca inclui um utilitário:

bash
BONK_USERNAME=seu_usuario BONK_PASSWORD=sua_senha npx bonktools-capture-is https://bonk.io/123456abcde

Ele entra na sala como espectador e espera. Quando um host real iniciar uma partida no navegador, ele imprime o blob no formato BONK_INITIAL_STATE=..., pronto para colar no seu .env ou no cache por mapa. Capture um blob para cada número de jogadores ativos que você pretende usar.

O campo bal

O bal diz qual corpo cada jogador controla, no formato { idDoJogador: indiceDoCorpo }.

ts
// bot (id 0) sem corpo; jogadores 5 e 7 com corpos 1 e 2
room.startGame({ is, gs: { bal: { 0: 0, 5: 1, 7: 2 } } });

Sempre use o mapeamento explícito. Com bal: [], os corpos são atribuídos por ordem crescente de id, e se jogadores entraram e saíram os ids têm buracos: um jogador do time azul pode nascer no lado vermelho.

Quem entra com a partida rolando

Quando um jogador entra, o host precisa lhe entregar os dados iniciais. Existem dois pacotes possíveis, e o client só aceita um:

SituaçãoPacote enviado
Sala no lobbyINFORM_IN_LOBBY
Partida em andamentoINFORM_IN_GAME (traz o estado da partida)

A biblioteca escolhe sozinha: se uma partida foi iniciada com startGame({ is }) e ainda está ativa, o novo jogador recebe INFORM_IN_GAME no lugar de INFORM_IN_LOBBY, e passa a ver a partida sem reiniciá-la para os demais.

Se o seu bot reinicia a partida logo depois de alguém entrar (como a sala 24/7 faz para completar times), tudo funciona: o jogador recebe o pacote certo e depois o início da nova partida.