NL

Tutorial 7 — Online multiplayer

JumPHP verbindt spelers via een relayserver (WebSocket): dezelfde code online op de desktop en in de browser. De game Pong is het complete voorbeeld (src/Scene/PlayScene.php).

De lobby

$this->scenes()->switchTo(LobbyScene::class, [
    'next' => PlayScene::class,             // de scène van de game, zodra de spelers verzameld zijn
    'nextParams' => ['mode' => 'online'],
    'back' => TitleScene::class,
    'players' => 2,
]);

De lobby maakt een kamer aan (een code van 4 letters om te delen), voegt je bij een kamer, of zoekt een tegenstander. Daarna opent hij de scène van de game met ['online' => true, 'net' => NetSession, 'host' => bool, 'peer' => int].

De berichten

$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);   // vaak: mag verloren gaan
$net->sendJson(self::MSG_EVENT, ['goal' => 1]);                                   // zelden: komt altijd aan

De juiste opzet

  • De host beslist: hij simuleert het spel, telt de punten en stuurt de toestand ~20 keer per seconde;
  • de anderen sturen hun commando's ~30 keer per seconde;
  • de objecten van de anderen worden getekend met een kleine, afgevlakte vertraging: SnapshotBuffer (push($this->engine->time(), $state) en daarna sample($this->engine->time())).

De relayserver start je bij jezelf met bin/jumphp relay up; de game geeft de zijne op met net_url in game.yaml (of ?net=wss://… in het adres van de pagina).