@indiegems/gem-web-sdk 9.0.0 → 9.1.1
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 +12 -0
- package/dist/gem-web-sdk.esm.js +1 -1
- 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/docs/api/api-reference-game.md +43 -9
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +4 -4
- package/docs/changelog.md +12 -0
- package/docs/cross-promotion.md +60 -21
- package/docs/getting-started.md +1 -1
- package/docs/manifest.json +12 -12
- package/docs/rewarded-ads.md +299 -147
- package/docs/server-bundles.md +2 -2
- package/docs/what-a-game-must-do.md +23 -12
- package/package.json +1 -1
- package/schema/bridge.v1.json +17 -5
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/v9.
|
|
84
|
-
curl -fsSL https://downloads.gemarcade.com/sdk/v9.
|
|
83
|
+
curl -fsSL -O https://downloads.gemarcade.com/sdk/v9.1.1/gem-web-sdk.tgz
|
|
84
|
+
curl -fsSL https://downloads.gemarcade.com/sdk/v9.1.1/gem-web-sdk.tgz.sri
|
|
85
85
|
openssl dgst -sha384 -binary gem-web-sdk.tgz | openssl base64 -A
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -528,7 +528,10 @@ credit for it until you say so.
|
|
|
528
528
|
inventory and dialog operable on the standard gamepad mapping with the pointer unused, and a focus
|
|
529
529
|
cue thicker than a hairline — a 1px outline disappears at ten feet. TV remotes arrive as
|
|
530
530
|
**keyboard-class events** (arrows, Enter, Back), so a game that calls itself a keyboard game is a
|
|
531
|
-
D-pad game on a TV whether it planned to be or not.
|
|
531
|
+
D-pad game on a TV whether it planned to be or not. One control a gamepad cannot work: a
|
|
532
|
+
rewarded-ad button. Browsers do not count gamepad input as a press, so a rewarded ask made from
|
|
533
|
+
one is refused ([`rewarded-ads.md` §3](rewarded-ads.md#3-ask-from-the-press-then-re-read)). A
|
|
534
|
+
remote's keys do count. Keep the ordinary way on beside the button working.
|
|
532
535
|
- **Title-safe layout.** HUD and critical UI inset at least ~5% of the frame — roughly 48–96px at
|
|
533
536
|
1080p. `env(safe-area-inset-*)` resolves to **0 on every TV**: overscan is a hardware crop the
|
|
534
537
|
browser cannot see, so no platform can hand you the number and your game must apply its own
|
|
@@ -540,6 +543,12 @@ credit for it until you say so.
|
|
|
540
543
|
- **Text entry the on-screen keyboard can serve.** Focusing a field summons the TV's OSK, so keep
|
|
541
544
|
entry fields few and ordinary — and never gate first play behind one. A player made to type on a
|
|
542
545
|
remote before they may play mostly does not.
|
|
546
|
+
|
|
547
|
+
The same fields have a rule that is not about televisions at all: **give every focusable text
|
|
548
|
+
field a font size of at least 16px**, on every device. Below that, iOS Safari zooms the page in
|
|
549
|
+
when the field takes focus and does not zoom back out, so the game is left cropped off the side of
|
|
550
|
+
the screen until the player pinches it back. A 14px lobby-code box is enough to do it.
|
|
551
|
+
|
|
543
552
|
- **A TV performance budget.** TV-browser SoCs are weak next to any desktop: ship a player-settable
|
|
544
553
|
render-scale option (render at DPR 1 and upscale), bound memory, assume a fixed frame — 16:9, or
|
|
545
554
|
a centred 9:16 column when your store page makes you
|
|
@@ -1122,15 +1131,15 @@ player (`gem.player`), room members, leaderboard rows, friends, profiles, showca
|
|
|
1122
1131
|
async opponent you read through the raw client, once you pass the row through `mapIdentity`. One
|
|
1123
1132
|
renderer serves all of them.
|
|
1124
1133
|
|
|
1125
|
-
| Field | What it is
|
|
1126
|
-
| --------------- |
|
|
1127
|
-
| `playerId` | The player's id. **Absent on an anonymous row**
|
|
1128
|
-
| `displayName` | The name the player chose
|
|
1129
|
-
| `discriminator` | The digits that tell two same-named players apart — `0001`, no `#`
|
|
1130
|
-
| `displayTag` | The precomposed `Name#0001`
|
|
1131
|
-
| `avatarIconId` | The portrait item's id
|
|
1132
|
-
| `avatarIconUrl` | The portrait's thumbnail
|
|
1133
|
-
| `badges` | Equipped badges, at most two, in the player's order, each `{ itemId, iconUrl }`
|
|
1134
|
+
| Field | What it is | Type |
|
|
1135
|
+
| --------------- | ------------------------------------------------------------------------------- | ------------ |
|
|
1136
|
+
| `playerId` | The player's id. **Absent on an anonymous row** | `string` |
|
|
1137
|
+
| `displayName` | The name the player chose | `PlayerText` |
|
|
1138
|
+
| `discriminator` | The digits that tell two same-named players apart — `0001`, no `#` | `string` |
|
|
1139
|
+
| `displayTag` | The precomposed `Name#0001` | `PlayerText` |
|
|
1140
|
+
| `avatarIconId` | The portrait item's id | `string` |
|
|
1141
|
+
| `avatarIconUrl` | The portrait's thumbnail | `string` |
|
|
1142
|
+
| `badges` | Equipped badges, at most two, in the player's order, each `{ itemId, iconUrl }` | array |
|
|
1134
1143
|
|
|
1135
1144
|
**A player chooses what they wear**: a portrait and up to two badges, each an icon they own — one
|
|
1136
1145
|
an achievement in your game or any other may have awarded them ([achievements.md](achievements.md)
|
|
@@ -1283,8 +1292,10 @@ nothing, so a reward must never be handed out on the strength of it.
|
|
|
1283
1292
|
[`cross-promotion.md`](cross-promotion.md) is the page.
|
|
1284
1293
|
|
|
1285
1294
|
A button the player presses for a reward — a revive, an extra attempt — is the same call with
|
|
1286
|
-
`format: 'rewarded'
|
|
1287
|
-
the
|
|
1295
|
+
`format: 'rewarded'`, made from that press itself. The button says it is an ad and names the
|
|
1296
|
+
reward, and the Arcade starts the ad as soon as the ask arrives. Your game config declares what
|
|
1297
|
+
each such button grants, the platform writes the reward into your game's inventory, and your game
|
|
1298
|
+
reads it there rather than from the answer.
|
|
1288
1299
|
[`rewarded-ads.md`](rewarded-ads.md) is that page.
|
|
1289
1300
|
|
|
1290
1301
|
## An account upsell, if your game has something to offer one
|
package/package.json
CHANGED
package/schema/bridge.v1.json
CHANGED
|
@@ -3203,9 +3203,21 @@
|
|
|
3203
3203
|
"",
|
|
3204
3204
|
" RENDER IT IN YOUR OWN CHROME. Labelled as a promotion, dismissible, and",
|
|
3205
3205
|
" focus-trapped over the paused game. Nothing in this message is rendered.",
|
|
3206
|
-
" For `rewarded`, the player pressed the game's button, and
|
|
3207
|
-
"
|
|
3208
|
-
"
|
|
3206
|
+
" For `rewarded`, the player pressed the game's button, and THAT PRESS IS",
|
|
3207
|
+
" THE OPT-IN: the game's label says it is an ad and names the reward, so",
|
|
3208
|
+
" start the ad without a prompt of your own. Label it as an ad for as long",
|
|
3209
|
+
" as it plays, and let the player close it; closing early is a skip and",
|
|
3210
|
+
" pays nothing. Where no ad could play and nothing was granted, say so",
|
|
3211
|
+
" briefly in your own chrome ('No ad available right now').",
|
|
3212
|
+
"",
|
|
3213
|
+
" DO NOT RELY ON THE FRAME HAVING CHECKED FOR A PRESS. SDK releases after",
|
|
3214
|
+
" 9.0.0 send a rewarded ask only while the frame holds user activation,",
|
|
3215
|
+
" where the browser reports it. Every SDK from 5.1.0 to 9.0.0 sends one",
|
|
3216
|
+
" with no such check, so a game pinned to one of those can ask from a",
|
|
3217
|
+
" timer and start an ad with no press, and a hostile frame posts on the",
|
|
3218
|
+
" port directly. Even the check cannot say which press caused an ask:",
|
|
3219
|
+
" activation belongs to the whole frame for a few seconds, so an ask from",
|
|
3220
|
+
" the game's jump button passes it too.",
|
|
3209
3221
|
"",
|
|
3210
3222
|
" PAUSE WITH `gem.pause`. That message already means 'stop running and stop",
|
|
3211
3223
|
" making noise', which is exactly what is wanted while a panel is up. Do",
|
|
@@ -3285,8 +3297,8 @@
|
|
|
3285
3297
|
" no; a game reads it identically to `no_ad`.",
|
|
3286
3298
|
"",
|
|
3287
3299
|
"AFTER A `rewarded` ASK the player pressed a button, so two of those",
|
|
3288
|
-
"readings change. `shown` means
|
|
3289
|
-
"closed
|
|
3300
|
+
"readings change. `shown` means the parent painted something for the ask",
|
|
3301
|
+
"and it has closed - the ad, however it ended - and still grants nothing.",
|
|
3290
3302
|
"`no_ad` can arrive with the reward already granted - where no ad serves",
|
|
3291
3303
|
"and the game's config says to grant without one, for one - so a game",
|
|
3292
3304
|
"reads its own inventory, never the outcome, to learn whether a reward",
|