@indiegems/gem-web-sdk 13.0.0 → 13.1.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 +14 -0
- package/dist/function.d.ts +1 -1
- package/dist/game.d.ts +15 -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 +1 -1
- 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 +15 -4
- package/dist/sdk.d.ts +15 -2
- package/docs/api/api-reference-function.md +13 -5
- package/docs/api/api-reference-game.md +190 -11
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +184 -10
- package/docs/arcade-avatars.md +194 -26
- package/docs/brand-art.md +3 -3
- package/docs/changelog.md +14 -0
- package/docs/getting-started.md +3 -2
- package/docs/inventory-and-catalogs.md +1 -1
- package/docs/manifest.json +14 -14
- package/docs/server-bundles.md +2 -2
- package/docs/what-a-game-must-do.md +97 -57
- package/package.json +4 -2
- package/rigs/adult_human.glb +0 -0
- package/schema/bridge.v1.json +53 -6
- package/schema/capabilities.public.json +6 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The browser surface — API reference
|
|
2
2
|
|
|
3
|
-
Generated from `@indiegems/gem-web-sdk/sdk` v13.
|
|
3
|
+
Generated from `@indiegems/gem-web-sdk/sdk` v13.1.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
|
|
4
4
|
|
|
5
5
|
`@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/game` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
|
|
6
6
|
|
|
@@ -3925,6 +3925,100 @@ for the avatars already worn when you subscribe: read
|
|
|
3925
3925
|
|
|
3926
3926
|
**Returns.** a function that stops the calls. Calling it twice is harmless.
|
|
3927
3927
|
|
|
3928
|
+
<a id="avatarrignode"></a>
|
|
3929
|
+
|
|
3930
|
+
## AvatarRigNode
|
|
3931
|
+
|
|
3932
|
+
```ts
|
|
3933
|
+
interface AvatarRigNode
|
|
3934
|
+
```
|
|
3935
|
+
|
|
3936
|
+
One node of a rig family's tree: its exact, case-sensitive name, and the
|
|
3937
|
+
name of the node it is a DIRECT child of. `parent` is `null` for the rig's
|
|
3938
|
+
root, which is a root node of the scene.
|
|
3939
|
+
|
|
3940
|
+
<a id="avatarrignode-node"></a>
|
|
3941
|
+
|
|
3942
|
+
## AvatarRigNode.node
|
|
3943
|
+
|
|
3944
|
+
```ts
|
|
3945
|
+
readonly node: string
|
|
3946
|
+
```
|
|
3947
|
+
|
|
3948
|
+
The node's name, exact and case-sensitive.
|
|
3949
|
+
|
|
3950
|
+
<a id="avatarrignode-parent"></a>
|
|
3951
|
+
|
|
3952
|
+
## AvatarRigNode.parent
|
|
3953
|
+
|
|
3954
|
+
```ts
|
|
3955
|
+
readonly parent: string | null
|
|
3956
|
+
```
|
|
3957
|
+
|
|
3958
|
+
The node it is a direct child of; `null` for the rig's root.
|
|
3959
|
+
|
|
3960
|
+
<a id="avatarrigs"></a>
|
|
3961
|
+
|
|
3962
|
+
## AvatarRigs
|
|
3963
|
+
|
|
3964
|
+
```ts
|
|
3965
|
+
interface AvatarRigs
|
|
3966
|
+
```
|
|
3967
|
+
|
|
3968
|
+
The rig families this SDK knows, by name.
|
|
3969
|
+
|
|
3970
|
+
<a id="avatarrigs-small_human"></a>
|
|
3971
|
+
|
|
3972
|
+
## AvatarRigs.small_human
|
|
3973
|
+
|
|
3974
|
+
```ts
|
|
3975
|
+
readonly small_human: readonly AvatarRigNode[]
|
|
3976
|
+
```
|
|
3977
|
+
|
|
3978
|
+
The toy rig: rigid limbs on a body, eight nodes.
|
|
3979
|
+
|
|
3980
|
+
<a id="avatarrigs-adult_human"></a>
|
|
3981
|
+
|
|
3982
|
+
## AvatarRigs.adult_human
|
|
3983
|
+
|
|
3984
|
+
```ts
|
|
3985
|
+
readonly adult_human: readonly AvatarRigNode[]
|
|
3986
|
+
```
|
|
3987
|
+
|
|
3988
|
+
The adult humanoid with fingers: 56 nodes, world-aligned at rest.
|
|
3989
|
+
|
|
3990
|
+
<a id="avatar_rigs"></a>
|
|
3991
|
+
|
|
3992
|
+
## AVATAR_RIGS
|
|
3993
|
+
|
|
3994
|
+
```ts
|
|
3995
|
+
AVATAR_RIGS: AvatarRigs
|
|
3996
|
+
```
|
|
3997
|
+
|
|
3998
|
+
Every node each rig family requires, with the node it is a direct child of,
|
|
3999
|
+
parents before children. Frozen: read it, never change it.
|
|
4000
|
+
|
|
4001
|
+
The platform refuses an upload whose model is missing one of these, has one
|
|
4002
|
+
under another parent, or has one twice (`rig_mismatch`). Extra nodes are
|
|
4003
|
+
allowed anywhere. `adult_human` also requires every one of its nodes to be
|
|
4004
|
+
world-aligned at rest; that rule is not in this list, see the guide.
|
|
4005
|
+
|
|
4006
|
+
```js
|
|
4007
|
+
import { AVATAR_RIGS } from '@indiegems/gem-web-sdk/sdk';
|
|
4008
|
+
|
|
4009
|
+
// Every joint of the worn avatar, by name.
|
|
4010
|
+
const joints = new Map(
|
|
4011
|
+
AVATAR_RIGS.adult_human.map(({ node }) => [node, gltf.scene.getObjectByName(node)]),
|
|
4012
|
+
);
|
|
4013
|
+
|
|
4014
|
+
// A test that one of your own models is on the rig.
|
|
4015
|
+
for (const { node, parent } of AVATAR_RIGS.adult_human) {
|
|
4016
|
+
const found = gltf.scene.getObjectByName(node);
|
|
4017
|
+
if (!found) throw new Error(`missing ${node}`);
|
|
4018
|
+
if (parent !== null && found.parent?.name !== parent) throw new Error(`${node} is not under ${parent}`);
|
|
4019
|
+
}
|
|
4020
|
+
```
|
|
4021
|
+
|
|
3928
4022
|
<a id="gemapierror"></a>
|
|
3929
4023
|
|
|
3930
4024
|
## GemApiError
|
|
@@ -5347,7 +5441,7 @@ interface RewardCue
|
|
|
5347
5441
|
```
|
|
5348
5442
|
|
|
5349
5443
|
A platform-currency reward on its way to the arcade — in the Gem Arcade, a
|
|
5350
|
-
flight into the Gem button
|
|
5444
|
+
flight into the Gem button, in whichever corner of your frame it sits — what
|
|
5351
5445
|
`gem.cueReward` takes.
|
|
5352
5446
|
|
|
5353
5447
|
<a id="rewardcue-currencyslug"></a>
|
|
@@ -5408,6 +5502,18 @@ y: number
|
|
|
5408
5502
|
|
|
5409
5503
|
From the top edge of your viewport.
|
|
5410
5504
|
|
|
5505
|
+
<a id="gemcorner"></a>
|
|
5506
|
+
|
|
5507
|
+
## GemCorner
|
|
5508
|
+
|
|
5509
|
+
```ts
|
|
5510
|
+
type GemCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right"
|
|
5511
|
+
```
|
|
5512
|
+
|
|
5513
|
+
A corner of your frame, for `gem.setGemCorner`: where you would like the
|
|
5514
|
+
arcade's Gem button to sit. `'top-left'` is where it sits unless you ask.
|
|
5515
|
+
Physical corners: `'top-left'` is the top-left in every language.
|
|
5516
|
+
|
|
5411
5517
|
<a id="framestate"></a>
|
|
5412
5518
|
|
|
5413
5519
|
## FrameState
|
|
@@ -5737,6 +5843,30 @@ connected, and only to an arcade that draws a menu.
|
|
|
5737
5843
|
**Returns.** whether the message left the frame — `false` before the bridge is
|
|
5738
5844
|
up, for an arcade with no menu, and past this frame's own limit.
|
|
5739
5845
|
|
|
5846
|
+
<a id="gemframe-setgemcorner"></a>
|
|
5847
|
+
|
|
5848
|
+
## GemFrame.setGemCorner
|
|
5849
|
+
|
|
5850
|
+
```ts
|
|
5851
|
+
setGemCorner(corner: GemCorner): boolean
|
|
5852
|
+
```
|
|
5853
|
+
|
|
5854
|
+
Ask the arcade to put its own control over your game — the Gem button —
|
|
5855
|
+
in this corner of your frame: the whole answer each time, the latest one
|
|
5856
|
+
winning.
|
|
5857
|
+
|
|
5858
|
+
Prefer `gem.setGemCorner`, which holds the corner across a reconnect.
|
|
5859
|
+
This one sends only while connected, and only to an arcade that can move
|
|
5860
|
+
its control.
|
|
5861
|
+
|
|
5862
|
+
| Parameter | Type |
|
|
5863
|
+
| --- | --- |
|
|
5864
|
+
| `corner` | `GemCorner` |
|
|
5865
|
+
|
|
5866
|
+
**Returns.** whether the message left the frame — `false` before the bridge is
|
|
5867
|
+
up, for an arcade that cannot move its control, for a value that is not
|
|
5868
|
+
one of the four corners, and past this frame's own limit.
|
|
5869
|
+
|
|
5740
5870
|
<a id="gemframe-requestshare"></a>
|
|
5741
5871
|
|
|
5742
5872
|
## GemFrame.requestShare
|
|
@@ -8303,7 +8433,7 @@ readonly reserved: readonly GemReservedArea[]
|
|
|
8303
8433
|
```
|
|
8304
8434
|
|
|
8305
8435
|
Rectangles of your frame the arcade's own controls cover — in the Gem
|
|
8306
|
-
Arcade, its Gem button in
|
|
8436
|
+
Arcade, its Gem button in whichever corner it sits, and the frame-rate readout
|
|
8307
8437
|
beside it while the player shows it; an embedder that draws wallets over
|
|
8308
8438
|
your game adds theirs (see `setWalletVisible`). Keep essential UI and touch
|
|
8309
8439
|
targets out of them. Empty when the arcade covers nothing.
|
|
@@ -9430,7 +9560,7 @@ cueReward(cue: RewardCue): boolean
|
|
|
9430
9560
|
|
|
9431
9561
|
Tell the arcade a platform-currency reward is on its way, so it **shows it
|
|
9432
9562
|
landing**: in the Gem Arcade the currency flies from `origin` into the Gem
|
|
9433
|
-
button
|
|
9563
|
+
button, wherever on your frame it sits, which pops as each mark lands, and
|
|
9434
9564
|
the player's total moves once the platform confirms the grant. The Gem
|
|
9435
9565
|
Arcade draws no wallet over your game: the player sees their Gems and
|
|
9436
9566
|
Tickets in the Gem menu. A payout you do not cue still flies, from the
|
|
@@ -9532,8 +9662,9 @@ gem.setMenu({
|
|
|
9532
9662
|
```
|
|
9533
9663
|
|
|
9534
9664
|
**Your settings are not in it: draw your own settings button, always** —
|
|
9535
|
-
top-right,
|
|
9536
|
-
your settings
|
|
9665
|
+
top-right, with your Back button just to its left, clear of
|
|
9666
|
+
`gem.viewport.reserved`. The Arcade's menu never opens your settings
|
|
9667
|
+
screen.
|
|
9537
9668
|
|
|
9538
9669
|
**It is screen state, not a toggle.** Each call is the whole answer and
|
|
9539
9670
|
replaces the last, so call it again when the entries change — a new
|
|
@@ -9553,6 +9684,46 @@ should not assume the game was paused by you.
|
|
|
9553
9684
|
up (the menu is held and sent when it connects) and under an embedder
|
|
9554
9685
|
that draws no menu.
|
|
9555
9686
|
|
|
9687
|
+
<a id="gem-setgemcorner"></a>
|
|
9688
|
+
|
|
9689
|
+
## Gem.setGemCorner
|
|
9690
|
+
|
|
9691
|
+
```ts
|
|
9692
|
+
setGemCorner(corner: GemCorner): boolean
|
|
9693
|
+
```
|
|
9694
|
+
|
|
9695
|
+
Ask the arcade to put its Gem button — its one control over your game,
|
|
9696
|
+
top-left unless you ask — in another corner of your frame.
|
|
9697
|
+
|
|
9698
|
+
```js
|
|
9699
|
+
// This game's own HUD needs the top-left, so the Gem goes top-right.
|
|
9700
|
+
gem.setGemCorner('top-right');
|
|
9701
|
+
```
|
|
9702
|
+
|
|
9703
|
+
**Leave it top-left unless your own HUD needs that corner**, and then pick
|
|
9704
|
+
one corner for the whole game — at most one per orientation. A Gem that
|
|
9705
|
+
moves between screens is a way out the player has to look for. In
|
|
9706
|
+
landscape the bottom corners sit where a player's thumbs hold the sticks.
|
|
9707
|
+
|
|
9708
|
+
**Lay out around `gem.viewport.reserved`, never around the corner you
|
|
9709
|
+
asked for.** The arcade moves the Gem on its own terms: not while the
|
|
9710
|
+
player is using it or its menu is open, not more often than every few
|
|
9711
|
+
seconds, and never over a corner the player chose for themselves. The
|
|
9712
|
+
rectangles say where it actually is, and the `--gem-reserved-*` CSS
|
|
9713
|
+
properties follow them.
|
|
9714
|
+
|
|
9715
|
+
**It is screen state, not a toggle.** Each call is the whole answer and
|
|
9716
|
+
replaces the last. A value that is not one of the four corners is ignored,
|
|
9717
|
+
with a warning on the console, and changes nothing.
|
|
9718
|
+
|
|
9719
|
+
| Parameter | Type | Description |
|
|
9720
|
+
| --- | --- | --- |
|
|
9721
|
+
| `corner` | `GemCorner` | `'top-left'`, `'top-right'`, `'bottom-left'` or `'bottom-right'`. |
|
|
9722
|
+
|
|
9723
|
+
**Returns.** `true` when the arcade was told now; `false` before the bridge is
|
|
9724
|
+
up (the corner is held and sent when it connects), under an embedder that
|
|
9725
|
+
cannot move its control, and for a value that is not a corner.
|
|
9726
|
+
|
|
9556
9727
|
<a id="gem-exit"></a>
|
|
9557
9728
|
|
|
9558
9729
|
## Gem.exit
|
|
@@ -10352,7 +10523,7 @@ The match this connection belongs to.
|
|
|
10352
10523
|
## MatchConnection.protocol
|
|
10353
10524
|
|
|
10354
10525
|
```ts
|
|
10355
|
-
readonly protocol: "
|
|
10526
|
+
readonly protocol: "p2p" | "dedicated" | "loopback"
|
|
10356
10527
|
```
|
|
10357
10528
|
|
|
10358
10529
|
What is on the other end: `dedicated` (the platform's server), `p2p` (the
|
|
@@ -10544,13 +10715,21 @@ putting it in an `<img src>`.
|
|
|
10544
10715
|
## Avatar3dFamily
|
|
10545
10716
|
|
|
10546
10717
|
```ts
|
|
10547
|
-
type Avatar3dFamily = "small_human" | string & object
|
|
10718
|
+
type Avatar3dFamily = "small_human" | "adult_human" | string & object
|
|
10548
10719
|
```
|
|
10549
10720
|
|
|
10550
10721
|
A rig family — the skeleton contract a 3D avatar is built on, and what a
|
|
10551
|
-
game declares it can animate.
|
|
10552
|
-
|
|
10553
|
-
`
|
|
10722
|
+
game declares it can animate. Two today:
|
|
10723
|
+
|
|
10724
|
+
- `small_human`, the toy rig: a `root` node with a `body` child, which holds
|
|
10725
|
+
`head`, `arm_l`, `arm_r`, `leg_l` and `leg_r`, and a `hand_socket` under
|
|
10726
|
+
`arm_r`.
|
|
10727
|
+
- `adult_human`, a full humanoid with fingers: 56 nodes from `root` and
|
|
10728
|
+
`hips` down to `toes_r`, every one world-aligned at rest, so one clip plays
|
|
10729
|
+
on every avatar in the family.
|
|
10730
|
+
|
|
10731
|
+
`AVATAR_RIGS` (from `@indiegems/gem-web-sdk/sdk`) lists every node of
|
|
10732
|
+
both, with its parent.
|
|
10554
10733
|
|
|
10555
10734
|
Open-ended (`| (string & {})`) so a family the platform adds later does not
|
|
10556
10735
|
break a `switch` you compiled against this version: keep a `default` arm and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The server surface — API reference
|
|
2
2
|
|
|
3
|
-
Generated from `@indiegems/gem-web-sdk/sdk` v13.
|
|
3
|
+
Generated from `@indiegems/gem-web-sdk/sdk` v13.1.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
|
|
4
4
|
|
|
5
5
|
`@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/server` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
|
|
6
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": "13.
|
|
5
|
+
"version": "13.1.0"
|
|
6
6
|
},
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -4797,6 +4797,118 @@
|
|
|
4797
4797
|
"defaultValue": null,
|
|
4798
4798
|
"guides": []
|
|
4799
4799
|
},
|
|
4800
|
+
{
|
|
4801
|
+
"id": "AvatarRigNode",
|
|
4802
|
+
"name": "AvatarRigNode",
|
|
4803
|
+
"anchor": "avatarrignode",
|
|
4804
|
+
"group": "avatars3d",
|
|
4805
|
+
"signature": "interface AvatarRigNode",
|
|
4806
|
+
"documented": true,
|
|
4807
|
+
"summary": "One node of a rig family's tree: its exact, case-sensitive name, and the\nname of the node it is a DIRECT child of. `parent` is `null` for the rig's\nroot, which is a root node of the scene.",
|
|
4808
|
+
"deprecated": null,
|
|
4809
|
+
"params": [],
|
|
4810
|
+
"returns": null,
|
|
4811
|
+
"throws": null,
|
|
4812
|
+
"example": null,
|
|
4813
|
+
"defaultValue": null,
|
|
4814
|
+
"guides": []
|
|
4815
|
+
},
|
|
4816
|
+
{
|
|
4817
|
+
"id": "AvatarRigNode.node",
|
|
4818
|
+
"name": "node",
|
|
4819
|
+
"anchor": "avatarrignode-node",
|
|
4820
|
+
"group": "avatars3d",
|
|
4821
|
+
"signature": "readonly node: string",
|
|
4822
|
+
"documented": true,
|
|
4823
|
+
"summary": "The node's name, exact and case-sensitive.",
|
|
4824
|
+
"deprecated": null,
|
|
4825
|
+
"params": [],
|
|
4826
|
+
"returns": null,
|
|
4827
|
+
"throws": null,
|
|
4828
|
+
"example": null,
|
|
4829
|
+
"defaultValue": null,
|
|
4830
|
+
"guides": []
|
|
4831
|
+
},
|
|
4832
|
+
{
|
|
4833
|
+
"id": "AvatarRigNode.parent",
|
|
4834
|
+
"name": "parent",
|
|
4835
|
+
"anchor": "avatarrignode-parent",
|
|
4836
|
+
"group": "avatars3d",
|
|
4837
|
+
"signature": "readonly parent: string | null",
|
|
4838
|
+
"documented": true,
|
|
4839
|
+
"summary": "The node it is a direct child of; `null` for the rig's root.",
|
|
4840
|
+
"deprecated": null,
|
|
4841
|
+
"params": [],
|
|
4842
|
+
"returns": null,
|
|
4843
|
+
"throws": null,
|
|
4844
|
+
"example": null,
|
|
4845
|
+
"defaultValue": null,
|
|
4846
|
+
"guides": []
|
|
4847
|
+
},
|
|
4848
|
+
{
|
|
4849
|
+
"id": "AvatarRigs",
|
|
4850
|
+
"name": "AvatarRigs",
|
|
4851
|
+
"anchor": "avatarrigs",
|
|
4852
|
+
"group": "avatars3d",
|
|
4853
|
+
"signature": "interface AvatarRigs",
|
|
4854
|
+
"documented": true,
|
|
4855
|
+
"summary": "The rig families this SDK knows, by name.",
|
|
4856
|
+
"deprecated": null,
|
|
4857
|
+
"params": [],
|
|
4858
|
+
"returns": null,
|
|
4859
|
+
"throws": null,
|
|
4860
|
+
"example": null,
|
|
4861
|
+
"defaultValue": null,
|
|
4862
|
+
"guides": []
|
|
4863
|
+
},
|
|
4864
|
+
{
|
|
4865
|
+
"id": "AvatarRigs.small_human",
|
|
4866
|
+
"name": "small_human",
|
|
4867
|
+
"anchor": "avatarrigs-small_human",
|
|
4868
|
+
"group": "avatars3d",
|
|
4869
|
+
"signature": "readonly small_human: readonly AvatarRigNode[]",
|
|
4870
|
+
"documented": true,
|
|
4871
|
+
"summary": "The toy rig: rigid limbs on a body, eight nodes.",
|
|
4872
|
+
"deprecated": null,
|
|
4873
|
+
"params": [],
|
|
4874
|
+
"returns": null,
|
|
4875
|
+
"throws": null,
|
|
4876
|
+
"example": null,
|
|
4877
|
+
"defaultValue": null,
|
|
4878
|
+
"guides": []
|
|
4879
|
+
},
|
|
4880
|
+
{
|
|
4881
|
+
"id": "AvatarRigs.adult_human",
|
|
4882
|
+
"name": "adult_human",
|
|
4883
|
+
"anchor": "avatarrigs-adult_human",
|
|
4884
|
+
"group": "avatars3d",
|
|
4885
|
+
"signature": "readonly adult_human: readonly AvatarRigNode[]",
|
|
4886
|
+
"documented": true,
|
|
4887
|
+
"summary": "The adult humanoid with fingers: 56 nodes, world-aligned at rest.",
|
|
4888
|
+
"deprecated": null,
|
|
4889
|
+
"params": [],
|
|
4890
|
+
"returns": null,
|
|
4891
|
+
"throws": null,
|
|
4892
|
+
"example": null,
|
|
4893
|
+
"defaultValue": null,
|
|
4894
|
+
"guides": []
|
|
4895
|
+
},
|
|
4896
|
+
{
|
|
4897
|
+
"id": "AVATAR_RIGS",
|
|
4898
|
+
"name": "AVATAR_RIGS",
|
|
4899
|
+
"anchor": "avatar_rigs",
|
|
4900
|
+
"group": "avatars3d",
|
|
4901
|
+
"signature": "AVATAR_RIGS: AvatarRigs",
|
|
4902
|
+
"documented": true,
|
|
4903
|
+
"summary": "Every node each rig family requires, with the node it is a direct child of,\nparents before children. Frozen: read it, never change it.\n\nThe platform refuses an upload whose model is missing one of these, has one\nunder another parent, or has one twice (`rig_mismatch`). Extra nodes are\nallowed anywhere. `adult_human` also requires every one of its nodes to be\nworld-aligned at rest; that rule is not in this list, see the guide.\n\n```js\nimport { AVATAR_RIGS } from '@indiegems/gem-web-sdk/sdk';\n\n// Every joint of the worn avatar, by name.\nconst joints = new Map(\n AVATAR_RIGS.adult_human.map(({ node }) => [node, gltf.scene.getObjectByName(node)]),\n);\n\n// A test that one of your own models is on the rig.\nfor (const { node, parent } of AVATAR_RIGS.adult_human) {\n const found = gltf.scene.getObjectByName(node);\n if (!found) throw new Error(`missing ${node}`);\n if (parent !== null && found.parent?.name !== parent) throw new Error(`${node} is not under ${parent}`);\n}\n```",
|
|
4904
|
+
"deprecated": null,
|
|
4905
|
+
"params": [],
|
|
4906
|
+
"returns": null,
|
|
4907
|
+
"throws": null,
|
|
4908
|
+
"example": null,
|
|
4909
|
+
"defaultValue": null,
|
|
4910
|
+
"guides": []
|
|
4911
|
+
},
|
|
4800
4912
|
{
|
|
4801
4913
|
"id": "GemApiError",
|
|
4802
4914
|
"name": "GemApiError",
|
|
@@ -6346,7 +6458,7 @@
|
|
|
6346
6458
|
"group": "platform",
|
|
6347
6459
|
"signature": "interface RewardCue",
|
|
6348
6460
|
"documented": true,
|
|
6349
|
-
"summary": "A platform-currency reward on its way to the arcade — in the Gem Arcade, a\nflight into the Gem button
|
|
6461
|
+
"summary": "A platform-currency reward on its way to the arcade — in the Gem Arcade, a\nflight into the Gem button, in whichever corner of your frame it sits — what\n`gem.cueReward` takes.",
|
|
6350
6462
|
"deprecated": null,
|
|
6351
6463
|
"params": [],
|
|
6352
6464
|
"returns": null,
|
|
@@ -6435,6 +6547,22 @@
|
|
|
6435
6547
|
"defaultValue": null,
|
|
6436
6548
|
"guides": []
|
|
6437
6549
|
},
|
|
6550
|
+
{
|
|
6551
|
+
"id": "GemCorner",
|
|
6552
|
+
"name": "GemCorner",
|
|
6553
|
+
"anchor": "gemcorner",
|
|
6554
|
+
"group": "frame",
|
|
6555
|
+
"signature": "type GemCorner = \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\"",
|
|
6556
|
+
"documented": true,
|
|
6557
|
+
"summary": "A corner of your frame, for `gem.setGemCorner`: where you would like the\narcade's Gem button to sit. `'top-left'` is where it sits unless you ask.\nPhysical corners: `'top-left'` is the top-left in every language.",
|
|
6558
|
+
"deprecated": null,
|
|
6559
|
+
"params": [],
|
|
6560
|
+
"returns": null,
|
|
6561
|
+
"throws": null,
|
|
6562
|
+
"example": null,
|
|
6563
|
+
"defaultValue": null,
|
|
6564
|
+
"guides": []
|
|
6565
|
+
},
|
|
6438
6566
|
{
|
|
6439
6567
|
"id": "FrameState",
|
|
6440
6568
|
"name": "FrameState",
|
|
@@ -6769,6 +6897,29 @@
|
|
|
6769
6897
|
"defaultValue": null,
|
|
6770
6898
|
"guides": []
|
|
6771
6899
|
},
|
|
6900
|
+
{
|
|
6901
|
+
"id": "GemFrame.setGemCorner",
|
|
6902
|
+
"name": "setGemCorner",
|
|
6903
|
+
"anchor": "gemframe-setgemcorner",
|
|
6904
|
+
"group": "frame",
|
|
6905
|
+
"signature": "setGemCorner(corner: GemCorner): boolean",
|
|
6906
|
+
"documented": true,
|
|
6907
|
+
"summary": "Ask the arcade to put its own control over your game — the Gem button —\nin this corner of your frame: the whole answer each time, the latest one\nwinning.\n\nPrefer `gem.setGemCorner`, which holds the corner across a reconnect.\nThis one sends only while connected, and only to an arcade that can move\nits control.",
|
|
6908
|
+
"deprecated": null,
|
|
6909
|
+
"params": [
|
|
6910
|
+
{
|
|
6911
|
+
"name": "corner",
|
|
6912
|
+
"type": "GemCorner",
|
|
6913
|
+
"optional": false,
|
|
6914
|
+
"summary": null
|
|
6915
|
+
}
|
|
6916
|
+
],
|
|
6917
|
+
"returns": "whether the message left the frame — `false` before the bridge is\n up, for an arcade that cannot move its control, for a value that is not\n one of the four corners, and past this frame's own limit.",
|
|
6918
|
+
"throws": null,
|
|
6919
|
+
"example": null,
|
|
6920
|
+
"defaultValue": null,
|
|
6921
|
+
"guides": []
|
|
6922
|
+
},
|
|
6772
6923
|
{
|
|
6773
6924
|
"id": "GemFrame.requestShare",
|
|
6774
6925
|
"name": "requestShare",
|
|
@@ -9401,7 +9552,7 @@
|
|
|
9401
9552
|
"group": "player",
|
|
9402
9553
|
"signature": "readonly reserved: readonly GemReservedArea[]",
|
|
9403
9554
|
"documented": true,
|
|
9404
|
-
"summary": "Rectangles of your frame the arcade's own controls cover — in the Gem\nArcade, its Gem button in
|
|
9555
|
+
"summary": "Rectangles of your frame the arcade's own controls cover — in the Gem\nArcade, its Gem button in whichever corner it sits, and the frame-rate readout\nbeside it while the player shows it; an embedder that draws wallets over\nyour game adds theirs (see `setWalletVisible`). Keep essential UI and touch\ntargets out of them. Empty when the arcade covers nothing.\n\nA stylesheet reads the per-corner custom properties the SDK stamps from\nthese instead — `--gem-reserved-tl-height` and friends.",
|
|
9405
9556
|
"deprecated": null,
|
|
9406
9557
|
"params": [],
|
|
9407
9558
|
"returns": null,
|
|
@@ -10412,7 +10563,7 @@
|
|
|
10412
10563
|
"group": "start",
|
|
10413
10564
|
"signature": "cueReward(cue: RewardCue): boolean",
|
|
10414
10565
|
"documented": true,
|
|
10415
|
-
"summary": "Tell the arcade a platform-currency reward is on its way, so it **shows it\nlanding**: in the Gem Arcade the currency flies from `origin` into the Gem\nbutton
|
|
10566
|
+
"summary": "Tell the arcade a platform-currency reward is on its way, so it **shows it\nlanding**: in the Gem Arcade the currency flies from `origin` into the Gem\nbutton, wherever on your frame it sits, which pops as each mark lands, and\nthe player's total moves once the platform confirms the grant. The Gem\nArcade draws no wallet over your game: the player sees their Gems and\nTickets in the Gem menu. A payout you do not cue still flies, from the\nmiddle of your frame, so cue the ones the player earns on screen.\n\nCall it the moment your game decides to award — when your server has moved\n(or is about to move) the progression mapped onto a platform currency —\nand pass the centre of that currency's icon (or hero) on your screen, so\nthe flight starts from the mark the player is looking at:\n\n```js\nconst { x, y, width, height } = rewardGem.getBoundingClientRect(); // the gem's own box\ngem.cueReward({\n currencySlug: 'GEMS', // or 'ARCADE_TICKETS', from the ticket\n expected: 15,\n origin: { x: x + width / 2, y: y + height / 2 },\n});\n```\n\n**This is the platform-currency animation, and the only one.** The display\nof every platform currency — Gems and Tickets alike — belongs to the\narcade: a game draws no flight or celebration of its own for one and keeps\nno counter of one. **If this returns `false`, do nothing** — there is no\nfallback celebration.\n\n**The arcade never takes your word for the amount.** What lands, and the\nplayer's new total, come from the platform itself; `expected` is drawn as\nprovisional, and a cue the platform never confirms fades on its own — a\ngrant clamped to zero, say, or one the receipt reports `suppressed`. So\nthe cue can only ever make the wallet move for a reward that really\nlanded — which it does on every channel, dev and test included.",
|
|
10416
10567
|
"deprecated": null,
|
|
10417
10568
|
"params": [
|
|
10418
10569
|
{
|
|
@@ -10464,7 +10615,7 @@
|
|
|
10464
10615
|
"group": "start",
|
|
10465
10616
|
"signature": "setMenu(menu: GameMenu): boolean",
|
|
10466
10617
|
"documented": true,
|
|
10467
|
-
"summary": "Put up to four entries of your own in the arcade's menu. The arcade keeps\none menu button over your game: it is how a player leaves, mutes, goes\nfullscreen, reports a problem and changes their Arcade-wide settings.\n\n```js\ngem.setMenu({\n items: [{ id: 'how-to-play', label: t('How to play'), onSelect: () => help.open() }],\n});\n```\n\n**Your settings are not in it: draw your own settings button, always** —\ntop-right, clear of
|
|
10618
|
+
"summary": "Put up to four entries of your own in the arcade's menu. The arcade keeps\none menu button over your game: it is how a player leaves, mutes, goes\nfullscreen, reports a problem and changes their Arcade-wide settings.\n\n```js\ngem.setMenu({\n items: [{ id: 'how-to-play', label: t('How to play'), onSelect: () => help.open() }],\n});\n```\n\n**Your settings are not in it: draw your own settings button, always** —\ntop-right, with your Back button just to its left, clear of\n`gem.viewport.reserved`. The Arcade's menu never opens your settings\nscreen.\n\n**It is screen state, not a toggle.** Each call is the whole answer and\nreplaces the last, so call it again when the entries change — a new\nlanguage, a screen with different options. `gem.setMenu({})` takes\neverything of yours back out. The arcade's own entries are not yours to\nchange, and Return to the Arcade is always among them.\n\n**The arcade pauses your game while its menu is open** (`onPause`), and\nresumes it before a handler of yours runs. A handler opens a screen; it\nshould not assume the game was paused by you.",
|
|
10468
10619
|
"deprecated": null,
|
|
10469
10620
|
"params": [
|
|
10470
10621
|
{
|
|
@@ -10480,6 +10631,29 @@
|
|
|
10480
10631
|
"defaultValue": null,
|
|
10481
10632
|
"guides": []
|
|
10482
10633
|
},
|
|
10634
|
+
{
|
|
10635
|
+
"id": "Gem.setGemCorner",
|
|
10636
|
+
"name": "setGemCorner",
|
|
10637
|
+
"anchor": "gem-setgemcorner",
|
|
10638
|
+
"group": "start",
|
|
10639
|
+
"signature": "setGemCorner(corner: GemCorner): boolean",
|
|
10640
|
+
"documented": true,
|
|
10641
|
+
"summary": "Ask the arcade to put its Gem button — its one control over your game,\ntop-left unless you ask — in another corner of your frame.\n\n```js\n// This game's own HUD needs the top-left, so the Gem goes top-right.\ngem.setGemCorner('top-right');\n```\n\n**Leave it top-left unless your own HUD needs that corner**, and then pick\none corner for the whole game — at most one per orientation. A Gem that\nmoves between screens is a way out the player has to look for. In\nlandscape the bottom corners sit where a player's thumbs hold the sticks.\n\n**Lay out around `gem.viewport.reserved`, never around the corner you\nasked for.** The arcade moves the Gem on its own terms: not while the\nplayer is using it or its menu is open, not more often than every few\nseconds, and never over a corner the player chose for themselves. The\nrectangles say where it actually is, and the `--gem-reserved-*` CSS\nproperties follow them.\n\n**It is screen state, not a toggle.** Each call is the whole answer and\nreplaces the last. A value that is not one of the four corners is ignored,\nwith a warning on the console, and changes nothing.",
|
|
10642
|
+
"deprecated": null,
|
|
10643
|
+
"params": [
|
|
10644
|
+
{
|
|
10645
|
+
"name": "corner",
|
|
10646
|
+
"type": "GemCorner",
|
|
10647
|
+
"optional": false,
|
|
10648
|
+
"summary": "`'top-left'`, `'top-right'`, `'bottom-left'` or `'bottom-right'`."
|
|
10649
|
+
}
|
|
10650
|
+
],
|
|
10651
|
+
"returns": "`true` when the arcade was told now; `false` before the bridge is\n up (the corner is held and sent when it connects), under an embedder that\n cannot move its control, and for a value that is not a corner.",
|
|
10652
|
+
"throws": null,
|
|
10653
|
+
"example": null,
|
|
10654
|
+
"defaultValue": null,
|
|
10655
|
+
"guides": []
|
|
10656
|
+
},
|
|
10483
10657
|
{
|
|
10484
10658
|
"id": "Gem.exit",
|
|
10485
10659
|
"name": "exit",
|
|
@@ -11364,7 +11538,7 @@
|
|
|
11364
11538
|
"name": "protocol",
|
|
11365
11539
|
"anchor": "matchconnection-protocol",
|
|
11366
11540
|
"group": "match",
|
|
11367
|
-
"signature": "readonly protocol: \"
|
|
11541
|
+
"signature": "readonly protocol: \"p2p\" | \"dedicated\" | \"loopback\"",
|
|
11368
11542
|
"documented": true,
|
|
11369
11543
|
"summary": "What is on the other end: `dedicated` (the platform's server), `p2p` (the\nhosting player's browser), or `loopback` (this browser — you are the host,\nand this is the in-process link to your own bundle).",
|
|
11370
11544
|
"deprecated": null,
|
|
@@ -11619,9 +11793,9 @@
|
|
|
11619
11793
|
"name": "Avatar3dFamily",
|
|
11620
11794
|
"anchor": "avatar3dfamily",
|
|
11621
11795
|
"group": "avatars3d",
|
|
11622
|
-
"signature": "type Avatar3dFamily = \"small_human\" | string & object",
|
|
11796
|
+
"signature": "type Avatar3dFamily = \"small_human\" | \"adult_human\" | string & object",
|
|
11623
11797
|
"documented": true,
|
|
11624
|
-
"summary": "A rig family — the skeleton contract a 3D avatar is built on, and what a\ngame declares it can animate. `small_human
|
|
11798
|
+
"summary": "A rig family — the skeleton contract a 3D avatar is built on, and what a\ngame declares it can animate. Two today:\n\n- `small_human`, the toy rig: a `root` node with a `body` child, which holds\n `head`, `arm_l`, `arm_r`, `leg_l` and `leg_r`, and a `hand_socket` under\n `arm_r`.\n- `adult_human`, a full humanoid with fingers: 56 nodes from `root` and\n `hips` down to `toes_r`, every one world-aligned at rest, so one clip plays\n on every avatar in the family.\n\n`AVATAR_RIGS` (from `@indiegems/gem-web-sdk/sdk`) lists every node of\nboth, with its parent.\n\nOpen-ended (`| (string & {})`) so a family the platform adds later does not\nbreak a `switch` you compiled against this version: keep a `default` arm and\nskip a family you do not draw.",
|
|
11625
11799
|
"deprecated": null,
|
|
11626
11800
|
"params": [],
|
|
11627
11801
|
"returns": null,
|
|
@@ -32069,9 +32243,9 @@
|
|
|
32069
32243
|
"name": "Avatar3dFamily",
|
|
32070
32244
|
"anchor": "avatar3dfamily",
|
|
32071
32245
|
"group": "identity",
|
|
32072
|
-
"signature": "type Avatar3dFamily = \"small_human\" | string & object",
|
|
32246
|
+
"signature": "type Avatar3dFamily = \"small_human\" | \"adult_human\" | string & object",
|
|
32073
32247
|
"documented": true,
|
|
32074
|
-
"summary": "A rig family — the skeleton contract a 3D avatar is built on, and what a\ngame declares it can animate. `small_human
|
|
32248
|
+
"summary": "A rig family — the skeleton contract a 3D avatar is built on, and what a\ngame declares it can animate. Two today:\n\n- `small_human`, the toy rig: a `root` node with a `body` child, which holds\n `head`, `arm_l`, `arm_r`, `leg_l` and `leg_r`, and a `hand_socket` under\n `arm_r`.\n- `adult_human`, a full humanoid with fingers: 56 nodes from `root` and\n `hips` down to `toes_r`, every one world-aligned at rest, so one clip plays\n on every avatar in the family.\n\n`AVATAR_RIGS` (from `@indiegems/gem-web-sdk/sdk`) lists every node of\nboth, with its parent.\n\nOpen-ended (`| (string & {})`) so a family the platform adds later does not\nbreak a `switch` you compiled against this version: keep a `default` arm and\nskip a family you do not draw.",
|
|
32075
32249
|
"deprecated": null,
|
|
32076
32250
|
"params": [],
|
|
32077
32251
|
"returns": null,
|