@indiegems/gem-web-sdk 10.4.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/function.d.ts +3 -0
- package/dist/game.d.ts +7 -2
- package/dist/gem-web-sdk.bridge.js +1 -1
- package/dist/gem-web-sdk.esm.js +2 -2
- package/dist/gem-web-sdk.function.js +2 -2
- package/dist/gem-web-sdk.game.js +2 -2
- package/dist/gem-web-sdk.min.js +2 -2
- package/dist/gem-web-sdk.sdk.js +2 -2
- package/dist/gem-web-sdk.server.js +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/sdk.d.ts +13 -2
- package/dist/server-api.d.ts +6 -0
- package/dist/server.d.ts +6 -0
- package/docs/api/api-reference-game.md +377 -19
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +359 -9
- package/docs/changelog.md +17 -0
- package/docs/getting-started.md +1 -1
- package/docs/manifest.json +8 -8
- package/docs/server-bundles.md +2 -2
- package/docs/what-a-game-must-do.md +69 -19
- package/package.json +1 -1
- package/schema/bridge.v1.json +79 -6
package/docs/api/reference.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schema_version": 2,
|
|
3
3
|
"source": {
|
|
4
4
|
"repo": "IndieGems/gem-web-sdk",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "11.0.0"
|
|
6
6
|
},
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -6632,11 +6632,18 @@
|
|
|
6632
6632
|
"name": "requestAvatarPicker",
|
|
6633
6633
|
"anchor": "gemframe-requestavatarpicker",
|
|
6634
6634
|
"group": "frame",
|
|
6635
|
-
"signature": "requestAvatarPicker(): boolean",
|
|
6635
|
+
"signature": "requestAvatarPicker(tab?: \"2d\" | \"3d\"): boolean",
|
|
6636
6636
|
"documented": true,
|
|
6637
|
-
"summary": "Ask the arcade to open its own avatar picker over your game. Nothing comes\nback: a changed portrait arrives as a new `gem.player
|
|
6637
|
+
"summary": "Ask the arcade to open its own avatar picker over your game. Nothing comes\nback: a changed portrait or 3D character arrives as a new `gem.player`,\nthrough `onPlayer`.\n\nPrefer `gem.openAvatarPicker`, which documents what a game does with the\nchange.",
|
|
6638
6638
|
"deprecated": null,
|
|
6639
|
-
"params": [
|
|
6639
|
+
"params": [
|
|
6640
|
+
{
|
|
6641
|
+
"name": "tab",
|
|
6642
|
+
"type": "\"2d\" | \"3d\"",
|
|
6643
|
+
"optional": true,
|
|
6644
|
+
"summary": "Which tab to open on — `'2d'` (the portrait) or `'3d'` (the 3D\n character). Omit it to let the arcade decide. Anything else is treated as\n omitted. An arcade older than the tabs ignores it."
|
|
6645
|
+
}
|
|
6646
|
+
],
|
|
6640
6647
|
"returns": "whether the message left the frame — `false` before the bridge is\n up, for an arcade that has no avatar picker here, and past this frame's\n own limit of six a minute.",
|
|
6641
6648
|
"throws": null,
|
|
6642
6649
|
"example": null,
|
|
@@ -6824,6 +6831,54 @@
|
|
|
6824
6831
|
"defaultValue": null,
|
|
6825
6832
|
"guides": []
|
|
6826
6833
|
},
|
|
6834
|
+
{
|
|
6835
|
+
"id": "Friend.avatar3dId",
|
|
6836
|
+
"name": "avatar3dId",
|
|
6837
|
+
"anchor": "friend-avatar3did",
|
|
6838
|
+
"group": "friends",
|
|
6839
|
+
"signature": "readonly avatar3dId?: string",
|
|
6840
|
+
"documented": true,
|
|
6841
|
+
"summary": "The id of the 3D character the player wears, when they wear one — an\nArcade item of type `avatar_3d`, chosen on the 3D tab of the Arcade's\navatar picker. What a game that draws Arcade avatars keys its character\non: prefer it, load [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl), and fall back\nto your own mapping of [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) when it is\nabsent.\n\nIndependent of the portrait: wearing a 3D character never changes\n`avatarIconId`, and the other way round. Absent means the game's default\nlook. On `gem.player` it changes when the player wears another one, and\n`onPlayer` runs again; see `gem.openAvatarPicker`.",
|
|
6842
|
+
"deprecated": null,
|
|
6843
|
+
"params": [],
|
|
6844
|
+
"returns": null,
|
|
6845
|
+
"throws": null,
|
|
6846
|
+
"example": null,
|
|
6847
|
+
"defaultValue": null,
|
|
6848
|
+
"guides": []
|
|
6849
|
+
},
|
|
6850
|
+
{
|
|
6851
|
+
"id": "Friend.avatar3dModelUrl",
|
|
6852
|
+
"name": "avatar3dModelUrl",
|
|
6853
|
+
"anchor": "friend-avatar3dmodelurl",
|
|
6854
|
+
"group": "friends",
|
|
6855
|
+
"signature": "readonly avatar3dModelUrl?: string",
|
|
6856
|
+
"documented": true,
|
|
6857
|
+
"summary": "The worn 3D character's model — a binary glTF (`.glb`) with one rig,\n`root > body > (head, arm_l, arm_r > hand_socket, leg_l, leg_r)`, and\npossibly animation clips. Load it with three.js's `GLTFLoader`, after\npassing it through [platformIconUrl](api-reference-game.md#platformiconurl), which pins models to the\nplatform's item host exactly as it pins pictures. Absent when no 3D\ncharacter is worn.",
|
|
6858
|
+
"deprecated": null,
|
|
6859
|
+
"params": [],
|
|
6860
|
+
"returns": null,
|
|
6861
|
+
"throws": null,
|
|
6862
|
+
"example": null,
|
|
6863
|
+
"defaultValue": null,
|
|
6864
|
+
"guides": []
|
|
6865
|
+
},
|
|
6866
|
+
{
|
|
6867
|
+
"id": "Friend.avatar3dIconUrl",
|
|
6868
|
+
"name": "avatar3dIconUrl",
|
|
6869
|
+
"anchor": "friend-avatar3diconurl",
|
|
6870
|
+
"group": "friends",
|
|
6871
|
+
"signature": "readonly avatar3dIconUrl?: string",
|
|
6872
|
+
"documented": true,
|
|
6873
|
+
"summary": "A rendered portrait of the worn 3D character, for a roster or a menu where\nloading the model is too much. Not the 2D portrait\n([PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)), which is a separate choice. Pass it\nthrough [platformIconUrl](api-reference-game.md#platformiconurl) before putting it in an `<img src>`.",
|
|
6874
|
+
"deprecated": null,
|
|
6875
|
+
"params": [],
|
|
6876
|
+
"returns": null,
|
|
6877
|
+
"throws": null,
|
|
6878
|
+
"example": null,
|
|
6879
|
+
"defaultValue": null,
|
|
6880
|
+
"guides": []
|
|
6881
|
+
},
|
|
6827
6882
|
{
|
|
6828
6883
|
"id": "Friend.badges",
|
|
6829
6884
|
"name": "badges",
|
|
@@ -8594,6 +8649,54 @@
|
|
|
8594
8649
|
"defaultValue": null,
|
|
8595
8650
|
"guides": []
|
|
8596
8651
|
},
|
|
8652
|
+
{
|
|
8653
|
+
"id": "GemPlayer.avatar3dId",
|
|
8654
|
+
"name": "avatar3dId",
|
|
8655
|
+
"anchor": "gemplayer-avatar3did",
|
|
8656
|
+
"group": "player",
|
|
8657
|
+
"signature": "readonly avatar3dId?: string",
|
|
8658
|
+
"documented": true,
|
|
8659
|
+
"summary": "The id of the 3D character the player wears, when they wear one — an\nArcade item of type `avatar_3d`, chosen on the 3D tab of the Arcade's\navatar picker. What a game that draws Arcade avatars keys its character\non: prefer it, load [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl), and fall back\nto your own mapping of [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) when it is\nabsent.\n\nIndependent of the portrait: wearing a 3D character never changes\n`avatarIconId`, and the other way round. Absent means the game's default\nlook. On `gem.player` it changes when the player wears another one, and\n`onPlayer` runs again; see `gem.openAvatarPicker`.",
|
|
8660
|
+
"deprecated": null,
|
|
8661
|
+
"params": [],
|
|
8662
|
+
"returns": null,
|
|
8663
|
+
"throws": null,
|
|
8664
|
+
"example": null,
|
|
8665
|
+
"defaultValue": null,
|
|
8666
|
+
"guides": []
|
|
8667
|
+
},
|
|
8668
|
+
{
|
|
8669
|
+
"id": "GemPlayer.avatar3dModelUrl",
|
|
8670
|
+
"name": "avatar3dModelUrl",
|
|
8671
|
+
"anchor": "gemplayer-avatar3dmodelurl",
|
|
8672
|
+
"group": "player",
|
|
8673
|
+
"signature": "readonly avatar3dModelUrl?: string",
|
|
8674
|
+
"documented": true,
|
|
8675
|
+
"summary": "The worn 3D character's model — a binary glTF (`.glb`) with one rig,\n`root > body > (head, arm_l, arm_r > hand_socket, leg_l, leg_r)`, and\npossibly animation clips. Load it with three.js's `GLTFLoader`, after\npassing it through [platformIconUrl](api-reference-game.md#platformiconurl), which pins models to the\nplatform's item host exactly as it pins pictures. Absent when no 3D\ncharacter is worn.",
|
|
8676
|
+
"deprecated": null,
|
|
8677
|
+
"params": [],
|
|
8678
|
+
"returns": null,
|
|
8679
|
+
"throws": null,
|
|
8680
|
+
"example": null,
|
|
8681
|
+
"defaultValue": null,
|
|
8682
|
+
"guides": []
|
|
8683
|
+
},
|
|
8684
|
+
{
|
|
8685
|
+
"id": "GemPlayer.avatar3dIconUrl",
|
|
8686
|
+
"name": "avatar3dIconUrl",
|
|
8687
|
+
"anchor": "gemplayer-avatar3diconurl",
|
|
8688
|
+
"group": "player",
|
|
8689
|
+
"signature": "readonly avatar3dIconUrl?: string",
|
|
8690
|
+
"documented": true,
|
|
8691
|
+
"summary": "A rendered portrait of the worn 3D character, for a roster or a menu where\nloading the model is too much. Not the 2D portrait\n([PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)), which is a separate choice. Pass it\nthrough [platformIconUrl](api-reference-game.md#platformiconurl) before putting it in an `<img src>`.",
|
|
8692
|
+
"deprecated": null,
|
|
8693
|
+
"params": [],
|
|
8694
|
+
"returns": null,
|
|
8695
|
+
"throws": null,
|
|
8696
|
+
"example": null,
|
|
8697
|
+
"defaultValue": null,
|
|
8698
|
+
"guides": []
|
|
8699
|
+
},
|
|
8597
8700
|
{
|
|
8598
8701
|
"id": "GemPlayer.badges",
|
|
8599
8702
|
"name": "badges",
|
|
@@ -9756,11 +9859,18 @@
|
|
|
9756
9859
|
"name": "openAvatarPicker",
|
|
9757
9860
|
"anchor": "gem-openavatarpicker",
|
|
9758
9861
|
"group": "start",
|
|
9759
|
-
"signature": "openAvatarPicker(): boolean",
|
|
9862
|
+
"signature": "openAvatarPicker(options?: { tab?: \"2d\" | \"3d\" }): boolean",
|
|
9760
9863
|
"documented": true,
|
|
9761
|
-
"summary": "Open the arcade's avatar picker over your game, so the player can change\nthe Arcade avatar they wear without leaving it. For a game that draws\nArcade avatars — whole characters the player owns as Arcade items — put a\n\"Change avatar\" button in your own UI and call this from it:\n\n```js\nchangeAvatar.hidden = !gem.avatarPickerAvailable;\nchangeAvatar.onclick = () => {\n if (!gem.openAvatarPicker()) changeAvatar.hidden = true;\n};\n```\n\n**The change arrives as a new player, not as an answer.** Nothing comes\nback from this call. When the player picks a different avatar, the arcade\npauses your game while the picker is open, then sends the player again —\nyour `onPlayer` callback runs and [Gem.player](api-reference-game.md#gem-player) holds the new\n[PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid)
|
|
9864
|
+
"summary": "Open the arcade's avatar picker over your game, so the player can change\nthe Arcade avatar they wear without leaving it. For a game that draws\nArcade avatars — whole characters the player owns as Arcade items — put a\n\"Change avatar\" button in your own UI and call this from it:\n\n```js\nchangeAvatar.hidden = !gem.avatarPickerAvailable;\nchangeAvatar.onclick = () => {\n if (!gem.openAvatarPicker()) changeAvatar.hidden = true;\n};\n```\n\n**Two tabs: 2D and 3D.** The picker has a 2D tab — the portrait, a\npicture ([PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid)) — and a 3D tab — a whole\ncharacter with its own model ([PlayerIdentity.avatar3dId](api-reference-game.md#playeridentity-avatar3did),\n[PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl)). They are separate choices: wearing\none never changes the other. Pass `{ tab: '3d' }` or `{ tab: '2d' }` to\nopen on one; omit it and the arcade decides (a game that draws Arcade\navatars gets the 3D tab). An arcade older than the tabs ignores it.\n\n**The change arrives as a new player, not as an answer.** Nothing comes\nback from this call. When the player picks a different avatar, the arcade\npauses your game while the picker is open, then sends the player again —\nyour `onPlayer` callback runs and [Gem.player](api-reference-game.md#gem-player) holds the new\n[PlayerIdentity.avatar3dId](api-reference-game.md#playeridentity-avatar3did) or [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) —\nand resumes it. Redraw from `onPlayer`, which also runs when the player\nchanges their avatar from the arcade's own menu without your game asking.\nA player who closes the picker unchanged produces nothing at all.\n\n**Your server learns it only when it reads the room again.** A\nserver-authoritative game reads each member's `avatar_3d_id` and\n`avatar_icon_id` from the room read\n(`GET /v1/games/{game_id}/game-rooms/{game_room_id}`, or `gem.room.get()`\non a dedicated server); nothing tells the server the player changed. So\nwhen `onPlayer` brings a different avatar, have your client tell your\nserver, and have the server re-read the room — never trust the id the\nclient sends.",
|
|
9762
9865
|
"deprecated": null,
|
|
9763
|
-
"params": [
|
|
9866
|
+
"params": [
|
|
9867
|
+
{
|
|
9868
|
+
"name": "options",
|
|
9869
|
+
"type": "{ tab?: \"2d\" | \"3d\" }",
|
|
9870
|
+
"optional": true,
|
|
9871
|
+
"summary": "`tab` — `'2d'` or `'3d'`, the tab to open on. Omit it to let\n the arcade decide; any other value is treated as omitted."
|
|
9872
|
+
}
|
|
9873
|
+
],
|
|
9764
9874
|
"returns": "`true` when the arcade was asked; `false` when it was not and\n never will be for this call — outside the arcade, before the bridge is\n up, under an embedder with no avatar picker, or past six asks a minute.\n It never throws and never waits.",
|
|
9765
9875
|
"throws": null,
|
|
9766
9876
|
"example": null,
|
|
@@ -11419,6 +11529,54 @@
|
|
|
11419
11529
|
"defaultValue": null,
|
|
11420
11530
|
"guides": []
|
|
11421
11531
|
},
|
|
11532
|
+
{
|
|
11533
|
+
"id": "PlayerIdentity.avatar3dId",
|
|
11534
|
+
"name": "avatar3dId",
|
|
11535
|
+
"anchor": "playeridentity-avatar3did",
|
|
11536
|
+
"group": "player",
|
|
11537
|
+
"signature": "readonly avatar3dId?: string",
|
|
11538
|
+
"documented": true,
|
|
11539
|
+
"summary": "The id of the 3D character the player wears, when they wear one — an\nArcade item of type `avatar_3d`, chosen on the 3D tab of the Arcade's\navatar picker. What a game that draws Arcade avatars keys its character\non: prefer it, load [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl), and fall back\nto your own mapping of [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) when it is\nabsent.\n\nIndependent of the portrait: wearing a 3D character never changes\n`avatarIconId`, and the other way round. Absent means the game's default\nlook. On `gem.player` it changes when the player wears another one, and\n`onPlayer` runs again; see `gem.openAvatarPicker`.",
|
|
11540
|
+
"deprecated": null,
|
|
11541
|
+
"params": [],
|
|
11542
|
+
"returns": null,
|
|
11543
|
+
"throws": null,
|
|
11544
|
+
"example": null,
|
|
11545
|
+
"defaultValue": null,
|
|
11546
|
+
"guides": []
|
|
11547
|
+
},
|
|
11548
|
+
{
|
|
11549
|
+
"id": "PlayerIdentity.avatar3dModelUrl",
|
|
11550
|
+
"name": "avatar3dModelUrl",
|
|
11551
|
+
"anchor": "playeridentity-avatar3dmodelurl",
|
|
11552
|
+
"group": "player",
|
|
11553
|
+
"signature": "readonly avatar3dModelUrl?: string",
|
|
11554
|
+
"documented": true,
|
|
11555
|
+
"summary": "The worn 3D character's model — a binary glTF (`.glb`) with one rig,\n`root > body > (head, arm_l, arm_r > hand_socket, leg_l, leg_r)`, and\npossibly animation clips. Load it with three.js's `GLTFLoader`, after\npassing it through [platformIconUrl](api-reference-game.md#platformiconurl), which pins models to the\nplatform's item host exactly as it pins pictures. Absent when no 3D\ncharacter is worn.",
|
|
11556
|
+
"deprecated": null,
|
|
11557
|
+
"params": [],
|
|
11558
|
+
"returns": null,
|
|
11559
|
+
"throws": null,
|
|
11560
|
+
"example": null,
|
|
11561
|
+
"defaultValue": null,
|
|
11562
|
+
"guides": []
|
|
11563
|
+
},
|
|
11564
|
+
{
|
|
11565
|
+
"id": "PlayerIdentity.avatar3dIconUrl",
|
|
11566
|
+
"name": "avatar3dIconUrl",
|
|
11567
|
+
"anchor": "playeridentity-avatar3diconurl",
|
|
11568
|
+
"group": "player",
|
|
11569
|
+
"signature": "readonly avatar3dIconUrl?: string",
|
|
11570
|
+
"documented": true,
|
|
11571
|
+
"summary": "A rendered portrait of the worn 3D character, for a roster or a menu where\nloading the model is too much. Not the 2D portrait\n([PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)), which is a separate choice. Pass it\nthrough [platformIconUrl](api-reference-game.md#platformiconurl) before putting it in an `<img src>`.",
|
|
11572
|
+
"deprecated": null,
|
|
11573
|
+
"params": [],
|
|
11574
|
+
"returns": null,
|
|
11575
|
+
"throws": null,
|
|
11576
|
+
"example": null,
|
|
11577
|
+
"defaultValue": null,
|
|
11578
|
+
"guides": []
|
|
11579
|
+
},
|
|
11422
11580
|
{
|
|
11423
11581
|
"id": "PlayerIdentity.badges",
|
|
11424
11582
|
"name": "badges",
|
|
@@ -11442,7 +11600,7 @@
|
|
|
11442
11600
|
"group": "player",
|
|
11443
11601
|
"signature": "function mapIdentity(row: unknown): PlayerIdentity",
|
|
11444
11602
|
"documented": true,
|
|
11445
|
-
"summary": "Map one row's identity fields, as the platform's API sends them, to\n[PlayerIdentity](api-reference-game.md#playeridentity).\n\nEvery surface this SDK names maps its rows through this already. You need it\nonly for a row you fetched yourself through the raw client — an async\nopponent, for instance:\n\n```js\nimport { mapIdentity, text } from '@indiegems/gem-web-sdk/sdk';\n\nconst { opponents } = await gem.client.get('/v1/async-opponents?opponent_type=ghost-lap');\nfor (const row of opponents) {\n const who = mapIdentity(row);\n label(who.displayName ? text.toPlain(who.displayName) : 'Anonymous player');\n}\n```\n\nReads `player_id`, `display_name`, `discriminator`, `display_tag`,\n`avatar_icon_id`, `avatar_icon_url` and `badges`, and nothing else from the
|
|
11603
|
+
"summary": "Map one row's identity fields, as the platform's API sends them, to\n[PlayerIdentity](api-reference-game.md#playeridentity).\n\nEvery surface this SDK names maps its rows through this already. You need it\nonly for a row you fetched yourself through the raw client — an async\nopponent, for instance:\n\n```js\nimport { mapIdentity, text } from '@indiegems/gem-web-sdk/sdk';\n\nconst { opponents } = await gem.client.get('/v1/async-opponents?opponent_type=ghost-lap');\nfor (const row of opponents) {\n const who = mapIdentity(row);\n label(who.displayName ? text.toPlain(who.displayName) : 'Anonymous player');\n}\n```\n\nReads `player_id`, `display_name`, `discriminator`, `display_tag`,\n`avatar_icon_id`, `avatar_icon_url`, `avatar_3d_id`, `avatar_3d_model_url`,\n`avatar_3d_icon_url` and `badges`, and nothing else from the row. Anything missing, empty or of the wrong type is absent in the result.",
|
|
11446
11604
|
"deprecated": null,
|
|
11447
11605
|
"params": [
|
|
11448
11606
|
{
|
|
@@ -11465,7 +11623,7 @@
|
|
|
11465
11623
|
"group": "player",
|
|
11466
11624
|
"signature": "function platformIconUrl(url: string | undefined): string | undefined",
|
|
11467
11625
|
"documented": true,
|
|
11468
|
-
"summary": "The icon URL, if and only if the platform serves it — otherwise `undefined`.\n\nUse it on every [PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)
|
|
11626
|
+
"summary": "The icon URL, if and only if the platform serves it — otherwise `undefined`.\n\nUse it on every [PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl),\n[PlayerIdentity.avatar3dIconUrl](api-reference-game.md#playeridentity-avatar3diconurl), [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl)\nand [PlayerBadge.iconUrl](api-reference-game.md#playerbadge-iconurl) before it reaches an `<img src>`, a texture\nloader, a `GLTFLoader` or a `fetch`:\n\n```js\nimport { platformIconUrl } from '@indiegems/gem-web-sdk/sdk';\n\nconst src = platformIconUrl(member.avatarIconUrl);\nif (src) img.src = src; else drawPlaceholder();\n```\n\n**Why it exists.** Loading an image is a request, and a request carries the\npage's `Referer` and the moment it happened. The URLs the SDK hands you are\nchecked for shape — `https`, no credentials — but a shape check cannot know\nwhich host is the platform's, so an icon URL from anywhere but the platform's\nown image host would be a beacon on your player. This compares the whole\norigin against the hosts the platform serves item icons from in production. A\nURL on `localhost` passes too, for a stack running on one machine.\n\nAn unrecognised host answers `undefined` — draw your placeholder, as for a\nplayer with no portrait. That includes a development backend's image host,\nso portraits appear only against production and loopback.",
|
|
11469
11627
|
"deprecated": null,
|
|
11470
11628
|
"params": [
|
|
11471
11629
|
{
|
|
@@ -14207,6 +14365,54 @@
|
|
|
14207
14365
|
"defaultValue": null,
|
|
14208
14366
|
"guides": []
|
|
14209
14367
|
},
|
|
14368
|
+
{
|
|
14369
|
+
"id": "LeaderboardEntry.avatar3dId",
|
|
14370
|
+
"name": "avatar3dId",
|
|
14371
|
+
"anchor": "leaderboardentry-avatar3did",
|
|
14372
|
+
"group": "leaderboards",
|
|
14373
|
+
"signature": "readonly avatar3dId?: string",
|
|
14374
|
+
"documented": true,
|
|
14375
|
+
"summary": "The id of the 3D character the player wears, when they wear one — an\nArcade item of type `avatar_3d`, chosen on the 3D tab of the Arcade's\navatar picker. What a game that draws Arcade avatars keys its character\non: prefer it, load [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl), and fall back\nto your own mapping of [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) when it is\nabsent.\n\nIndependent of the portrait: wearing a 3D character never changes\n`avatarIconId`, and the other way round. Absent means the game's default\nlook. On `gem.player` it changes when the player wears another one, and\n`onPlayer` runs again; see `gem.openAvatarPicker`.",
|
|
14376
|
+
"deprecated": null,
|
|
14377
|
+
"params": [],
|
|
14378
|
+
"returns": null,
|
|
14379
|
+
"throws": null,
|
|
14380
|
+
"example": null,
|
|
14381
|
+
"defaultValue": null,
|
|
14382
|
+
"guides": []
|
|
14383
|
+
},
|
|
14384
|
+
{
|
|
14385
|
+
"id": "LeaderboardEntry.avatar3dModelUrl",
|
|
14386
|
+
"name": "avatar3dModelUrl",
|
|
14387
|
+
"anchor": "leaderboardentry-avatar3dmodelurl",
|
|
14388
|
+
"group": "leaderboards",
|
|
14389
|
+
"signature": "readonly avatar3dModelUrl?: string",
|
|
14390
|
+
"documented": true,
|
|
14391
|
+
"summary": "The worn 3D character's model — a binary glTF (`.glb`) with one rig,\n`root > body > (head, arm_l, arm_r > hand_socket, leg_l, leg_r)`, and\npossibly animation clips. Load it with three.js's `GLTFLoader`, after\npassing it through [platformIconUrl](api-reference-game.md#platformiconurl), which pins models to the\nplatform's item host exactly as it pins pictures. Absent when no 3D\ncharacter is worn.",
|
|
14392
|
+
"deprecated": null,
|
|
14393
|
+
"params": [],
|
|
14394
|
+
"returns": null,
|
|
14395
|
+
"throws": null,
|
|
14396
|
+
"example": null,
|
|
14397
|
+
"defaultValue": null,
|
|
14398
|
+
"guides": []
|
|
14399
|
+
},
|
|
14400
|
+
{
|
|
14401
|
+
"id": "LeaderboardEntry.avatar3dIconUrl",
|
|
14402
|
+
"name": "avatar3dIconUrl",
|
|
14403
|
+
"anchor": "leaderboardentry-avatar3diconurl",
|
|
14404
|
+
"group": "leaderboards",
|
|
14405
|
+
"signature": "readonly avatar3dIconUrl?: string",
|
|
14406
|
+
"documented": true,
|
|
14407
|
+
"summary": "A rendered portrait of the worn 3D character, for a roster or a menu where\nloading the model is too much. Not the 2D portrait\n([PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)), which is a separate choice. Pass it\nthrough [platformIconUrl](api-reference-game.md#platformiconurl) before putting it in an `<img src>`.",
|
|
14408
|
+
"deprecated": null,
|
|
14409
|
+
"params": [],
|
|
14410
|
+
"returns": null,
|
|
14411
|
+
"throws": null,
|
|
14412
|
+
"example": null,
|
|
14413
|
+
"defaultValue": null,
|
|
14414
|
+
"guides": []
|
|
14415
|
+
},
|
|
14210
14416
|
{
|
|
14211
14417
|
"id": "LeaderboardEntry.badges",
|
|
14212
14418
|
"name": "badges",
|
|
@@ -15970,6 +16176,54 @@
|
|
|
15970
16176
|
"defaultValue": null,
|
|
15971
16177
|
"guides": []
|
|
15972
16178
|
},
|
|
16179
|
+
{
|
|
16180
|
+
"id": "PlayerProfile.avatar3dId",
|
|
16181
|
+
"name": "avatar3dId",
|
|
16182
|
+
"anchor": "playerprofile-avatar3did",
|
|
16183
|
+
"group": "profiles",
|
|
16184
|
+
"signature": "readonly avatar3dId?: string",
|
|
16185
|
+
"documented": true,
|
|
16186
|
+
"summary": "The id of the 3D character the player wears, when they wear one — an\nArcade item of type `avatar_3d`, chosen on the 3D tab of the Arcade's\navatar picker. What a game that draws Arcade avatars keys its character\non: prefer it, load [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl), and fall back\nto your own mapping of [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) when it is\nabsent.\n\nIndependent of the portrait: wearing a 3D character never changes\n`avatarIconId`, and the other way round. Absent means the game's default\nlook. On `gem.player` it changes when the player wears another one, and\n`onPlayer` runs again; see `gem.openAvatarPicker`.",
|
|
16187
|
+
"deprecated": null,
|
|
16188
|
+
"params": [],
|
|
16189
|
+
"returns": null,
|
|
16190
|
+
"throws": null,
|
|
16191
|
+
"example": null,
|
|
16192
|
+
"defaultValue": null,
|
|
16193
|
+
"guides": []
|
|
16194
|
+
},
|
|
16195
|
+
{
|
|
16196
|
+
"id": "PlayerProfile.avatar3dModelUrl",
|
|
16197
|
+
"name": "avatar3dModelUrl",
|
|
16198
|
+
"anchor": "playerprofile-avatar3dmodelurl",
|
|
16199
|
+
"group": "profiles",
|
|
16200
|
+
"signature": "readonly avatar3dModelUrl?: string",
|
|
16201
|
+
"documented": true,
|
|
16202
|
+
"summary": "The worn 3D character's model — a binary glTF (`.glb`) with one rig,\n`root > body > (head, arm_l, arm_r > hand_socket, leg_l, leg_r)`, and\npossibly animation clips. Load it with three.js's `GLTFLoader`, after\npassing it through [platformIconUrl](api-reference-game.md#platformiconurl), which pins models to the\nplatform's item host exactly as it pins pictures. Absent when no 3D\ncharacter is worn.",
|
|
16203
|
+
"deprecated": null,
|
|
16204
|
+
"params": [],
|
|
16205
|
+
"returns": null,
|
|
16206
|
+
"throws": null,
|
|
16207
|
+
"example": null,
|
|
16208
|
+
"defaultValue": null,
|
|
16209
|
+
"guides": []
|
|
16210
|
+
},
|
|
16211
|
+
{
|
|
16212
|
+
"id": "PlayerProfile.avatar3dIconUrl",
|
|
16213
|
+
"name": "avatar3dIconUrl",
|
|
16214
|
+
"anchor": "playerprofile-avatar3diconurl",
|
|
16215
|
+
"group": "profiles",
|
|
16216
|
+
"signature": "readonly avatar3dIconUrl?: string",
|
|
16217
|
+
"documented": true,
|
|
16218
|
+
"summary": "A rendered portrait of the worn 3D character, for a roster or a menu where\nloading the model is too much. Not the 2D portrait\n([PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)), which is a separate choice. Pass it\nthrough [platformIconUrl](api-reference-game.md#platformiconurl) before putting it in an `<img src>`.",
|
|
16219
|
+
"deprecated": null,
|
|
16220
|
+
"params": [],
|
|
16221
|
+
"returns": null,
|
|
16222
|
+
"throws": null,
|
|
16223
|
+
"example": null,
|
|
16224
|
+
"defaultValue": null,
|
|
16225
|
+
"guides": []
|
|
16226
|
+
},
|
|
15973
16227
|
{
|
|
15974
16228
|
"id": "PlayerProfile.badges",
|
|
15975
16229
|
"name": "badges",
|
|
@@ -18786,6 +19040,54 @@
|
|
|
18786
19040
|
"defaultValue": null,
|
|
18787
19041
|
"guides": []
|
|
18788
19042
|
},
|
|
19043
|
+
{
|
|
19044
|
+
"id": "RoomMember.avatar3dId",
|
|
19045
|
+
"name": "avatar3dId",
|
|
19046
|
+
"anchor": "roommember-avatar3did",
|
|
19047
|
+
"group": "rooms",
|
|
19048
|
+
"signature": "readonly avatar3dId?: string",
|
|
19049
|
+
"documented": true,
|
|
19050
|
+
"summary": "The id of the 3D character the player wears, when they wear one — an\nArcade item of type `avatar_3d`, chosen on the 3D tab of the Arcade's\navatar picker. What a game that draws Arcade avatars keys its character\non: prefer it, load [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl), and fall back\nto your own mapping of [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) when it is\nabsent.\n\nIndependent of the portrait: wearing a 3D character never changes\n`avatarIconId`, and the other way round. Absent means the game's default\nlook. On `gem.player` it changes when the player wears another one, and\n`onPlayer` runs again; see `gem.openAvatarPicker`.",
|
|
19051
|
+
"deprecated": null,
|
|
19052
|
+
"params": [],
|
|
19053
|
+
"returns": null,
|
|
19054
|
+
"throws": null,
|
|
19055
|
+
"example": null,
|
|
19056
|
+
"defaultValue": null,
|
|
19057
|
+
"guides": []
|
|
19058
|
+
},
|
|
19059
|
+
{
|
|
19060
|
+
"id": "RoomMember.avatar3dModelUrl",
|
|
19061
|
+
"name": "avatar3dModelUrl",
|
|
19062
|
+
"anchor": "roommember-avatar3dmodelurl",
|
|
19063
|
+
"group": "rooms",
|
|
19064
|
+
"signature": "readonly avatar3dModelUrl?: string",
|
|
19065
|
+
"documented": true,
|
|
19066
|
+
"summary": "The worn 3D character's model — a binary glTF (`.glb`) with one rig,\n`root > body > (head, arm_l, arm_r > hand_socket, leg_l, leg_r)`, and\npossibly animation clips. Load it with three.js's `GLTFLoader`, after\npassing it through [platformIconUrl](api-reference-game.md#platformiconurl), which pins models to the\nplatform's item host exactly as it pins pictures. Absent when no 3D\ncharacter is worn.",
|
|
19067
|
+
"deprecated": null,
|
|
19068
|
+
"params": [],
|
|
19069
|
+
"returns": null,
|
|
19070
|
+
"throws": null,
|
|
19071
|
+
"example": null,
|
|
19072
|
+
"defaultValue": null,
|
|
19073
|
+
"guides": []
|
|
19074
|
+
},
|
|
19075
|
+
{
|
|
19076
|
+
"id": "RoomMember.avatar3dIconUrl",
|
|
19077
|
+
"name": "avatar3dIconUrl",
|
|
19078
|
+
"anchor": "roommember-avatar3diconurl",
|
|
19079
|
+
"group": "rooms",
|
|
19080
|
+
"signature": "readonly avatar3dIconUrl?: string",
|
|
19081
|
+
"documented": true,
|
|
19082
|
+
"summary": "A rendered portrait of the worn 3D character, for a roster or a menu where\nloading the model is too much. Not the 2D portrait\n([PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)), which is a separate choice. Pass it\nthrough [platformIconUrl](api-reference-game.md#platformiconurl) before putting it in an `<img src>`.",
|
|
19083
|
+
"deprecated": null,
|
|
19084
|
+
"params": [],
|
|
19085
|
+
"returns": null,
|
|
19086
|
+
"throws": null,
|
|
19087
|
+
"example": null,
|
|
19088
|
+
"defaultValue": null,
|
|
19089
|
+
"guides": []
|
|
19090
|
+
},
|
|
18789
19091
|
{
|
|
18790
19092
|
"id": "RoomMember.badges",
|
|
18791
19093
|
"name": "badges",
|
|
@@ -19868,6 +20170,54 @@
|
|
|
19868
20170
|
"defaultValue": null,
|
|
19869
20171
|
"guides": []
|
|
19870
20172
|
},
|
|
20173
|
+
{
|
|
20174
|
+
"id": "ShowcaseFriendEntry.avatar3dId",
|
|
20175
|
+
"name": "avatar3dId",
|
|
20176
|
+
"anchor": "showcasefriendentry-avatar3did",
|
|
20177
|
+
"group": "showcase",
|
|
20178
|
+
"signature": "readonly avatar3dId?: string",
|
|
20179
|
+
"documented": true,
|
|
20180
|
+
"summary": "The id of the 3D character the player wears, when they wear one — an\nArcade item of type `avatar_3d`, chosen on the 3D tab of the Arcade's\navatar picker. What a game that draws Arcade avatars keys its character\non: prefer it, load [PlayerIdentity.avatar3dModelUrl](api-reference-game.md#playeridentity-avatar3dmodelurl), and fall back\nto your own mapping of [PlayerIdentity.avatarIconId](api-reference-game.md#playeridentity-avatariconid) when it is\nabsent.\n\nIndependent of the portrait: wearing a 3D character never changes\n`avatarIconId`, and the other way round. Absent means the game's default\nlook. On `gem.player` it changes when the player wears another one, and\n`onPlayer` runs again; see `gem.openAvatarPicker`.",
|
|
20181
|
+
"deprecated": null,
|
|
20182
|
+
"params": [],
|
|
20183
|
+
"returns": null,
|
|
20184
|
+
"throws": null,
|
|
20185
|
+
"example": null,
|
|
20186
|
+
"defaultValue": null,
|
|
20187
|
+
"guides": []
|
|
20188
|
+
},
|
|
20189
|
+
{
|
|
20190
|
+
"id": "ShowcaseFriendEntry.avatar3dModelUrl",
|
|
20191
|
+
"name": "avatar3dModelUrl",
|
|
20192
|
+
"anchor": "showcasefriendentry-avatar3dmodelurl",
|
|
20193
|
+
"group": "showcase",
|
|
20194
|
+
"signature": "readonly avatar3dModelUrl?: string",
|
|
20195
|
+
"documented": true,
|
|
20196
|
+
"summary": "The worn 3D character's model — a binary glTF (`.glb`) with one rig,\n`root > body > (head, arm_l, arm_r > hand_socket, leg_l, leg_r)`, and\npossibly animation clips. Load it with three.js's `GLTFLoader`, after\npassing it through [platformIconUrl](api-reference-game.md#platformiconurl), which pins models to the\nplatform's item host exactly as it pins pictures. Absent when no 3D\ncharacter is worn.",
|
|
20197
|
+
"deprecated": null,
|
|
20198
|
+
"params": [],
|
|
20199
|
+
"returns": null,
|
|
20200
|
+
"throws": null,
|
|
20201
|
+
"example": null,
|
|
20202
|
+
"defaultValue": null,
|
|
20203
|
+
"guides": []
|
|
20204
|
+
},
|
|
20205
|
+
{
|
|
20206
|
+
"id": "ShowcaseFriendEntry.avatar3dIconUrl",
|
|
20207
|
+
"name": "avatar3dIconUrl",
|
|
20208
|
+
"anchor": "showcasefriendentry-avatar3diconurl",
|
|
20209
|
+
"group": "showcase",
|
|
20210
|
+
"signature": "readonly avatar3dIconUrl?: string",
|
|
20211
|
+
"documented": true,
|
|
20212
|
+
"summary": "A rendered portrait of the worn 3D character, for a roster or a menu where\nloading the model is too much. Not the 2D portrait\n([PlayerIdentity.avatarIconUrl](api-reference-game.md#playeridentity-avatariconurl)), which is a separate choice. Pass it\nthrough [platformIconUrl](api-reference-game.md#platformiconurl) before putting it in an `<img src>`.",
|
|
20213
|
+
"deprecated": null,
|
|
20214
|
+
"params": [],
|
|
20215
|
+
"returns": null,
|
|
20216
|
+
"throws": null,
|
|
20217
|
+
"example": null,
|
|
20218
|
+
"defaultValue": null,
|
|
20219
|
+
"guides": []
|
|
20220
|
+
},
|
|
19871
20221
|
{
|
|
19872
20222
|
"id": "ShowcaseFriendEntry.badges",
|
|
19873
20223
|
"name": "badges",
|
package/docs/changelog.md
CHANGED
|
@@ -16,6 +16,23 @@ Its entries are grouped under up to five headings:
|
|
|
16
16
|
- **Rebuild**: a type changed. Recompile against the new version; code that compiles today keeps compiling unless the entry says otherwise.
|
|
17
17
|
- **New capability**: something a game can now do. Nothing changes unless you use it.
|
|
18
18
|
|
|
19
|
+
## 11.0.0
|
|
20
|
+
|
|
21
|
+
Upgrading from 10.4.0. Impact: required.
|
|
22
|
+
|
|
23
|
+
### Rebuild
|
|
24
|
+
|
|
25
|
+
- The calls that ask the Arcade to open the avatar picker now accept an optional tab, either 2d or 3d. Existing calls without arguments still compile and behave as before. Recompile; pass a tab only if you want the picker to open on a specific one.
|
|
26
|
+
- The host callback for avatar picker requests now receives a request object that may carry the requested tab. Handlers that take no arguments still compile. Recompile, and if you host games, read the tab to open the picker on the right one.
|
|
27
|
+
|
|
28
|
+
### New capability
|
|
29
|
+
|
|
30
|
+
- The current player now carries optional 3D avatar fields: an identifier, a model URL and an icon URL. They describe the 3D character the player wears in the Arcade, which is chosen independently of the 2D portrait. The fields may be absent, so keep a fallback to the portrait. They are sent again whenever the worn 3D character changes, so a game that shows the player's avatar should update when they change.
|
|
31
|
+
- Room members, leaderboard rows, friends and showcase friend rows now carry the same optional 3D avatar identifier, model URL and icon URL. A game can show other players' 3D characters wherever it already shows their portraits. Treat the fields as optional and fall back to the portrait when they are missing.
|
|
32
|
+
- Code that embeds a game and sends player details to it can now pass the 3D avatar identifier, model URL and icon URL along with the other player fields. Send them whenever the player's worn 3D character changes.
|
|
33
|
+
- The raw server and API identity types now include optional 3D avatar identifier, model URL and icon URL properties for players and subjects. Code that reads these types directly can use them. They may not be populated by the service yet, so handle their absence.
|
|
34
|
+
- The Arcade avatar picker now has a 2D tab and a 3D tab. A game asking the Arcade to open the picker can say which tab to show, and a host receiving that request can read the requested tab. Omitting the tab keeps the previous behaviour. An unknown tab value is dropped rather than failing the request.
|
|
35
|
+
|
|
19
36
|
## 10.4.0
|
|
20
37
|
|
|
21
38
|
Upgrading from 10.3.1. Impact: required.
|
package/docs/getting-started.md
CHANGED
package/docs/manifest.json
CHANGED
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"file": "changelog.md",
|
|
36
|
-
"sha256": "
|
|
37
|
-
"updated": "2026-10-
|
|
36
|
+
"sha256": "49abc51f04333f12f5b88687a4d5cd702bac1ab28a8f19533f9253ba015ec41a",
|
|
37
|
+
"updated": "2026-10-11T20:42:08Z"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"file": "cross-promotion.md",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"file": "getting-started.md",
|
|
71
|
-
"sha256": "
|
|
72
|
-
"updated": "2026-10-
|
|
71
|
+
"sha256": "f46be1e65cc5936ad3c06c27f5eb33b250651003f8880c36bf4f0deb50b30e09",
|
|
72
|
+
"updated": "2026-10-11T20:42:08Z"
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"file": "inventory-and-catalogs.md",
|
|
@@ -123,8 +123,8 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"file": "server-bundles.md",
|
|
126
|
-
"sha256": "
|
|
127
|
-
"updated": "2026-10-
|
|
126
|
+
"sha256": "74b7d0964881a74ee12097bdee41afec12ca03d3feddb5a935bea7483a79967d",
|
|
127
|
+
"updated": "2026-10-11T20:42:08Z"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"file": "serverless-functions-js.md",
|
|
@@ -148,8 +148,8 @@
|
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
150
|
"file": "what-a-game-must-do.md",
|
|
151
|
-
"sha256": "
|
|
152
|
-
"updated": "2026-10-11T19:
|
|
151
|
+
"sha256": "ab4f18f2c1cfccf54b01027dea77d229f0a9f086e373d6cfd4c741fd0004557f",
|
|
152
|
+
"updated": "2026-10-11T19:48:44Z"
|
|
153
153
|
}
|
|
154
154
|
]
|
|
155
155
|
}
|
package/docs/server-bundles.md
CHANGED
|
@@ -80,8 +80,8 @@ To check the download yourself: the package npm serves is, byte for byte, the fi
|
|
|
80
80
|
also publishes on its download host, with the hash beside it:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
curl -fsSL -O https://downloads.gemarcade.com/sdk/
|
|
84
|
-
curl -fsSL https://downloads.gemarcade.com/sdk/
|
|
83
|
+
curl -fsSL -O https://downloads.gemarcade.com/sdk/v11.0.0/gem-web-sdk.tgz
|
|
84
|
+
curl -fsSL https://downloads.gemarcade.com/sdk/v11.0.0/gem-web-sdk.tgz.sri
|
|
85
85
|
openssl dgst -sha384 -binary gem-web-sdk.tgz | openssl base64 -A
|
|
86
86
|
```
|
|
87
87
|
|