GamesPlayerLeftPayload games.player.left@1
Generated at from
openvibe-contracts v0.34.2 and
openvibe-sdk v0.5.0.
- Version
- 1.0.0
- Owner
- games
- Visibility
- first-party
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/events/payloads/games.player.left.v1.json
games.player.left v1 (OpenVibe.Games apps/server/src/platform/gameEvents.ts playerLeftEvent, via GameEventRecorder.recordLeave from game/gameServer.ts onDisconnect -> savePlayer(session, true)). A character's connection closed: written in the same transaction as its final save, after any games.skill.leveled / games.blueprint.unlocked that save produced. session_seconds is the time since its games.player.joined in this process, rounded to whole seconds; 0 when the join was not tracked. No position, appearance, inventory, rank or connection data. Envelope: subject { type: player, id: <player.id> }, visibility subject when the player has a Network subject and internal otherwise, priority low, actor user:<usr_...> or guest:<gst_...> from player.subject, else service:games. No consumer yet.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
player | one of | yes | The character. account network: a signed-in openvibe.network account, keyed by its canonical subject (user usr_..., or guest gst_... for a Network guest session). account guest: a local guest (browser token), or a Network sign-in whose token predates subject ids; no subject then. | |
world | string | yes | World id (the loaded content world, e.g. openvibeville_v2). Also the envelope subject id of games.world.saved. | |
session_seconds | integer | yes |
|
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: guest-untracked
{
"player": {
"id": "01kz4a7r2p9b6g3e8v0z",
"slot": 0,
"name": "Guest 42",
"account": "guest"
},
"world": "openvibeville_v2",
"session_seconds": 0
}Valid: network
{
"player": {
"id": "01kz3m8q4d7xw2ht5n9c",
"slot": 1,
"name": "Rustbucket",
"account": "network",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
},
"world": "openvibeville_v2",
"session_seconds": 1834
}Rejected: extra-property
{
"player": {
"id": "01kz3m8q4d7xw2ht5n9c",
"slot": 1,
"name": "Rustbucket",
"account": "network",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
},
"world": "openvibeville_v2",
"session_seconds": 10,
"restored": true
}Rejected: fractional-seconds
{
"player": {
"id": "01kz3m8q4d7xw2ht5n9c",
"slot": 1,
"name": "Rustbucket",
"account": "network",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
},
"world": "openvibeville_v2",
"session_seconds": 61.4
}Rejected: slot-out-of-range
{
"player": {
"id": "01kz3m8q4d7xw2ht5n9c",
"slot": 3,
"name": "Rustbucket",
"account": "network",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
},
"world": "openvibeville_v2",
"session_seconds": 10
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('games.player.left@1', value); // { valid, errors: [{ path, message }] }