このページは編集中です。更新が保留になっている可能性があります。

Webhooks

概要

Webhookは、信頼できるゲーム設定やルーム構成の情報源として主に利用され、オンラインアプリケーションの安全性向上に大きく寄与します。

デフォルトのクラウドプラグインは、AppIDダッシュボードで定義されたさまざまなWebhookをサポートしています。設定と有効化を行うと、Photon CloudはカスタムバックエンドへHTTP POSTリクエストを送信し、そのレスポンスデータ(JSON)を活用して、ルームやゲームセッションの各種構成を適用します。

セットアップ

WebhookはPhotonダッシュボード上でAppIdごとにセットアップを行います。

  1. Photon Dashboard へナビゲートし、ログインする。
  2. AppIdを探し、Manageをクリックする。
  3. プラグインまでスクロールで下がり、Editをクリックする。
  4. Add New Pairをクリックして、keysvalues (各設定値に使えるのは最大1024文字)を追加する。
  5. Saveを押下して最大1分間待ち変更が反映されたことを確認する。
Photon Dashboard Properties

ダッシュボード設定

Key Type Example Description
WebHookBaseUrl string https://localhost:3581 カスタムバックエンドの基本URLです。WebhookのパスはこのURLに追加され、次の形式になります: {WebHookBaseUrl}/game/create

必ず設定してください。
WebHookIntegration string Default 選択されたWebhookの統合方法です(デフォルトは `Default`)。

選択肢は以下の通りです:
DefaultPlayFab
WebHookSecret string ********** これらは各Webリクエストとともに送信され、リクエストの認証に利用できます。
ヘッダー名は `X-SecretKey` に設定されます。
WebHookCustomHttpHeaders Dictionary <string, string> {"A": "Foo", "B": "100" } `JSON`形式の辞書です。すべてのエントリーはカスタムWebリクエストのヘッダーに追加されます。ダブルクォーテーションを使用してください。
WebHookEnableOnCreate bool true これを`true`に設定すると、クライアントがゲームセッションを作成するときに`CreateGame`Webhookが発動します。
WebHookEnableOnClose bool false これを`true`に設定すると、ゲームセッションが閉じられた際に `CloseGame` Webhookが発動します。
WebHookEnableOnJoin bool true これを`true`に設定すると、クライアントがゲームセッションに参加しようとした際に`JoinGame` Webhookが発動します。
WebHookEnableOnLeave bool false これを`true`に設定すると、クライアントがゲームセッションを退出した際に `LeaveGame` Webhookが発動します。
WebHookUrl{KEY} string https://foo.net/path このパターンは任意で、`WebHookBaseUrl`に基づいて個別のWebhookのデフォルトパスを上書きするために使用できます。
`{KEY}` の有効な置換文字列は、`OnCreate`、`OnJoin`、`OnLeave`などです。

Quantum Dashboard Configurations

Key Type Example Description
WebHookEnableGameConfigs bool false If set to true, the GameConfigs webhook will be fired when a client uploaded the game configs RuntimeConfig and SessionConfig using the StartRequest operation.
WebHookEnableGameResult bool false If set to true, the GameResult webhook will be invoked.
WebHookEnableAddPlayer bool false If set to true, the client operation AddPlayer will invoke the AddPlayer web request.
WebHookEnablePlayerAdded bool false If set to true, the PlayerAdded web request is invoked after a player has been successfully added to the Quantum online game.
WebHookEnablePlayerRemoved bool false If set to true, the PlayerRemoved web request is invoked after a player was removed from the Quantum game.
WebHookEnableReplay bool false Setting this to true will enable the replay streaming based on the ReplayStart and ReplayChunk web requests.

Webhook API

WebhooksはJSONコンテンツを送信し、レスポンスもJSON形式のコンテンツのみを受け付けます。JSONの文字エンコーディングはUTF-8のみが必須です。

WebhooksはHTTPレスポンスコードとして200または400を期待しています。

  • 200: リクエスト成功
  • 400: エラーまたは操作が拒否された(例:クライアントによるルームやゲームセッションの作成を許可しない場合)

Photonサーバーは、通信エラー時にWebhookのリトライを3回行います。リトライ間の遅延は、400ms、1600ms、6400msです。また、リクエストが失敗し再試行されないまでのタイムアウト時間は10秒です。

エラーの詳細情報をPhotonプラグインに返すために、WebhookErrorの定義を記入してください。これにより、以下の用途に利用できます:

  • ロギング
  • クライアントへの情報返還
  • カスタムプラグインによる高度なエラー処理

Httpリクエスト再試行

Photonサーバーは、バックエンドからの再試行可能なエラー応答に対して、リクエストをさらに3回再送信します。

その後のリクエストには、それらを識別するための異なるヘッダーが付加されます。

EGRepeatId - 例えば、0123などの整数値で、リクエストの再送番号。
EGInvokeId - リクエストID (整数)

よくあるリクエストヘッダ

Tこれらの共通リクエストヘッダーは、すべての ウェブリクエストに追加されます。

Name Type Content Description
Accept string application/json Webhooksは、レスポンス本文として JSON 形式のみを受け付けます
Accept-Charset string utf-8 Webhooksは、レスポンスの本文の文字エンコーディングとしてUTF-8のみを受け付けます
Content-Type string application/json すべてのWebhooksは、 JSON 形式の本文データを送信します
X-SecretKey string ********** このキーはカスタムバックエンドのみが知っているべきものであり、受信するウェブリクエストの認証に使われます。PhotonダッシュボードでWebHookSecretと設定されます。
X-Origin string Photon 必ず"Photon"と設定

CreateGame

このWebhookは、ルームまたはゲームセッションがPhotonサーバー上で作成される前に呼び出されます。Webhookがレスポンスを受け取るまで作成はブロックされるため、これによりクライアントが接続を確立するまでの時間に影響します。

CreateGameWebhookは、常にルームまたはゲームセッションの作成を開始したユーザーのJoinGameリクエストとして扱われます。このユーザーに対して後続のJoinGameWebhookは発生しません。このWebhookは、JoinGameWebhookのデータを共有します。

このWebhookを設定するには、PhotonダッシュボードでWebHookBaseUrlWebHookEnableCreateGameを設定している必要があります。

JavaScript

POST https://{WebHookBaseUrl}/game/create

CreateGameリクエスト

Name Type Example Description
AppId string d1f67eec-51fb-45c1 The Photon AppId.
AppVersion string 1.0-live ルームまたはゲームセッションの作成時に使用されるアプリバージョンです。
Region string eu ルームまたはゲームセッションが作成されたゲームサーバーのリージョンコードです。.
Cloud string 1 そのゲームサーバーが稼働しているCloud Idです。
UserId string db757806-8570-45aa ルームまたはゲームセッションを作成したクライアントのUserIdです。
AuthCookie Dictionary<string, object> db757806-8570-45aa バックエンドによって設定されたPhotonのカスタム認証クッキーです。
RoomName string e472a861-a1e2-49f7 ルームまたはゲームセッションの名前です.
GameId string 0:eu:e472a861-a1e2-49f7 GameIdは、 {Cloud:}{Region:}RoomNameで構成される一意のIDです。レスポンスによって上書きされることがあります。
EnterRoomParams EnterRoomParams JSON: EnterRoomParamセクションをご覧ください クライアントから送信されたPhotonのルームまたはゲームセッションのオプションです

Jsonの例:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "AppVersion": "1.0-live",
  "Region": "eu",
  "Cloud": "1",
  "UserId": "db757806-8570-45aa",
  "AuthCookie": {
    "Secret": "**********"
  }
  "RoomName": "e472a861-a1e2-49f7",
  "GameId": "0:eu:e472a861-a1e2-49f7",
  "EnterRoomParams": {
    "RoomOptions": {
      "IsVisible": true,
      "IsOpen": true
    }
  }
}

HTTP応答コード

Name Type Description
200 OK CreateGame応答 ルームまたはゲームセッションの作成は開始されますが、レスポンスの設定データによってクライアントから送信されたデータが上書きされます。
400 Bad Request WebhookError ルームまたはゲームセッションの作成は許可されず、キャンセルされます。クライアントはエラーを受け取ります。

CreateGame応答

Name Type Description
GameId string 後続のウェブリクエストで使用される `GameId` を上書きします。
値は `null` もしくは省略可能です。
EnterRoomParams EnterRoomParams 作成時に選択したルームオプションを強制適用します。
JSONオブジェクトには、上書きしたいメンバーだけを含める必要があり、すべてのメンバーを含める必要はありません。

最初のオプションは、`EnterRoomParams`を送信することで保護されます。ほとんどの設定は、クライアントがPhotonのルームプロパティを送信して変更することが可能です。これを防ぐには、Photonダッシュボードの `BlockRoomProperties`設定を有効にしてください。
値は `null` もしくは省略可能です。
Name Type Description
SessionConfig SessionConfig Return a SessionConfig object that is used by the game. Game configs sent by clients will be ignored.
RuntimeConfig RuntimeConfig Return a RuntimeConfig object that is used by the game. Game configs sent by clients will be ignored.
RuntimePlayer RuntimePlayer Return a RuntimePlayer object that will be used for the client that created this room/session.

This only overwrites the first AddPlayer data sent for player slot 0. MaxPlayerSlots should be set to 1.
MaxPlayerSlots int The maximum number of player slots this client can acquire:
0 = only spectating
1..255 = specific number
-1 = unlimited

If this response is sent but this value is not set MaxPlayerSlots will default to 1.

Players requesting an invalid player slot number or more slots than allowed will be disconnected.
SnapshotsBlocked bool This player will not be selected for sending game snapshots to other players if there are other clients available.
StartPropertyBlockedTimeSec int Minimum delay in seconds before starting Quantum inside a room after its creation, ensuring players have enough time to join. A value greater than zero activates this feature.
StartPropertyForcedTimeSec int Maximum delay in seconds before starting Quantum inside a room after its creation. Exceeding this time auto-activates "StartQuantum" if not already set. A value greater than zero activates this feature.
HideRoomAfterStartSec int Number of seconds after which the room will be hidden from public listings once Quantum starts within the room. A value greater than zero activates this feature.
CloseRoomAfterStartSec int Number of seconds after which the room will be closed following the start of Quantum inside the room, preventing new players from joining. A value greater than zero activates this feature.

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "GameId": "0:eu:db757806-8570-45aa",
  "EnterRoomParams": {
    "RoomOptions": {
      "IsVisible": true,
      "IsOpen": true
    }
  },
  "SessionConfig": {
    "PlayerCount": 8,
    "ChecksumCrossPlatformDeterminism": false,
    "UpdateFPS": 30
  },
  "RuntimeConfig": {
    "Map": {
      "Id": {
        "Value": 94358348534
      }
    }
  },
  "RuntimePlayer": {
    "Name": "player1"
  },
  "MaxPlayerSlots": 2,
  "SnapshotsBlocked": true
}

JoinGame

JoinGameWebhookは、クライアントが既存のルームやゲームセッションに参加する前に送信されます。
参加を許可する場合は200を返し、キャンセルする場合は400を返してください。

このWebhookを有効にするには、PhotonアプリIDダッシュボードでWebHookBaseUrlWebHookEnableOnJoinを設定する必要があります。

JavaScript

POST https://{WebHookBaseUrl}/game/join

JoinGameリクエスト

Name Type Example Description
AppId string d1f67eec-51fb-45c1 Photon AppId
GameId string 0:eu:db757806-8570-45aa 一意のGameId
UserId string db757806-8570-45aa Photon UserId
AuthCookie Dictionary<string, object> db757806-8570-45aa バックエンドによって設定されたPhotonのカスタム認証クッキーです。

Jsonの例:

JSON

{
  "AppId": "*******************",
  "GameId": "0:eu:db757806-8570-45aa",
  "UserId": "db757806-8570-45aa",
  "AuthCookie": {
    "Secret": "**********"
  }
}

HTTP応答コード

Name Type Description
200 OK JoinGame Response クライアントがルームに参加します。
400 Bad Request WebhookError ルームへの参加は失敗します。

JoinGame応答

Name Type Description
RuntimePlayer RuntimePlayer Return a RuntimePlayer object that will be used for the client that created this room/session.

This only overwrites the first AddPlayer data sent for player slot 0. MaxPlayerSlots should be set to 1.
MaxPlayerSlots int The maximum number of player slots this client can acquire:
0 = only spectating
1..255 = specific number
-1 = unlimited

If this response is send but this value is not set MaxPlayerSlots will default to 1.

Players requesting an invalid player slot number or more slots than allowed will be disconnected.

Json Example:

JSON

{
  "RuntimePlayer": {
    "Name": "player1"
  },
  "MaxPlayerSlots": 1
}

Hint

Rather use AddPlayer to return the RuntimePlayer data, because its request will includes a RuntimePlayer client object sent by the client.

Also consider using the CreateGame response to reserve player slots for users (if they are already known at that time).

LeaveGame

LeaveGameWebhookは、クライアントが既存のルームまたはゲームセッションを離れた後に送信されます。

このWebhookを有効にするには、PhotonアプリIDダッシュボードでWebHookBaseUrlWebHookEnableOnLeaveを設定してください。

JavaScript

POST https://{WebHookBaseUrl}/game/leave

LeaveGameリクエスト

Name Type Example Description
AppId string d1f67eec-51fb-45c1 Photon AppId
GameId string 0:eu:db757806-8570-45aa 一意のGameId
UserId string db757806-8570-45aa Photon UserId
ActorNr int db757806-8570-45aa Photonサーバーが割り当てるアクター番号で、クライアントごとにインクリメントされるランタイムIDです。
AuthCookie Dictionary<string, object> db757806-8570-45aa Photon UserId
IsInactive bool db757806-8570-45aa プレイヤーがルームを離れたが、Player TTLが設定されている場合などで、まだ非アクティブとしてマークされているときに`true`に設定されます。この状態では、追加の`LeaveGame`リクエストが続けて送信されることがあります。

Jsonの例:

JSON

{
  "AppId": "*******************",
  "GameId": "0:eu:db757806-8570-45aa",
  "UserId": "db757806-8570-45aa",
  "ActorNr": 1,
  "AuthCookie": {
    "Secret": "**********"
  },
  "IsInactive": false
}

HTTP Response Codes

Name Type Description
200 OK LeaveGame Response 受信の確認のみ。
400 Bad Request WebhookError エラーが無視されます。Photon Cloudにログされるだけです。

LeaveGameレスポンス

Jsonの例:

JSON

{
  // empty
}

CloseGame

CloseGame webhookは、クライアント全員が退出した後、ルーム/ゲームセッションが閉じられると送信されます。
Photonダッシュボード上でWebHookBaseUrlおよびWebHookEnableOnCloseの設定が必須です。

JavaScript

POST https://{WebHookBaseUrl}/game/close

CloseGameリクエスト

Name Type Example Description
AppId string d1f67eec-51fb-45c1 The Photon AppId
GameId string 0:eu:db757806-8570-45aa Unique game id
CloseReason int (CloseReason) 0 The reason why this room/session has been closed.

Json Example:

JSON

{
  "GameId": "0:eu:db757806-8570-45aa",
  "CloseReason": 0
}

HTTP応答コード

Name Type Description
200 OK Confirmation of receipt.

CloseReason

Name Value Description
Ok 0 Session was closed without errors.
FailedOnCreate 1 Session was closed because it failed to Create.

GameConfigs

The GameConfigs webhook is sent when a player sent a StartRequest operation attached with the game configs RuntimeConfig and SessionConfig. Both config files are attached to the request body as Json objects.

This webhook is only send once per room upon the first arrival of any clients start operation.

Requires WebHookBaseUrl and WebHookEnableGameConfigs to be set on the Photon dashboard.

JavaScript

POST https://{WebHookBaseUrl}/game/configs

GameConfigs Request

Name Type Example Description
AppId string d1f67eec-51fb-45c1 The Photon AppId
GameId string 0:eu:db757806-8570-45aa Unique game id
UserId string db757806-8570-45aa Photon UserId
ActorNr int db757806-8570-45aa The Photon actor number, a incrementing runtime id for clients.
RuntimeConfig RuntimeConfig { "Level": 1 } The RuntimeConfig object sent by the client to the plugin. Can be null.
SessionConfig SessionConfig { "PlayerCount": 8, .. } The SessionConfig object sent by the client to the plugin. Can be null.
AuthCookie Dictionary<string, object> db757806-8570-45aa The Photon custom authentication cookie set by the backend.

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "GameId": "0:eu:db757806-8570-45aa",
  "UserId": "db757806-8570-45aa",
  "ActorNr": 1,
  "RuntimeConfig": {
    "Map": {
      "Id": {
        "Value": 94358348534
      }
    }
  },
  "SessionConfig": {
    "PlayerCount": 8,
    "ChecksumCrossPlatformDeterminism": false,
    "LockstepSimulation": false,
    //..  
  },
  "AuthCookie": {
    "Secret": "**********"
  }
}

HTTP Response Codes

Name Type Description
200 OK GameConfigs Response The game start sequence can continue. Game configs attached to response should be overwritten.
400 Bad Request WebhookError The game will be terminated and all clients are disconnected.

GameConfigs Response

Both objects on the response can be null to accept the configs that the client sent. Otherwise they will be overwritten.

Name Type Description
RuntimeConfig RuntimeConfig The RuntimeConfig object to overwrite the one the client sent.
SessionConfig SessionConfig The SessionConfig object to overwrite the one the client sent.

Json Example:

JSON

{
  "RuntimeConfig": {
    "Map": {
      "Id": {
        "Value": 94358348534
      }
    }
  },
  "SessionConfig": {
    "PlayerCount": 8,
    "ChecksumCrossPlatformDeterminism": false,
    "LockstepSimulation": false,
    //..  
  }
}

AddPlayer

The AddPlayer webhook is sent when a client tries to add a player to the Quantum online game using the AddPlayer operation.

Adding a player to the online game can still fail after this webhook returns when no player slot is free then. Use the PlayerAdded webhook to track the player online status.

Requires WebHookBaseUrl and WebHookEnableAddPlayer to be set on the Photon dashboard.

JavaScript

POST https://{WebHookBaseUrl}/player/add

AddPlayer Request

Name Type Example Description
AppId string d1f67eec-51fb-45c1 The Photon AppId
GameId string 0:eu:db757806-8570-45aa Unique game id
UserId string db757806-8570-45aa Photon UserId or ClientId
ActorNr int db757806-8570-45aa The Photon actor number, a incrementing runtime id for clients.
PlayerSlot int 0 Player slot requested. Usually is 0.
RuntimePlayer RuntimePlayer { "Foo": 222 } The RuntimePlayer object sent by the client to the plugin. Can be null.
AuthCookie Dictionary<string, object> db757806-8570-45aa The Photon custom authentication cookie set by the backend.

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "GameId": "0:eu:db757806-8570-45aa",
  "UserId": "db757806-8570-45aa", 
  "ActorNr": 1,
  "PlayerSlot": 0,
  "RuntimePlayer": {
    "Name": "player1"
  },
  "AuthCookie": {
    "Secret": "**********"
  }
}

HTTP Response Codes

Name Type Description
200 OK AddPlayer Response The client can add a player to the selected player slot and optionally received a RuntimePlayer object from the backend.
400 Bad Request WebhookError The client cannot add the player and will receive an error protocol message and callback: OnLocalPlayerAddFailed.

AddPlayer Response

Name Type Description
RuntimePlayer object The RuntimePlayer object to overwrite the RuntimePlayer that the client sent. If null the clients RuntimePlayer will be accepted.

Json Example:

JSON

{
  "RuntimePlayer": {
    "Name": "player1"
  }
}

PlayerAdded

The PlayerAdded webhook is send after a client successfully added a player to the online game.

Requires WebHookBaseUrl and WebHookEnablePlayerAdded to be set on the Photon dashboard.

JavaScript

POST https://{WebHookBaseUrl}/player/added

PlayerAdded Request

Name Type Example Description
AppId string d1f67eec-51fb-45c1 The Photon AppId
GameId string 0:eu:db757806-8570-45aa Unique game id
UserId string db757806-8570-45aa Photon UserId or ClientId
ActorNr int db757806-8570-45aa The Photon actor number, a incrementing runtime id for clients.
PlayerSlot int 0 The (local) player slot that the client reserved.
Player int 21 The (global) Player id that the client received.
AuthCookie Dictionary<string, object> db757806-8570-45aa The Photon custom authentication cookie set by the backend.

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "GameId": "0:eu:db757806-8570-45aa",
  "UserId": "db757806-8570-45aa",
  "ActorNr": 1,
  "PlayerSlot": 0,
  "Player": 21,
  "AuthCookie": {
    "Secret": "**********"
  }
}

HTTP Response Codes

Name Type Description
200 OK Confirmation of receipt.

PlayerRemoved

The PlayerRemoved webhook is sent when a client was removed from the online game.

Requires WebHookBaseUrl and WebHookEnablePlayerRemoved to be set on the Photon dashboard.

JavaScript

POST https://{WebHookBaseUrl}/player/removed

PlayerRemoved Request

Name Type Example Description
AppId string d1f67eec-51fb-45c1 The Photon AppId
GameId string 0:eu:db757806-8570-45aa Unique game id
UserId string db757806-8570-45aa Photon UserId or ClientId
ActorNr int db757806-8570-45aa The Photon actor number, a incrementing runtime id for clients.
PlayerSlot int 0 The (local) player slot.
Player int 21 The (global) Player id.
Reason int 0 The reason why the player was removed from the game.

0 = Requested
1 = ClientDisconnected
2 = Error
AuthCookie Dictionary<string, object> db757806-8570-45aa The Photon custom authentication cookie set by the backend.

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "GameId": "0:eu:db757806-8570-45aa",
  "UserId": "db757806-8570-45aa",
  "ActorNr": 1,
  "PlayerSlot": 0,
  "Player": 21,
  "Reason": 0,
  "AuthCookie": {
    "Secret": "**********"
  }
}

HTTP Response Codes

Name Type Description
200 OK Confirmation of receipt.

GameResult

Using the GameResult Quantum event in the simulation will trigger the upload of a GameResult instance by clients to the Quantum server once per game.

The results are aggregated and forwarded as the GameResult webhook when the game/room is closed. Because lingering clients and RoomTTL can prolong closing the room, there can be a delay between the game ending and the result webhook.

Requires WebHookBaseUrl and WebHookEnableGameResult to be set on the Photon dashboard.

Note:

  • The GameResult webhook supports both standard JSON format and binary payloads using base64 encoding.
  • Dictionaries are not supported, due to Unity serialization limitations. Quantum relies on Unity's built-in serialization system, which does not support Dictionary<,> types. These fields will be ignored or cause deserialization failures if present.

Requires WebHookBaseUrl and WebHookEnableGameResult to be set on the Photon dashboard.

If the server is running the simulation the webhooks are executed immediately from the server simulation and can be used as a reliable and trusted source of game results.

JavaScript

POST https://{WebHookBaseUrl}/game/result

Replays

The game result can also be used inside a replay by registering to EventGameResult .

C#

var eventDispatcher = new EventDispatcher();
eventDispatcher.SubscribeManual((EventGameResult e) => {
  if (e.Game?.Session != null) {
    // Handle result and stop replay
  }
});

GameResult Request

Name Type Example Description
AppId string d1f67eec-51fb-45c1 The Photon AppId
GameId string 0:eu:db757806-8570-45aa Unique game id
Results GameResultInfo[] see below The aggregated game results

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "GameId": "0:eu:db757806-8570-45aa",
  "Results": [
      {
          "Clients": [
              {
                  "UserId": "FJEH43FL56FSDR",
                  "Players": [
                      0
                  ],
                  "GameTime": 63.3636703
              }
          ],
          "Result": {
              "$type": "Quantum.GameResult, Quantum.Simulation",
              "Frame": 12010
              "Winner": 2
          },
          "IsServerResult": false
      }
  ],
  "UserId": "0"
}

HTTP Response Codes

Name Description
200 OK Confirmation of receipt

GameResultInfo

Name Type Description
Result GameResult The game specific game result Json object that the listed clients sent
Clients GameResultClientInfo[] The list of clients that generated this result
IsServerResult bool Has this result been generated by server simulation

GameResultClientInfo

Name Type Description
UserId string The Photon user id
Players int[] The list of players that this user controls
GameTime float The timestamp when the result reached the server

ReplayStart

The ReplayStart webhook is sent when the simulation and the input recording is starting on the server. It's is a trusted source for capturing the game replay directly from the server instead of relying on clients to send it to a developers backend.

This webhook has to be answered with the ReplayStartResponse which can signal the replay streaming to be skipped for this particular game session.

A response has to be received by the Quantum server before it is sending its first replay slice or the replay recording will be canceled.

Requires WebHookBaseUrl and WebHookEnableReplay to be set on the Photon dashboard.

JavaScript

POST https://{WebHookBaseUrl}/replay/start

ReplayStart Request

Name Type Description
AppId string The Photon AppId.
AppVersion string The AppVersion used when creating the room/game session.
Region string The Region code of the Game Server that the room/game session was created in.
Cloud string The Cloud Id of that the Game Server is running on.
RoomName string The room/game session Name.
GameId string A unique GameId which is composed of {Cloud:}{Region:}RoomName.
SessionConfig SessionConfig The SessionConfig that the simulation started with.
RuntimeConfig byte[] The GZipped Json of the RuntimeConfig that the simulation started with.

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "AppVersion": "1.0-live",
  "Region": "eu",
  "Cloud": "0:",
  "RoomName": "1.2-party-2349535735",
  "GameId": "0:eu:e472a861-a1e2-49f7",
  "SessionConfig": { },
  "RuntimeConfig": "H4sIAAAAAAAACnWNPQvCMBCG/4ocjkWuye
    X6sXZycNCCe8AogSYtNBlK6X/3UHQR4Zb35X2eW2GflslBC+ds
    Y8rhcMkx+eC6Md79o9h96t6HPNjkxwgF9M7doMUCTnaCdoWjpB
    WudshiUkxYsVHacE11KWe2TZiv4K3+4YjQkECKNJcVMuoXtszJ
    hfkPI1tUVc1sqFGN1g3Kr+0J+3ktedUAAAA="
}

HTTP Response Codes

Name Type Description
200 OK ReplayStart Response The replay streaming can start or be disabled when the Skip property is set.
400 Bad Request WebhookError In this case an error is logged on the server and the replay streaming is stopped.

ReplayStart Response

Name Type Description
Skip bool The replay streaming is disabled for this game session.

Json Example:

JSON

{
  "Skip": true
}

ReplayChunk

The ReplayChunk webhook is sent in intervals and it contains the delta compressed input history of a part of the simulation.

Requires WebHookBaseUrl and WebHookEnableReplay to be set on the Photon dashboard.

JavaScript

POST https://{WebHookBaseUrl}/replay/chunk

There are additional dashboard variables that configure the replay input streaming.

Dashboard Variable Type Description Default
WebHookReplayUseBinaryRequests bool The web request are not send as JSON content but as binary data. false
WebHookReplayUseCompression bool The input data on the chunks is GZip compressed. false
WebHookReplaySendIntervalInSec int The chunk send interval in seconds (min = 2, max = 40). 20

ReplayChunk Request

If WebHookReplayUseBinaryRequests is selected, then the following properties are part of the web request Headers instead of a JSON body. The body then will include the binary Input.

Name Type Description
AppId string The Photon AppId
GameId string The game id to identify the replay chunk.
ChunkNumber int The incrementing chunk number.
IsLast bool A flag that indicates that the last chunk has been send. Usually when a room closes.
LastTick int The oldest tick of input on this chunk.
TickCount int The number of ticks of input on this chunk.
TickCountTotal int The total incrementing number of ticks in the whole replay.
IsCompressed bool A flag indicating the input is GZip compressed.
Input byte[] The binary delta compressed input that needs to be appended to the complete input stream for this replay. The input for each tick has a leading int describing the data length. It can be stored in the ReplayFile.InputHistoryRaw field to be readable with the QuantumRunnerLocalReplay script in Unity.

Json Example:

JSON

{
  "AppId": "d1f67eec-51fb-45c1",
  "GameId": ":eu:e472a861-a1e2-49f7",
  "ChunkNumber": 0,
  "IsLast": false,
  "LastTick": 302,
  "TickCount": 243,
  "TickCountTotal": 243,
  "IsCompressed": false,
  "Input": "JQAAADwAAAAIAAMKFsCUwYDggOB/UCAAAPgfDMhgEoAHA////4PRBwATAAAAPQAAAAgAA2PaSK"
}

HTTP Response Codes

Name Type Description
200 OK Confirmation of receipt.
400 Bad Request WebhookError In this case an error is logged on the server and the replay streaming is stopped.

WebhookError

Name Type Description
Status int HTTPステータスコード
Error string エラー名
Message string エラーメッセージ

Jsonの例:

JSON

{
  "Status": 400,
  "Error": "PlayerNotAllowed",
  "Message": "LoremIpsum"
}

Quantum Classes

RuntimeConfig

Quantum 3 runtime configuration files RuntimeConfig and RuntimePlayer are uploaded by the clients using Json serialization. This way it is possible to send configurations to the Quantum public cloud game servers while it does not know the implementation and serialization details.

When RuntimeConfig or RuntimePlayer are used in a webhook response they need to be complete because the configs send by clients are completely replaced.

Json data sent by the custom backend has to be deterministically deserializable on every client.

Quantum internal classes usually operate with fields, make sure that the Json serialization and deserialization code needs to IncludeFields = true and IgnoreReadOnlyProperties = true.

A simple example of the RuntimeConfig class. Additionally to the partial declaration the base class adds a couple properties as well (Seed, Map, SimulationConfig, SystemsConfig).

The $type property is required for deserialization on the standalone or custom plugin.

C#

namespace Quantum {
  public partial class RuntimeConfig {
    public int GameMode;
  }
}

Json Example:

JSON

{
  "$type": "Quantum.RuntimeConfig, Quantum.Simulation",
  "GameMode": 1,
  "Seed": 0,
  "Map": {
    "Id": {
      "Value":2640765235684814815
      }
  },
  "SimulationConfig": {
    "Id": { 
      "Value":440543562436170603
    }
  },
  "SystemsConfig": {
    "Id": { 
      "Value":2430278665492933905
    }
  }
}

RuntimePlayer

C#

namespace Quantum {
  public partial class RuntimePlayer {
    public AssetRef<GearConfig> Loadout;
  }
}

Json Example:

JSON

{
  "$type":"Quantum.RuntimePlayer, Quantum.Simulation",
  "Loadout": {
    "Id": {
      "Value": 440543562436170603
    }
  },
  "PlayerAvatar": {
    "Id": {
      "Value": 2430278665492933905
    }
  },
  "PlayerNickname": "foo"
}

SessionConfig

SessionConfig is the abbreviation of the DeterministicSessionConfig class.

When a SessionConfig is returned by an webhook it needs to be complete because single values are not replaced.

The current SessionConfig asset can be exported in Unity using this menu entry:

Unity Editor > Quantum > Export > SessionConfig (Json)

When serializing the class on netcoreapp3.1 either use Newtonsoft or use DeterministicSessionConfigJsonConverter for Text.Json. Because "including fields" is a feature of net5.

Json Example:

JSON

{
  "PlayerCount": 8,
  "ChecksumCrossPlatformDeterminism": false,
  "LockstepSimulation": false,
  "InputDeltaCompression": true,
  "UpdateFPS": 60,
  "ChecksumInterval": 60,
  "RollbackWindow": 60,
  "InputHardTolerance": 8,
  "InputRedundancy": 3,
  "InputRepeatMaxDistance": 10,
  "SessionStartTimeout": 1,
  "TimeCorrectionRate": 4,
  "MinTimeCorrectionFrames": 1,
  "MinOffsetCorrectionDiff": 1,
  "TimeScaleMin": 100,
  "TimeScalePingMin": 100,
  "TimeScalePingMax": 300,
  "InputDelayMin": 0,
  "InputDelayMax": 60,
  "InputDelayPingStart": 100,
  "InputFixedSizeEnabled": true,
  "InputFixedSize": 24
}

GameResult Event

The GameResult class can be extended by adding fields using the partial class declaration inside the GameResult.User.cs script. It will be Json serialized on the client and send to the Quantum server.

C#

namespace Quantum {
  public partial class GameResult {
    public int Winner;
  }
}

Json Example:

JSON

{
  "$type":"Quantum.GameResult, Quantum.Simulation",
  "Frame": 200,
  "Winner": 2
}

The game result event can be invoked once per game by each client, which is triggered from inside the simulation by calling the GameResult Quantum event. The actual webhook is launched when the room is disbanded and closed.

C#

f.Events.GameResult(new GameResult { Winner = 3 });

When running an enterprise Photon Quantum cloud with server simulation this will be transparently send by the server for a trusted source of game results.

Photon Realtime Classes

EnterRoomParams

この定義は、Photon RealtimeのEnterRoomParamsクラスに似せて設計されています。CreateGameWebhookで設定可能なすべてのオプションを含んでいます。JSONレスポンスを作成する際は、すべてのメンバーが任意であり、nullまたは未設定にすることも可能です。

Name Type Description
RoomOptions RoomOptions RoomOptionsオブジェクト
ExpectedUsers string[] ルームまたはセッションに参加を許可するUserIdsの一覧です(ルームを作成したユーザーに加えて)。
もしMaxPlayersが記載されたExpectedUsersの数より大きい場合は、未予約の枠に任意のプレイヤーが参加して埋めることができます。

これはRoomJoin()のみに有効で、JoinRandom()には適用されません。

Jsonの例:

JSON

{
  "RoomOptions": {
    "IsVisible": true,
    "IsOpen": true,
    "MaxPlayers": 8,
    "PlayerTtl": null,
    "EmptyRoomTtl": 10000,
    "CustomRoomProperties": {
      "Foo": "bar",
      "PlayerClass": 1
    },
    "CustomRoomPropertiesForLobby": [
      "Foo"
    ],
    "SuppressRoomEvents": null,
    "SuppressPlayerInfo": null,
    "PublishUserId": null,
    "DeleteNullProperties": null,
    "BroadcastPropsChangeToAll": null,
    "CleanupCacheOnLeave": null,
    "CheckUserOnJoin": null
  },
  "ExpectedUsers": [
    "A",
    "B",
    "C"
  ]
}

RoomOptions

すべての値はnull許容型であり、Quantumサーバーに返信する際にnullに設定したり、省略したりすることが可能です。その場合、このレスポンスは該当するルームプロパティを変更せず、デフォルトの値のままか、ルーム作成時にクライアントが送信した値が維持されます。

Name Type Description
IsVisible bool このルームがPhotonのマッチメイキングにリストされるかどうかを定義します。
IsOpen bool このルームに他のクライアントが参加できるかどうかを定義します。
MaxPlayers byte 任意の時点でルーム内に入れる最大プレイヤー数です。0は「制限なし」を意味します。
PlayerTtl int ルーム内の「アクター」の生存時間(TTL)をミリ秒単位で設定します。クライアントが切断された場合、このアクターは最初に非アクティブとなり、指定されたタイムアウト後に削除されます。
EmptyRoomTtl int 最後のプレイヤーが退室した後のルームの生存時間(TTL)をミリ秒単位で設定します。これは、プレイヤーが近いうちに再参加する場合にルームをメモリ内に保持しておくためのものです。
CustomRoomProperties Dictionary <string, object> ルーム作成時に設定されるカスタムプロパティです。
CustomRoomPropertiesForLobby string[] ロビーにリストされるカスタムルームプロパティを定義します。

これらのプロパティの値の型は bool, byte, short, int, long または stringである必要があります。

最大プロパティ数は 3 です。

文字列値の最大長は 64 文字です。

キーの制限は、Photonダッシュボードの設定AllowedLobbyPropertiesによっても適用可能です。
SuppressRoomEvents bool サーバーに対して、参加および退出するプレイヤーのルームイベントをスキップするよう指示します。

デフォルトは false です。
SuppressPlayerInfo bool サーバー側での参加と退出のイベントおよびルーム内のプロパティブロードキャストを無効にします(通信量を最小化するため)。

デフォルトは false です。
PublishUserId bool プレイヤーのUserIdsをルーム内で「公開」するかどうかを設定します。
これは、FindFriendsの機能を利用したり、プレイヤー同士が別のゲームで一緒にプレイしたい場合に役立ちます。

デフォルトは false です。
DeleteNullProperties bool オプションとして、値に null を割り当てると、そのプロパティが削除されます。

デフォルトは false です。/td>

PlayFab

PlayFabと連携させるには、WebHookIntegrationダッシュボード変数を追加し、その値をPlayFabに設定してください。

  • パス内のすべてのスラッシュ(/)はアンダースコア(_)に置き換えられます。例:game/creategame_create
  • すべてのWebhookリクエストには、WebHooksConfig.AppIdによって制御されるAppIdプロパティが自動的に追加されます(欠落している場合)。
  • すべてのWebhookリクエストには、UserIdプロパティが自動的に追加され、欠落している場合は"0"が設定されます。
  • Webhookのレスポンスは、以下のJson結果ボディを処理し、ResultCodeが0以外の場合にWebhookを失敗とみなします。エラー時には、MessageWebHookError.Messageにコピーされます。

JSON

{
    "ResultCode": 0,
    "Message": "success"
}

Photon CloudのWebリクエスト制限

デフォルトでは、PhotonサーバーはHTTPリクエストを直列に管理し、現在のリクエストが完了するまで新たなリクエストは開始されません。新しいリクエストはキューに追加されます。この制限は各ルームごとに適用されます。

このため、OnJoinやAddPlayerのWebhookを使用している場合、高いプレイヤー数やPhotonクラウドとカスタムバックエンド間のラウンドトリップタイムが長い場合に、予期しない待ち時間が発生する可能性があります。

並列リクエストはエンタープライズクラウドで有効にでき、また、公開クラウドアプリ向けにも選択制の対応を検討中です。

その他の制限は以下の通りです。

  • HttpRequestTimeout: 30000
  • LimitHttpResponseMaxSize: 200000
  • MaxQueuedRequests: 5000
Back to top