@indiegems/gem-web-sdk 7.9.0 → 7.9.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 +69 -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 +1 -1
- package/dist/gem-web-sdk.min.js +2 -2
- package/dist/gem-web-sdk.sdk.js +1 -1
- package/dist/gem-web-sdk.server.js +1 -1
- package/docs/api/api-reference-game.md +12 -8
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +3 -3
- package/docs/changelog.md +69 -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 +94 -63
- package/package.json +1 -1
|
@@ -571,73 +571,117 @@ the `var()` above, or read `gem.viewport`. The release checklist looks for the b
|
|
|
571
571
|
|
|
572
572
|
### The arcade's own controls: reserved areas
|
|
573
573
|
|
|
574
|
-
On a phone your game is full-bleed, and the arcade keeps one
|
|
575
|
-
**top-right corner**:
|
|
574
|
+
On a phone your game is full-bleed, and the arcade keeps one row of its own over the top of it:
|
|
576
575
|
|
|
577
|
-
- **The menu button**, in the corner
|
|
576
|
+
- **The menu button**, in the **top-right corner**, always there. It opens
|
|
578
577
|
[the Arcade's menu](#the-arcades-menu-your-settings-live-in-it): Return to the Arcade, your
|
|
579
578
|
settings, mute and the rest.
|
|
580
|
-
- **The player's wallets** (Gems, Tickets, their achievement score),
|
|
581
|
-
|
|
582
|
-
|
|
579
|
+
- **The player's wallets** (Gems, Tickets, their achievement score), in the **middle of the row**,
|
|
580
|
+
[always there](#the-arcades-wallet-always-shown-never-drawn), during play as well as on your
|
|
581
|
+
menus. They are translucent, so your game shows through them — but they are still the Arcade's,
|
|
582
|
+
and still taps the Arcade takes.
|
|
583
583
|
|
|
584
|
-
**The top
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
584
|
+
**The top of the screen has one layout, in every game:**
|
|
585
|
+
|
|
586
|
+
| Where | Whose | What goes there |
|
|
587
|
+
| -------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
588
|
+
| **Top-left** | yours | Your **Home / Back** buttons, drawn when a screen needs them, in the space to the left of the wallets. They move around _inside_ your game — back to your level select or title screen — and never leave it. |
|
|
589
|
+
| **Middle and top-right** | the Arcade's | Its wallets and its menu button. Nothing of yours. |
|
|
590
|
+
| **Centre and right, below the Arcade's row** | yours | Your **information**: score, moves, a timer, a level name. It starts under the bottom of the Arcade's row, never beside it or under it. |
|
|
591
|
+
|
|
592
|
+
Keep the left for Home / Back even on a screen that has neither today: a player learns where "back"
|
|
593
|
+
is once, across every game, and information that sits there on one screen teaches them the wrong
|
|
594
|
+
thing on the next.
|
|
595
|
+
|
|
596
|
+
**Put no settings, pause-menu or burger button of your own top-right**: your settings open from the
|
|
597
|
+
Arcade's menu, and a second button under the Arcade's would mean something else in every game.
|
|
598
|
+
|
|
599
|
+
**How much room the top-left has.** The menu button is about 48px across — the size of a Home or
|
|
600
|
+
Back button. With every wallet shown, the narrowest phones (360px wide) leave roughly 68px to the
|
|
601
|
+
left of the wallets: room for **one** button. Two buttons, or a wide one, go on their own row below
|
|
602
|
+
the Arcade's. Do not copy those numbers — read the space, as below.
|
|
588
603
|
|
|
589
604
|
Those rectangles of your frame are **reserved**: keep essential UI and every touch target out of
|
|
590
605
|
them. **Never hard-code their size or height.** They differ by phone, and in native fullscreen the
|
|
591
606
|
whole row may rise into the camera band — read them, as below.
|
|
592
607
|
|
|
593
|
-
An inset cannot say that — as a top inset, a
|
|
608
|
+
An inset cannot say that — as a top inset, a button a few dozen pixels wide would take your whole top
|
|
594
609
|
strip. So `gem.viewport` also carries the rectangles, in the same CSS pixels of your frame, measured
|
|
595
|
-
from its top-left corner:
|
|
610
|
+
from its top-left corner — one per wallet shown, and one for the menu button:
|
|
596
611
|
|
|
597
612
|
```json
|
|
598
613
|
{
|
|
599
614
|
"insets": { "top": 47, "right": 0, "bottom": 34, "left": 0 },
|
|
600
|
-
"reserved": [
|
|
615
|
+
"reserved": [
|
|
616
|
+
{ "x": 68, "y": 51, "width": 72, "height": 28 },
|
|
617
|
+
{ "x": 144, "y": 51, "width": 72, "height": 28 },
|
|
618
|
+
{ "x": 220, "y": 51, "width": 72, "height": 28 },
|
|
619
|
+
{ "x": 304, "y": 51, "width": 48, "height": 48 }
|
|
620
|
+
]
|
|
601
621
|
}
|
|
602
622
|
```
|
|
603
623
|
|
|
604
624
|
**The SDK turns them into one pair of custom properties per corner**, written beside
|
|
605
625
|
`--gem-safe-*` before anything else hears the push: `--gem-reserved-tl-width` and
|
|
606
626
|
`--gem-reserved-tl-height`, and the same pair for `tr`, `bl` and `br` — how far that corner's
|
|
607
|
-
reserved rectangles reach in from its two edges.
|
|
627
|
+
reserved rectangles reach in from its two edges. A rectangle belongs to the corner its centre lies
|
|
628
|
+
nearest to.
|
|
629
|
+
|
|
630
|
+
⚠️ **The wallets sit in the middle, so they count toward BOTH top corners.** A wallet left of
|
|
631
|
+
centre is a top-left rectangle, one right of centre a top-right one. While wallets are shown,
|
|
632
|
+
`--gem-reserved-tl-height` is the bottom of the wallets and `--gem-reserved-tl-width` reaches to the
|
|
633
|
+
middle of the screen — even though the corner itself, left of the first wallet, is clear. So:
|
|
608
634
|
|
|
609
635
|
```css
|
|
610
|
-
/* your
|
|
636
|
+
/* your information — score, moves, a timer — below the WHOLE of the arcade's row: the taller of
|
|
637
|
+
the two top corners. It moves up by itself when gameplay hides the wallets. */
|
|
638
|
+
#info {
|
|
639
|
+
top: max(
|
|
640
|
+
var(--gem-safe-top, env(safe-area-inset-top, 0px)),
|
|
641
|
+
var(--gem-reserved-tl-height, 0px),
|
|
642
|
+
var(--gem-reserved-tr-height, 0px)
|
|
643
|
+
);
|
|
644
|
+
right: var(--gem-safe-right, 0px);
|
|
645
|
+
}
|
|
646
|
+
/* ONE Home or Back button, level with the arcade's row, in the clear corner to the wallets' left */
|
|
611
647
|
#back {
|
|
612
648
|
top: var(--gem-safe-top, env(safe-area-inset-top, 0px));
|
|
613
649
|
left: var(--gem-safe-left, 0px);
|
|
614
650
|
}
|
|
615
|
-
/* a
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
padding-right: var(--gem-reserved-tr-width, 0px);
|
|
651
|
+
/* a ROW of your own buttons does not fit beside the wallets: start it below the arcade's row,
|
|
652
|
+
like your information */
|
|
653
|
+
#nav {
|
|
654
|
+
top: max(
|
|
655
|
+
var(--gem-safe-top, env(safe-area-inset-top, 0px)),
|
|
656
|
+
var(--gem-reserved-tl-height, 0px),
|
|
657
|
+
var(--gem-reserved-tr-height, 0px)
|
|
658
|
+
);
|
|
624
659
|
}
|
|
625
660
|
```
|
|
626
661
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
662
|
+
The per-corner properties cannot say how wide the clear corner is — only that the corner's
|
|
663
|
+
rectangles reach in to the middle. To know whether your button fits beside the wallets, read the
|
|
664
|
+
rectangles from script: the clear width at the top-left is the smallest `x` among
|
|
665
|
+
`gem.viewport.reserved` (the whole width when the list is empty).
|
|
631
666
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
667
|
+
```js
|
|
668
|
+
const reserved = gem.viewport?.reserved ?? [];
|
|
669
|
+
const clearLeft = reserved.length ? Math.min(...reserved.map((r) => r.x)) : window.innerWidth;
|
|
670
|
+
nav.classList.toggle('below-arcade-row', clearLeft < nav.offsetWidth + 8);
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
All eight properties are written on every push, `0px` for a clear corner, so a rotation never leaves
|
|
674
|
+
a stale value; they are never set under an embedder that sends no viewport, which is what the `0px`
|
|
675
|
+
fallback is for. `gem.viewport.reserved` is `[]` when nothing is covered.
|
|
676
|
+
|
|
677
|
+
**Lay out against it whenever it changes.** The wallets' rectangles are there for the whole
|
|
678
|
+
session on the Arcade's phone layout, and their number and width can change as the player's
|
|
679
|
+
balances and currencies do. Read every corner, not only the ones this page names today: a layout that honours
|
|
680
|
+
all four is right under any embedder.
|
|
637
681
|
|
|
638
682
|
**Older SDKs get it folded into the top inset.** A game on an SDK from before reserved areas cannot
|
|
639
683
|
read the rectangles, so the arcade sends it none and instead raises `insets.top` — and so
|
|
640
|
-
`--gem-safe-top` — past the bottom of the
|
|
684
|
+
`--gem-safe-top` — past the bottom of the row. That game keeps working, at the cost of a full-width
|
|
641
685
|
band; upgrading gives the band back.
|
|
642
686
|
|
|
643
687
|
## Which store-page experiment brought this player in: cohorts
|
|
@@ -854,38 +898,25 @@ its music out than cut it, say. The Arcade still shows its button for your game
|
|
|
854
898
|
so this is a promise: your `onPrefs` handler must go quiet on `muted: true` and come back on `false`,
|
|
855
899
|
and the release checklist checks that it does.
|
|
856
900
|
|
|
857
|
-
## The Arcade's wallet:
|
|
901
|
+
## The Arcade's wallet: always shown, never drawn
|
|
858
902
|
|
|
859
903
|
The player's platform balances — Gems, Tickets (`ARCADE_TICKETS`) and their achievement score —
|
|
860
904
|
belong to the Arcade. **Your game never draws one**, and never shows a pending state for one: the
|
|
861
|
-
Arcade takes every figure from the platform and draws the wallets itself,
|
|
862
|
-
the top
|
|
863
|
-
|
|
864
|
-
**
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
as often as you like: before the Arcade connects the state is held and sent when it does, and
|
|
877
|
-
again after any reconnect; a repeat of the current state is not re-sent.
|
|
878
|
-
- **Shown wallets take space; a pop does not.** Shown, they widen the top-right
|
|
879
|
-
[reserved area](#the-arcades-own-controls-reserved-areas) beside the menu button, so lay your
|
|
880
|
-
screen out against `--gem-reserved-tr-*`; hidden, it shrinks back to the button alone. A pop floats
|
|
881
|
-
over your game and never moves its layout.
|
|
882
|
-
- **Narrowing is optional.** On a screen that sells in one currency — a ticket store — you may show
|
|
883
|
-
only that one: `gem.setWalletVisible(true, { only: ['ARCADE_TICKETS'] })`, with `'score'` for the
|
|
884
|
-
achievement score. Use it only there; leaving it out shows every wallet, which is always safe.
|
|
885
|
-
- **Where the Arcade docks its wallets beside your frame** — a desktop page — they are always on
|
|
886
|
-
show, and this changes nothing. Call it anyway; the same code is right everywhere.
|
|
887
|
-
- **`false` means nobody is listening** — no connection yet, or an embedder that draws no wallet.
|
|
888
|
-
Do nothing in its place.
|
|
905
|
+
Arcade takes every figure from the platform and draws the wallets itself, in the middle of the row
|
|
906
|
+
across the top of your frame on a phone, with its menu button at the right end.
|
|
907
|
+
|
|
908
|
+
**The Arcade shows every wallet the whole time, during play too** (since 2026-10-04). They are
|
|
909
|
+
small, translucent chips in the middle of the top row, and they are
|
|
910
|
+
[reserved rectangles](#the-arcades-own-controls-reserved-areas): lay every screen out below both
|
|
911
|
+
`--gem-reserved-tl-height` and `--gem-reserved-tr-height`, gameplay included. There is nothing for
|
|
912
|
+
your game to call.
|
|
913
|
+
|
|
914
|
+
⚠️ **`gem.setWalletVisible` no longer hides anything in the Arcade.** It was how a game hid the
|
|
915
|
+
wallets for gameplay and showed them on its menus, and narrowed them to one currency on a store
|
|
916
|
+
screen. The Arcade still accepts the call — it returns `true`, and existing games need no change —
|
|
917
|
+
but the wallets stay up whatever it is told. **Do not design a screen around the top row being
|
|
918
|
+
clear during play**: it is not. Another embedder may still honour the call, so leaving it in is
|
|
919
|
+
harmless; new code does not need it.
|
|
889
920
|
|
|
890
921
|
## No accidental text selection
|
|
891
922
|
|