UK

Посібник 7 — Онлайн-мультиплеєр

JumPHP з'єднує гравців через сервер-ретранслятор (WebSocket): той самий код працює онлайн на комп'ютері та в браузері. Гра Pong — повний приклад (src/Scene/PlayScene.php).

Лобі

$this->scenes()->switchTo(LobbyScene::class, [
    'next' => PlayScene::class,             // сцена гри, коли гравці зібралися
    'nextParams' => ['mode' => 'online'],
    'back' => TitleScene::class,
    'players' => 2,
]);

Лобі створює кімнату (код із 4 літер, яким можна поділитися), приєднується до наявної або знаходить суперника. Потім воно відкриває сцену гри з ['online' => true, 'net' => NetSession, 'host' => bool, 'peer' => int].

Повідомлення

$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);   // часто: може загубитися
$net->sendJson(self::MSG_EVENT, ['goal' => 1]);                                   // рідко: доходить завжди

Правильна організація

  • Господар вирішує: він симулює партію, рахує очки та надсилає стан ~20 разів на секунду;
  • інші надсилають свої команди ~30 разів на секунду;
  • об'єкти інших гравців малюються з невеликим згладженим запізненням: SnapshotBuffer (push($this->engine->time(), $state), потім sample($this->engine->time())).

Сервер-ретранслятор запускається у вас вдома командою bin/jumphp relay up; гра вказує свій через net_url у game.yaml (або ?net=wss://… в адресі сторінки).