PT

Tutorial 7 — O multijogador online

O JumPHP conecta os jogadores por um servidor de retransmissão (WebSocket): o mesmo código online no desktop e no navegador. O jogo Pong é o exemplo completo (src/Scene/PlayScene.php).

O lobby

$this->scenes()->switchTo(LobbyScene::class, [
    'next' => PlayScene::class,             // a cena do jogo, quando os jogadores estiverem reunidos
    'nextParams' => ['mode' => 'online'],
    'back' => TitleScene::class,
    'players' => 2,
]);

O lobby cria uma sala (um código de 4 letras para compartilhar), entra em uma ou encontra um adversário. Depois abre a cena do jogo com ['online' => true, 'net' => NetSession, 'host' => bool, 'peer' => int].

As mensagens

$net = $params['net'];
$net->removeAllListeners();
$net->on('message', fn (int $from, int $type, string $payload) => $this->receive($from, $type, $payload));
$net->on('peerLeave', fn (int $peer) => $this->scenes()->switchTo(TitleScene::class));

$net->send(self::MSG_STATE, pack('gg', $this->x, $this->y), reliable: false);   // frequente: pode se perder
$net->sendJson(self::MSG_EVENT, ['goal' => 1]);                                   // raro: sempre chega

A boa organização

  • O host decide: ele simula a partida, conta os pontos e envia o estado ~20 vezes por segundo;
  • os outros enviam seus comandos ~30 vezes por segundo;
  • os objetos dos outros são desenhados com um pequeno atraso suavizado: SnapshotBuffer (push($this->engine->time(), $state) e depois sample($this->engine->time())).

O servidor de retransmissão sobe na sua máquina com bin/jumphp relay up; o jogo indica o dele com net_url no game.yaml (ou ?net=wss://… no endereço da página).