@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
package/docs/arcade-avatars.md
CHANGED
|
@@ -24,10 +24,46 @@ nothing, and nothing else.
|
|
|
24
24
|
|
|
25
25
|
Everything your game calls is on [`gem.avatars3d`](api/api-reference-game.md#gem-avatars3d).
|
|
26
26
|
|
|
27
|
-
## 2. Rig families
|
|
27
|
+
## 2. Rig families
|
|
28
28
|
|
|
29
29
|
A family is a skeleton contract: the node names and parent-child shape every model in it has, so a
|
|
30
|
-
game that animates the family animates every avatar in it.
|
|
30
|
+
game that animates the family animates every avatar in it. There are two:
|
|
31
|
+
|
|
32
|
+
- **`small_human`**, a toy: rigid limbs on a body, eight nodes, no elbows, knees or fingers.
|
|
33
|
+
- **`adult_human`**, a full adult skeleton with a spine, elbows, knees, toes and fingers, 56
|
|
34
|
+
nodes, built so one animation plays on every avatar in the family.
|
|
35
|
+
|
|
36
|
+
Pick the one your characters are made of. A game that draws both kinds declares both (section 3).
|
|
37
|
+
|
|
38
|
+
**Never retype the node names.** `AVATAR_RIGS` lists every node of each family with the node it
|
|
39
|
+
is a direct child of, parents first, so your game finds its joints, and your tests check a model,
|
|
40
|
+
by the names the platform checks:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
import { AVATAR_RIGS } from '@indiegems/gem-web-sdk/sdk';
|
|
44
|
+
|
|
45
|
+
AVATAR_RIGS.adult_human; // [{ node: 'root', parent: null }, { node: 'hips', parent: 'root' }, …]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### What every family's upload must pass
|
|
49
|
+
|
|
50
|
+
The platform checks every model when it is uploaded, and gemctl runs the same checks on your
|
|
51
|
+
machine first. A model is refused when it breaks any of these:
|
|
52
|
+
|
|
53
|
+
- **The names are exact and case-sensitive**, each appears **exactly once**, and each is the
|
|
54
|
+
**direct child** of the parent its family gives. The family's `root` is a root node of the
|
|
55
|
+
scene.
|
|
56
|
+
- **Anything else is allowed**: extra nodes anywhere (twist bones, a cape, accessories), meshes,
|
|
57
|
+
materials, skins and animation clips. A rig is a floor, not a ceiling.
|
|
58
|
+
- **Nothing outside the file.** Buffers are embedded, and an image is embedded or a `data:` URI.
|
|
59
|
+
An external URI is refused.
|
|
60
|
+
- **No compression extension.** Draco and meshopt are refused. The extensions a model may
|
|
61
|
+
_require_ are `KHR_materials_unlit`, `KHR_texture_transform` and `KHR_mesh_quantization`.
|
|
62
|
+
- **At most 2 MiB** for the `.glb`.
|
|
63
|
+
- **A portrait**: a still, square PNG, 256 to 1024 pixels, at most 2 MiB — what shop tiles and
|
|
64
|
+
rosters show where loading the model is too much.
|
|
65
|
+
|
|
66
|
+
### `small_human`
|
|
31
67
|
|
|
32
68
|
```
|
|
33
69
|
root
|
|
@@ -40,29 +76,155 @@ root
|
|
|
40
76
|
└── leg_r
|
|
41
77
|
```
|
|
42
78
|
|
|
43
|
-
|
|
44
|
-
of
|
|
79
|
+
`body` is the child of `root`; `head`, `arm_l`, `arm_r`, `leg_l` and `leg_r` are children of
|
|
80
|
+
`body`; `hand_socket` is a child of `arm_r`. A held item goes on `hand_socket`. Nothing is checked
|
|
81
|
+
about its pose or its size.
|
|
45
82
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
83
|
+
### `adult_human`
|
|
84
|
+
|
|
85
|
+
`_l` and `_r` are the **character's** left and right.
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
root the ground between the feet
|
|
89
|
+
└── hips
|
|
90
|
+
├── spine
|
|
91
|
+
│ └── chest
|
|
92
|
+
│ └── upper_chest
|
|
93
|
+
│ ├── neck
|
|
94
|
+
│ │ └── head
|
|
95
|
+
│ │ └── head_socket hats and helmets
|
|
96
|
+
│ ├── shoulder_l
|
|
97
|
+
│ │ └── upper_arm_l
|
|
98
|
+
│ │ └── lower_arm_l
|
|
99
|
+
│ │ └── hand_l
|
|
100
|
+
│ │ ├── hand_socket_l held items
|
|
101
|
+
│ │ ├── thumb_1_l > thumb_2_l > thumb_3_l
|
|
102
|
+
│ │ ├── index_1_l > index_2_l > index_3_l
|
|
103
|
+
│ │ ├── middle_1_l > middle_2_l > middle_3_l
|
|
104
|
+
│ │ ├── ring_1_l > ring_2_l > ring_3_l
|
|
105
|
+
│ │ └── little_1_l > little_2_l > little_3_l
|
|
106
|
+
│ └── shoulder_r … the same as the left, with hand_socket_r
|
|
107
|
+
├── upper_leg_l
|
|
108
|
+
│ └── lower_leg_l
|
|
109
|
+
│ └── foot_l
|
|
110
|
+
│ └── toes_l
|
|
111
|
+
└── upper_leg_r > lower_leg_r > foot_r > toes_r
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`a > b > c` is a chain: `b` is the child of `a`, and `c` of `b`. That is 56 nodes: `root`, six
|
|
115
|
+
down the middle, four in each arm, fifteen finger joints in each hand, four in each leg, and three
|
|
116
|
+
sockets.
|
|
117
|
+
|
|
118
|
+
**Space and units are glTF's own**: Y is up, the character faces **+Z**, and a unit is a
|
|
119
|
+
**metre**. Its left hand is toward +X. `root` sits at the origin, on the ground between the feet.
|
|
120
|
+
|
|
121
|
+
**The rest pose is a T-pose**: legs straight down, arms straight out to the sides (the left along
|
|
122
|
+
+X, the right along −X), palms down, fingers straight along the arm, and the thumb forward (+Z)
|
|
123
|
+
and slightly out.
|
|
124
|
+
|
|
125
|
+
**Every rig node is world-aligned at rest.** Each of the 56 has an identity rotation and a scale
|
|
126
|
+
of 1; only its position differs from one avatar to the next. This is what makes animation
|
|
127
|
+
portable: a rotation you set on a joint is measured from the same rest on every avatar, so a clip
|
|
128
|
+
written for one plays the same on a tall, short, thin or wide one. A model whose bones keep the
|
|
129
|
+
turn a modelling tool gives them (Blender, for one, exports each bone turned to point along its
|
|
130
|
+
length) would play every clip twisted, so the platform refuses it. On top of the checks every
|
|
131
|
+
family passes, an `adult_human` model is refused when:
|
|
132
|
+
|
|
133
|
+
- **a rig node is rotated** more than 2° from identity, or **scaled** more than 0.001 from 1;
|
|
134
|
+
- **a rig node uses `matrix`** instead of translation, rotation and scale;
|
|
135
|
+
- **`root` is moved** more than 1 mm from the origin;
|
|
136
|
+
- **the hips are not 0.6 to 1.3 m up** (the heights of `root` and `hips` added): a model exported
|
|
137
|
+
in centimetres is a hundred times too big, and a toy is too small.
|
|
138
|
+
|
|
139
|
+
**The sockets** are plain nodes, empties or bones. `head_socket` sits on the crown of the head,
|
|
140
|
+
where a cap's band rests. `hand_socket_l` and `hand_socket_r` sit at the centre of the closed
|
|
141
|
+
grip, inside the curled fingers. Like every rig node they are world-aligned, so a hat or a bat
|
|
142
|
+
modelled upright, facing +Z, with its grip at its origin, sits the same way on every avatar.
|
|
143
|
+
Where a socket sits is not checked; the reference rig (below) follows it.
|
|
144
|
+
|
|
145
|
+
**Keep it light for a phone.** Not checked, but every game that accepts the family loads the
|
|
146
|
+
model, and other players' avatars beside it: up to 15,000 triangles, one 1024 × 1024 texture
|
|
147
|
+
(embedded JPEG or PNG), and up to four bone influences per vertex.
|
|
148
|
+
|
|
149
|
+
**Start from the reference rig.** The package ships one:
|
|
150
|
+
`node_modules/@indiegems/gem-web-sdk/rigs/adult_human.glb`, a plain skinned mannequin about
|
|
151
|
+
1.75 m tall, with no textures and no clips, that passes every check above. Make your game's clips
|
|
152
|
+
on it, and test your own avatars against it; import it by path
|
|
153
|
+
(`@indiegems/gem-web-sdk/rigs/adult_human.glb`) for a test scene. To export a rig of your own from
|
|
154
|
+
Blender with an identity rest: give every bone the same orientation in armature space (pointing
|
|
155
|
+
up, its local Z toward the character's front), make the sockets bones, keep the armature object
|
|
156
|
+
as the node `root`, and export with **+Y Up** on, `export_rest_position_armature=True` and
|
|
157
|
+
`export_def_bones=False`.
|
|
158
|
+
|
|
159
|
+
**Uploads wait for the platform to enable the family.** Where it is not enabled yet, an
|
|
160
|
+
`adult_human` upload is refused with `unknown_avatar_family`. Build and test against the
|
|
161
|
+
reference rig until then; nothing in your game changes when it is.
|
|
162
|
+
|
|
163
|
+
#### Pose it, or play your own clip on it
|
|
164
|
+
|
|
165
|
+
The model's own clips are its maker's and no contract. Your game brings its own animations and
|
|
166
|
+
plays them on the rig's names. Load the avatar as section 7 shows, then find the joints:
|
|
167
|
+
|
|
168
|
+
```js
|
|
169
|
+
import * as THREE from 'three';
|
|
170
|
+
import { AVATAR_RIGS } from '@indiegems/gem-web-sdk/sdk';
|
|
171
|
+
|
|
172
|
+
const joints = {};
|
|
173
|
+
for (const { node } of AVATAR_RIGS.adult_human) joints[node] = avatar.getObjectByName(node);
|
|
174
|
+
|
|
175
|
+
joints.hand_socket_r.add(bat); // a held item, modelled upright, facing +Z, grip at its origin
|
|
176
|
+
joints.head_socket.add(cap);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Pose it in code** by setting rotations on named joints. Every angle is measured from the
|
|
180
|
+
T-pose, because the rest rotation is identity, and `quaternion.identity()` puts a joint back:
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
function sitAtTheWheel() {
|
|
184
|
+
for (const joint of Object.values(joints)) joint.quaternion.identity(); // back to the T-pose
|
|
185
|
+
joints.upper_leg_l.rotation.x = joints.upper_leg_r.rotation.x = -Math.PI / 2; // thighs forward
|
|
186
|
+
joints.lower_leg_l.rotation.x = joints.lower_leg_r.rotation.x = Math.PI / 2; // shins down
|
|
187
|
+
joints.upper_arm_l.rotation.y = -Math.PI / 2; // left arm forward
|
|
188
|
+
joints.upper_arm_r.rotation.y = Math.PI / 2; // right arm forward
|
|
189
|
+
for (const finger of ['index', 'middle', 'ring', 'little']) {
|
|
190
|
+
for (const k of [1, 2, 3]) {
|
|
191
|
+
joints[`${finger}_${k}_l`].rotation.z = -1.2; // curl toward the palm
|
|
192
|
+
joints[`${finger}_${k}_r`].rotation.z = 1.2;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Play a clip** you made on the reference rig, from a file of your own. Its tracks name the rig's
|
|
199
|
+
nodes, so a mixer on any avatar finds them:
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
const { animations } = await loader.loadAsync('/anims/driver.glb'); // your clips, not the avatar's
|
|
203
|
+
const seated = THREE.AnimationClip.findByName(animations, 'seated');
|
|
204
|
+
seated.tracks = seated.tracks.filter((track) => track.name.endsWith('.quaternion'));
|
|
205
|
+
|
|
206
|
+
const mixer = new THREE.AnimationMixer(avatar);
|
|
207
|
+
mixer.clipAction(seated).play();
|
|
208
|
+
// every frame: mixer.update(dt)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- **Keep only the rotation tracks.** A position or scale track carries the reference rig's bone
|
|
212
|
+
lengths onto every avatar: a short player's hips are lifted to the reference rig's height. Move
|
|
213
|
+
and turn the whole character by the object that holds it.
|
|
214
|
+
- **Scale the object that holds the avatar, never a rig node**, when your world is not in metres.
|
|
215
|
+
- **One loaded copy per character on screen.** Two players wearing the same avatar need two
|
|
216
|
+
copies: clone a skinned model with three.js's `SkeletonUtils.clone`, never `Object3D.clone`,
|
|
217
|
+
which leaves both copies' meshes moving with one skeleton.
|
|
218
|
+
|
|
219
|
+
### When an upload is refused
|
|
59
220
|
|
|
60
|
-
| What you get
|
|
61
|
-
|
|
|
62
|
-
| `rig_mismatch`
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
221
|
+
| What you get | What happened | What to do |
|
|
222
|
+
| ----------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
|
|
223
|
+
| `rig_mismatch` | a node is missing, under the wrong parent, or named twice | read `details.missing`, `misplaced` and `duplicated`, rename in your modelling tool, upload again |
|
|
224
|
+
| `rig_mismatch` with `details.not_at_rest` | an `adult_human` rig node is not at rest, or the model is the wrong size | read each `{ node, reason }`, e.g. `"rotated 37°"` or `"hips at 92 m"`; apply rotation and scale, export in metres |
|
|
225
|
+
| `model_external_reference` | the file points at a buffer or image outside it | export as a single binary `.glb` with textures embedded |
|
|
226
|
+
| `model_extension_unsupported` | the file requires Draco, meshopt or another extension | export without compression |
|
|
227
|
+
| `unknown_avatar_family` | the family is not one the platform knows, or not enabled yet | use `small_human` or `adult_human`; an `adult_human` upload waits until it is enabled |
|
|
66
228
|
|
|
67
229
|
## 3. Declare the families your game accepts
|
|
68
230
|
|
|
@@ -85,6 +247,10 @@ gemctl config promote <version> --channel release --yes
|
|
|
85
247
|
|
|
86
248
|
- **The order is meaningful.** The first family is your default: it is the one the flat
|
|
87
249
|
`gem.player.avatar3dId` fields describe. Up to eight families, no repeats.
|
|
250
|
+
- **A game can declare both families**, `families: [adult_human, small_human]`, when it draws
|
|
251
|
+
both kinds of character. A player wears one avatar in each family, so ask for the one you draw
|
|
252
|
+
by name, `worn('adult_human') ?? worn('small_human')`, and animate each on its own rig: a
|
|
253
|
+
clip made for one rig does not fit the other.
|
|
88
254
|
- **Each channel reads its own config.** A channel whose config declares no families accepts
|
|
89
255
|
none: the Arcade shows no 3D picker in your game there, and nothing is for sale.
|
|
90
256
|
- **Read it back** with `gem.avatars3d.families()`, which resolves the declared list from the
|
|
@@ -97,8 +263,9 @@ gemctl item upload red-knight.glb --family small_human --portrait red-knight.png
|
|
|
97
263
|
--slug red-knight --name "Red Knight" --description "Sworn to the hearth."
|
|
98
264
|
```
|
|
99
265
|
|
|
100
|
-
A `.glb` file makes an avatar
|
|
101
|
-
|
|
266
|
+
A `.glb` file makes an avatar; `--family adult_human` uploads one on the adult rig. gemctl checks
|
|
267
|
+
the rig (and an `adult_human` model's rest pose), the size and the external references on your
|
|
268
|
+
machine before it uploads, so a broken model costs no upload; the platform checks again and
|
|
102
269
|
renders the item, and the command waits until it is `ready`.
|
|
103
270
|
|
|
104
271
|
- **An avatar cannot be changed after upload.** A fixed model is a new item with a new slug — the
|
|
@@ -249,7 +416,8 @@ gem.avatars3d.onChange(wear);
|
|
|
249
416
|
there you see your default look.
|
|
250
417
|
- **A model URL never changes what it serves**, so cache by URL. When one fails to load, show your
|
|
251
418
|
default look and do not retry in a loop; the next `onChange` is the next chance.
|
|
252
|
-
- **Attach and animate by the rig's names.** Look nodes up by name, never by index
|
|
419
|
+
- **Attach and animate by the rig's names.** Look nodes up by name, never by index. This is a
|
|
420
|
+
`small_human` model; an `adult_human` one is posed and animated as section 2 shows:
|
|
253
421
|
|
|
254
422
|
```js
|
|
255
423
|
function setCharacter(scene, clips) {
|
package/docs/brand-art.md
CHANGED
|
@@ -283,7 +283,7 @@ decision of that date); the ruling's other rules are unchanged. In rules:
|
|
|
283
283
|
|
|
284
284
|
- **Keep no Gems counter.** Your game shows no Gems balance, running total or wallet of its own, on
|
|
285
285
|
any screen. The arcade's wallet is the only place Gems accrue, and the only place a total is shown
|
|
286
|
-
— in the Gem Arcade, the Gem menu, which the player opens from the Gem button
|
|
286
|
+
— in the Gem Arcade, the Gem menu, which the player opens from the Gem button.
|
|
287
287
|
- **Draw no Gems flight or celebration of your own.** No particles flying to a corner, no counting-up
|
|
288
288
|
number, no burst of gems. `gem.cueReward` is the animation, and the arcade draws it.
|
|
289
289
|
- **Show no Gems amount at all when you are not connected to the arcade.** Without the arcade there is
|
|
@@ -308,8 +308,8 @@ decision of that date); the ruling's other rules are unchanged. In rules:
|
|
|
308
308
|
|
|
309
309
|
A Tickets payout is cued the same way, from the ticket, with `currencySlug: 'ARCADE_TICKETS'`. The
|
|
310
310
|
slug decides what flies — gems or tickets — and which total the platform moves. In the Gem Arcade
|
|
311
|
-
every payout flies into the Gem button
|
|
312
|
-
your game.
|
|
311
|
+
every payout flies into the Gem button, in whichever corner of your frame it sits; no wallet is
|
|
312
|
+
drawn over your game.
|
|
313
313
|
- **If `cueReward` returns `false`, do nothing.** There is no fallback celebration. `false` means the
|
|
314
314
|
arcade will not show the payout here — the bridge is not up, or the embedder has no wallet — and
|
|
315
315
|
your game does not replace it with one of its own. Your reward screen still says what was earned;
|
package/docs/changelog.md
CHANGED
|
@@ -16,6 +16,20 @@ 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
|
+
## 13.1.0
|
|
20
|
+
|
|
21
|
+
Upgrading from 13.0.0. Impact: required.
|
|
22
|
+
|
|
23
|
+
### Rebuild
|
|
24
|
+
|
|
25
|
+
- Avatar3dFamily now also accepts adult_human alongside small_human. Recompile your game. If any code switches over the family and assumes small_human is the only named value, add handling for adult_human or a sensible default.
|
|
26
|
+
- The list of messages a frame sends to its parent, the FrameMessage type, and the GemCapability type each gained a member for the Gem button corner (the gem.gemCorner message and the gemCorner capability). Recompile your game. If your code matches these unions exhaustively, add a case for the new member.
|
|
27
|
+
|
|
28
|
+
### New capability
|
|
29
|
+
|
|
30
|
+
- Your game can now ask the Arcade to move its Gem button to another corner by calling setGemCorner, using the GemCorner type for the value. Check that the gemCorner capability is available before relying on it, since the Arcade decides whether to honour the request.
|
|
31
|
+
- The adult_human avatar rig family is now available, and AVATAR_RIGS exposes the node and parent trees of both the small_human and adult_human rigs, described by the AvatarRigNode and AvatarRigs types. The package also ships a reference rig for adult_human, reachable through a new rigs export. Use these to attach items or animations to the right nodes of either family.
|
|
32
|
+
|
|
19
33
|
## 13.0.0
|
|
20
34
|
|
|
21
35
|
Upgrading from 12.0.0. Impact: required.
|
package/docs/getting-started.md
CHANGED
|
@@ -50,7 +50,7 @@ either way.
|
|
|
50
50
|
```jsonc
|
|
51
51
|
// package.json
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@indiegems/gem-web-sdk": "13.
|
|
53
|
+
"@indiegems/gem-web-sdk": "13.1.0"
|
|
54
54
|
}
|
|
55
55
|
```
|
|
56
56
|
|
|
@@ -178,7 +178,8 @@ gem.frame.progress(loaded, total); // while assets load
|
|
|
178
178
|
gem.frame.ready(); // once the player can actually play
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
And draw a settings button of your own — top-right
|
|
181
|
+
And draw a settings button of your own — top-right, with your Back button just to its left
|
|
182
|
+
([the top of the screen](what-a-game-must-do.md#the-top-of-the-screen)) — whose values start from
|
|
182
183
|
the player's Arcade-wide defaults, `gem.prefs.recommended`, until the player chooses their own
|
|
183
184
|
([what a game must do](what-a-game-must-do.md#game-settings)). The Arcade's menu does not open
|
|
184
185
|
your settings. Outside the Arcade there is no Arcade menu at all, so also give players a way out — a
|
|
@@ -590,7 +590,7 @@ the source progression from a function the player calls, on a progression that o
|
|
|
590
590
|
|
|
591
591
|
**Platform-currency display belongs to the arcade** (the creator's ruling, 2026-09-24) — Gems and
|
|
592
592
|
Tickets alike. The arcade shows the player's platform currencies in its own chrome — in the Gem
|
|
593
|
-
Arcade, the Gem menu the player opens from the Gem button
|
|
593
|
+
Arcade, the Gem menu the player opens from the Gem button over your frame; no wallet
|
|
594
594
|
is drawn over your game — and moves a total when the platform confirms a grant. Your game keeps no counter or balance
|
|
595
595
|
of a platform currency of its own, draws no flight or celebration of its own, and shows no
|
|
596
596
|
platform-currency amount at all when it is not connected to the arcade.
|
package/docs/manifest.json
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
"file": "arcade-avatars.md",
|
|
21
|
-
"sha256": "
|
|
22
|
-
"updated": "2026-10-
|
|
21
|
+
"sha256": "7269a0dbd515e2c52e63f9fad2b3028e136396522aa68aa177c44f7eceb2c0e0",
|
|
22
|
+
"updated": "2026-10-14T19:48:50Z"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"file": "arcade-economy.md",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"file": "brand-art.md",
|
|
36
|
-
"sha256": "
|
|
37
|
-
"updated": "2026-10-
|
|
36
|
+
"sha256": "44ba566da97e499f80b6c4898a5546bf7fb3dfba2290da9aa3e8d4e6056a7cce",
|
|
37
|
+
"updated": "2026-10-14T21:18:16Z"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"file": "changelog.md",
|
|
41
|
-
"sha256": "
|
|
42
|
-
"updated": "2026-10-
|
|
41
|
+
"sha256": "3041e5a29aec35ed4a1d299410d9a0795a7c48958f314a6497ca2b567ccaf000",
|
|
42
|
+
"updated": "2026-10-14T22:00:06Z"
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
"file": "cross-promotion.md",
|
|
@@ -73,13 +73,13 @@
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"file": "getting-started.md",
|
|
76
|
-
"sha256": "
|
|
77
|
-
"updated": "2026-10-
|
|
76
|
+
"sha256": "651392ad1b3bb28bd43cfb0a0df0a88b3d8c2e46a4bbb1cb9fcbbe762459f22e",
|
|
77
|
+
"updated": "2026-10-14T22:00:06Z"
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
"file": "inventory-and-catalogs.md",
|
|
81
|
-
"sha256": "
|
|
82
|
-
"updated": "2026-10-
|
|
81
|
+
"sha256": "4251f451c48ab80bb7a9c50a6a717dfca6e057ff128d32ecb5e2cd13d28c5b7d",
|
|
82
|
+
"updated": "2026-10-14T21:18:16Z"
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"file": "leaderboards.md",
|
|
@@ -128,8 +128,8 @@
|
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"file": "server-bundles.md",
|
|
131
|
-
"sha256": "
|
|
132
|
-
"updated": "2026-10-
|
|
131
|
+
"sha256": "c83325c8471f0ea2578f3476660751ad7f4fd96a51eb902336e57d7553ec5e46",
|
|
132
|
+
"updated": "2026-10-14T22:00:06Z"
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"file": "serverless-functions-js.md",
|
|
@@ -153,8 +153,8 @@
|
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
155
|
"file": "what-a-game-must-do.md",
|
|
156
|
-
"sha256": "
|
|
157
|
-
"updated": "2026-10-
|
|
156
|
+
"sha256": "7006e2e2900d71417002937d51a8d10ad9bcfdf02cd1b27f0f923e4cbe4ee79b",
|
|
157
|
+
"updated": "2026-10-14T21:18:16Z"
|
|
158
158
|
}
|
|
159
159
|
]
|
|
160
160
|
}
|
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/v13.
|
|
84
|
-
curl -fsSL https://downloads.gemarcade.com/sdk/v13.
|
|
83
|
+
curl -fsSL -O https://downloads.gemarcade.com/sdk/v13.1.0/gem-web-sdk.tgz
|
|
84
|
+
curl -fsSL https://downloads.gemarcade.com/sdk/v13.1.0/gem-web-sdk.tgz.sri
|
|
85
85
|
openssl dgst -sha384 -binary gem-web-sdk.tgz | openssl base64 -A
|
|
86
86
|
```
|
|
87
87
|
|