@indiegems/gem-web-sdk 23.1.0 → 23.1.2

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.
@@ -23,8 +23,8 @@
23
23
  },
24
24
  {
25
25
  "file": "arcade-avatars.md",
26
- "sha256": "e02e435d91e389f9cc2025945ebc0ac11882bac85a4e6d5d74278f11e38fee91",
27
- "updated": "2026-10-21T19:36:16Z"
26
+ "sha256": "d376a0fdc7b36355e08dd60871d8343f98b352df5938100129012248f5dbe7dc",
27
+ "updated": "2026-11-08T20:08:14Z"
28
28
  },
29
29
  {
30
30
  "file": "arcade-economy.md",
@@ -48,8 +48,8 @@
48
48
  },
49
49
  {
50
50
  "file": "changelog.md",
51
- "sha256": "08a45ac742126bf110a16e9373e09a4e06fd4ab8cd68d62309a512a1712c8c53",
52
- "updated": "2026-11-07T14:55:28Z"
51
+ "sha256": "d7d855fb6e811da4755ad43f059729d5d80083a363020ab0d48887d74d102540",
52
+ "updated": "2026-11-09T02:07:41Z"
53
53
  },
54
54
  {
55
55
  "file": "daily-challenges.md",
@@ -73,13 +73,13 @@
73
73
  },
74
74
  {
75
75
  "file": "game-economy-tutorial.md",
76
- "sha256": "0ab25a9d69cf5e40351624355da5ef84e1431bf8a8a420e2c4d7350e20a5b1c5",
77
- "updated": "2026-11-04T16:44:33Z"
76
+ "sha256": "322f4414cf724c7f602fea9fc08a3dd71dd24176f6f7dd5aa47b3607dcaeab53",
77
+ "updated": "2026-11-08T20:08:14Z"
78
78
  },
79
79
  {
80
80
  "file": "getting-started.md",
81
- "sha256": "a711052efd2252ddda2bed1af1394f8c57692086d5e3acdd6ccf2e5b7a14b4fc",
82
- "updated": "2026-11-07T14:55:28Z"
81
+ "sha256": "4c14ee632cd24cb26a3640f30631d7c64121f43e603afd10ff8adec07e1ef899",
82
+ "updated": "2026-11-09T02:07:41Z"
83
83
  },
84
84
  {
85
85
  "file": "graphics-route.md",
@@ -88,8 +88,8 @@
88
88
  },
89
89
  {
90
90
  "file": "inventory-and-catalogs.md",
91
- "sha256": "f5aa4e405989da098317ca704b4dd8b996a1369c78ef0515ed7442886aee85fc",
92
- "updated": "2026-11-04T23:38:54Z"
91
+ "sha256": "f0445a3b56f7a31590acd9ef2874a7f51cc8d89b6fbfc7de9ea5861f1ef555ca",
92
+ "updated": "2026-11-08T20:08:14Z"
93
93
  },
94
94
  {
95
95
  "file": "leaderboards.md",
@@ -118,13 +118,13 @@
118
118
  },
119
119
  {
120
120
  "file": "player-sign-in.md",
121
- "sha256": "df1e39628ccba04b6f7bcd0b90381dfa34a4480330a6af041d9b71bcaefddb5f",
122
- "updated": "2026-09-17T20:51:57Z"
121
+ "sha256": "904fecbeaf35d91e47007cb686f49fe8bf3c25d8646746899d542ef4dd6c5875",
122
+ "updated": "2026-11-09T01:14:38Z"
123
123
  },
124
124
  {
125
125
  "file": "rewarded-ads.md",
126
- "sha256": "0658ec71ae9938040c2a493385cd9e360224b51309b3254438950124ae444743",
127
- "updated": "2026-11-07T02:38:17Z"
126
+ "sha256": "81b421d4bde3f71b40c7a5a173e6a2c114a315215a11491e488872ff9e1909dc",
127
+ "updated": "2026-11-07T16:40:01Z"
128
128
  },
129
129
  {
130
130
  "file": "room-shapes.md",
@@ -143,8 +143,8 @@
143
143
  },
144
144
  {
145
145
  "file": "server-bundles.md",
146
- "sha256": "e0249cef381f23d156443b6a0b73c3a9616055e5434acf39fbdcada04ec0e745",
147
- "updated": "2026-11-07T14:55:28Z"
146
+ "sha256": "90bf6249f6200e66633d6434c517e6142b2d6d8c5c8dfeeb1378bfde24781717",
147
+ "updated": "2026-11-09T02:07:41Z"
148
148
  },
149
149
  {
150
150
  "file": "serverless-functions-js.md",
@@ -62,7 +62,8 @@ and nothing has changed; hide the upsell.
62
62
  `try`/`catch` to write.
63
63
 
64
64
  - **Say nothing on `declined`.** The player saw the prompt and closed it. A "sign-in failed"
65
- message after a deliberate Cancel reads as a bug.
65
+ message after a deliberate Cancel reads as a bug. Keep the button where it was: if the player
66
+ changes their mind and presses it again a few seconds later, the prompt shows again (section 4).
66
67
  - **You are told no reason**, and one will not be added. Why a sign-in did not happen is between
67
68
  the player and the Arcade.
68
69
  - **`unavailable` is ordinary**, not a fault. It is what every call returns outside the Arcade, and
@@ -76,6 +77,14 @@ never as the price of continuing to play. The Arcade decides whether a prompt ap
76
77
  one at a time, and is free to answer `declined` without showing anything to a game that asks too
77
78
  often.
78
79
 
80
+ Right after the player closes the prompt, the Arcade answers your next ask `declined` at once, with
81
+ nothing shown, for a few seconds (3 s today). That catches an ask repeated by accident: a double
82
+ press, or a game that asks again as soon as it hears `declined`. Once those seconds have passed,
83
+ the next ask shows the prompt again, so a player who closed it and then presses your Sign in button
84
+ on purpose gets the prompt, not a button that does nothing. Only the player closing the prompt
85
+ starts this wait; a `declined` answered at once does not start it again. Your game needs no code
86
+ for it: say nothing on `declined`, as above, and leave the button working.
87
+
79
88
  Pressing two upsell buttons does not open two prompts. A second call made while the first is still
80
89
  open joins it, and both resolve with the same answer.
81
90
 
@@ -110,7 +110,23 @@ rewarded_placements:
110
110
  | `cooldown_seconds` | Seconds between two grants to one player, 0 to 86400. Defaults to 0. |
111
111
  | `max_held` | No grant while the player already holds at least this many of the granted item. 1 to 100, and only on a placement whose grants are all items. |
112
112
  | `without_ads` | **Optional:** `grant` or `nothing`, and `nothing` when you leave it out. What a press gets when no ad plays: where no ad serves your channel at all, and where one does but no ad was available for this press or it failed to play (§8). `grant` pays the reward with no ad, within your caps, so write it out only for a reward that is fine to give free. |
113
- | `allowance_currency_slug` | Optional: one of your own currencies that each grant also spends 1 of. Use it when another path in your game must share the same daily cap. It must not be `client_writable`, must have `transfer_policy: none`, and needs a bucket that resets (daily, say) or it never refills. |
113
+ | `allowance_currency_slug` | Optional: one of your own currencies that each grant also spends 1 of. Use it when another path in your game must share the same daily cap. It must not be `client_writable` and must have `transfer_policy: none`. A grant is refused while it is empty (§3). ⚠️ For an allowance your game grants per use, put it in a bucket that never resets (`reset_interval: never`) for now, even though the upload warns `rewarded_placement_allowance_no_reset` (below). |
114
+
115
+ ⚠️ **Until a gem-api fix ships, an allowance in a resetting bucket refuses a player's first
116
+ press.** A grant that creates the player's balance of the allowance currency is not stamped with
117
+ the bucket's current period, so the next order on that player's inventory resets it, and the
118
+ press's own check is that order. A bucket that resets to `reset_amount: 0` (`daily`, say) therefore
119
+ empties the first grant before it can be spent, and the press answers `no_ad` with nothing granted.
120
+ Meanwhile:
121
+
122
+ - **An allowance your game grants per use** (one per level chest, say) needs no refill. Put its
123
+ currency in a bucket with `reset_interval: never`. The upload's
124
+ `rewarded_placement_allowance_no_reset` warning is about refilling, which such an allowance does
125
+ not need, so keep the bucket that never resets when the upload warns.
126
+ - **For a daily cap on this placement alone**, use its own `max_per_day` (§6), which needs no
127
+ allowance.
128
+
129
+ This advice will change once the fix is out.
114
130
 
115
131
  The placement only **selects** a reward your own config declared. Your game sends no reward, no
116
132
  amount, no watch time and no item in the request — nothing from your frame is trusted for that — so
@@ -216,6 +232,7 @@ after a press:
216
232
  | an ad source serves, but no ad was available for this press, or it failed to play | your `without_ads` decides: `grant` grants within your caps, with no ad; `nothing` grants nothing, and the Arcade shows "No ad available right now" |
217
233
  | no ad source serves the channel (§8) | your `without_ads` decides, with no ad |
218
234
  | a cap, a cooldown, `max_held`, the platform's spacing (§6), or something about the player | no |
235
+ | the placement's `allowance_currency_slug` (§2) is empty | no: the answer is `no_ad`, and on `dev` and `test` the console line says the allowance is spent (§10) |
219
236
 
220
237
  The answer is `shown` whenever the Arcade put its ad stage up, however the ad then ended: watched
221
238
  to the end, closed early, or no ad could play and `without_ads` decided. It is `no_ad` when no
@@ -312,8 +329,10 @@ never in a ranked mode — because the platform cannot see a run (§6).
312
329
  **Within those rules, draw it only when `gem.ads.rewardedStatus` says it can pay** (SDK 8.1.0 and
313
330
  later). The status reads the placement's caps as the platform holds them: `declared`, `grantable`,
314
331
  `remainingToday`, `nextEligibleAt`, `heldLimitReached` and `resetsAt`. `grantable` is `false` when
315
- a cap is spent, a cooldown runs, the player holds `max_held`, or rewarded is off on the channel, so
316
- drawing on it never offers a press that is certain to pay nothing. Hide or grey the button out
332
+ a cap is spent, a cooldown runs, the player holds `max_held`, or rewarded is off on the channel.
333
+ It does **not** read the placement's `allowance_currency_slug`: with the allowance empty,
334
+ `grantable` is still `true` and the press answers `no_ad`, so read the allowance currency's balance
335
+ yourself before you draw a placement that declares one (§2). Hide or grey the button out
317
336
  otherwise, and say when it is back from `nextEligibleAt` or `resetsAt`. `grantable` is not a
318
337
  promise: a press can still pay nothing for reasons the read never reports. The status reserves
319
338
  nothing, and it never rejects:
@@ -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/v23.1.0/gem-web-sdk.tgz
84
- curl -fsSL https://downloads.gemarcade.com/sdk/v23.1.0/gem-web-sdk.tgz.sri
83
+ curl -fsSL -O https://downloads.gemarcade.com/sdk/v23.1.2/gem-web-sdk.tgz
84
+ curl -fsSL https://downloads.gemarcade.com/sdk/v23.1.2/gem-web-sdk.tgz.sri
85
85
  openssl dgst -sha384 -binary gem-web-sdk.tgz | openssl base64 -A
86
86
  ```
87
87
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indiegems/gem-web-sdk",
3
- "version": "23.1.0",
3
+ "version": "23.1.2",
4
4
  "description": "postMessage bridge contract between gem-web and browser-playable games",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",