@indiegems/gem-web-sdk 7.3.1 → 7.4.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.
Files changed (42) hide show
  1. package/README.md +54 -0
  2. package/dist/game.d.ts +156 -22
  3. package/dist/gem-web-sdk.bridge.js +1 -1
  4. package/dist/gem-web-sdk.esm.js +2 -2
  5. package/dist/gem-web-sdk.game.js +2 -2
  6. package/dist/gem-web-sdk.min.js +2 -2
  7. package/dist/gem-web-sdk.sdk.js +2 -2
  8. package/dist/gem-web-sdk.server.js +2 -2
  9. package/dist/index.d.ts +89 -6
  10. package/dist/sdk.d.ts +156 -22
  11. package/docs/achievements.md +232 -0
  12. package/docs/analytics.md +271 -0
  13. package/docs/api/api-reference-game.md +15308 -0
  14. package/docs/api/api-reference-server.md +4397 -0
  15. package/docs/api/reference.json +24130 -0
  16. package/docs/arcade-economy.md +263 -0
  17. package/docs/async-opponents.md +396 -0
  18. package/docs/brand-art.md +334 -0
  19. package/docs/cross-promotion.md +137 -0
  20. package/docs/daily-challenges.md +530 -0
  21. package/docs/dedicated-server-flow.md +879 -0
  22. package/docs/deprecation-policy.md +124 -0
  23. package/docs/friends.md +233 -0
  24. package/docs/game-economy-tutorial.md +326 -0
  25. package/docs/getting-started.md +552 -0
  26. package/docs/inventory-and-catalogs.md +1035 -0
  27. package/docs/leaderboards.md +277 -0
  28. package/docs/manifest.json +135 -0
  29. package/docs/match-session.md +288 -0
  30. package/docs/p2p-and-parties.md +783 -0
  31. package/docs/platform-rules.md +372 -0
  32. package/docs/player-sign-in.md +89 -0
  33. package/docs/room-shapes.md +195 -0
  34. package/docs/rooms-and-matches.md +779 -0
  35. package/docs/saving-player-progress.md +457 -0
  36. package/docs/server-bundles.md +1041 -0
  37. package/docs/serverless-functions.md +748 -0
  38. package/docs/trading-and-gifting.md +98 -0
  39. package/docs/what-a-game-must-do.md +1231 -0
  40. package/package.json +7 -2
  41. package/schema/bridge.v1.json +440 -7
  42. package/schema/capabilities.public.json +189 -0
@@ -0,0 +1,98 @@
1
+ # Trading and gifting
2
+
3
+ Some games let one player hand an item or some currency to another — a gift, a trade, a drop for a
4
+ teammate. This is that. If your game has no player-to-player economy, you do not need it; read
5
+ [`inventory-and-catalogs.md`](inventory-and-catalogs.md) for what a single player owns and stop
6
+ there.
7
+
8
+ A transfer moves items and currency from one entity to another in a single call. It is separate
9
+ from the rest of the inventory surface because it names **two** players, not one, and is reached
10
+ as `gem.transfers` rather than through `gem.me`.
11
+
12
+ ```js
13
+ await gem.transfers.initiate({
14
+ to: { type: 'players', id: recipientId },
15
+ items: [{ itemDefinitionId: 'iron-sword', quantity: 1 }],
16
+ currencies: [{ currencyId: 'coins', amount: 50 }],
17
+ message: 'for the boss fight',
18
+ });
19
+ ```
20
+
21
+ ## Instant is the default, and it changes how you build the UI
22
+
23
+ **By default a transfer completes immediately.** The value leaves the sender and arrives at the
24
+ recipient in the one call, with **no action required from the recipient** — no accept, no confirm,
25
+ no prompt. Build a gifting UI on the assumption that sending _is_ the transaction, not that it
26
+ opens a pending request.
27
+
28
+ `accept()` and `reject()` exist, but they are reachable **only for a transfer that resolved to
29
+ escrow** — a held transfer the recipient must claim. An instant transfer is already done and
30
+ cannot be accepted or rejected; calling either on one is an error, not a no-op. Do not write a
31
+ "the gift is waiting" flow for the default mode, because there is no waiting.
32
+
33
+ ```js
34
+ // Only for a transfer that resolved to escrow:
35
+ await gem.transfers.accept(transferId);
36
+ await gem.transfers.reject(transferId);
37
+ // The sender can pull back an unclaimed escrow transfer:
38
+ await gem.transfers.cancel(transferId);
39
+ ```
40
+
41
+ ## The recipient is not told
42
+
43
+ **A transfer produces no event in the recipient's game.** As everywhere else, there is no push
44
+ into a sandboxed frame — the arriving gift is, by definition, a change some _other_ player made,
45
+ which is precisely the kind of change your game cannot be notified of. See
46
+ [`inventory-and-catalogs.md`](inventory-and-catalogs.md#6-when-to-re-read) for the full rule; the
47
+ short version is that the recipient sees the gift the next time their game re-reads its inventory,
48
+ so re-read after any action that could have involved another player, and design so a few seconds
49
+ of not-yet-seeing-it is harmless.
50
+
51
+ ## `transfer_policy` is your game's rule, not the platform's
52
+
53
+ An item definition can carry a `transfer_policy` — soulbound, account-bound, tradeable — and the
54
+ platform honours it. But it is **your setting, declared in your config**, and it constrains an
55
+ honest client. It is not a security boundary: it stops the game you shipped from moving an item it
56
+ marked soulbound; it does not stop a modified client from attempting whatever the route allows.
57
+ Treat it as a design rule you asked the platform to enforce for you, not as protection against a
58
+ hostile client — that distinction is the same one
59
+ [`inventory-and-catalogs.md`](inventory-and-catalogs.md#14-there-is-no-client-side-integrity-boundary)
60
+ makes about the whole economy.
61
+
62
+ ## The message is another player's text
63
+
64
+ A transfer can carry a short `message`, and on the receiving side **that message is text another
65
+ player wrote.** Up to a couple hundred characters of input you did not author arrive in your UI.
66
+
67
+ It arrives as a `PlayerText`, not a `string` — the same brand a player's display name carries — so
68
+ it cannot reach `innerHTML` by accident: assigning it to `textContent` shows a placeholder naming
69
+ the fix rather than the text. Convert it at the boundary and render the plain string the way you
70
+ render any untrusted one:
71
+
72
+ ```js
73
+ import { text } from '@indiegems/gem-web-sdk/sdk'; // the package getting-started.md installs
74
+
75
+ label.textContent = text.toPlain(transfer.message); // never innerHTML, never an img.src or a.href
76
+ ```
77
+
78
+ (`text` comes from the one dependency [getting-started.md](getting-started.md#3-add-the-sdk)
79
+ adds; there is no `gem.text`.)
80
+
81
+ The platform bounds its length and does light sanitising, but the rule that keeps you safe is your
82
+ own rendering, not the platform's cleaning. This is the same population as an item's freeform
83
+ properties and a player's display name: three places outside text reaches your code.
84
+
85
+ ## Errors
86
+
87
+ | What you get | What happened | What to do |
88
+ | ---------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
89
+ | The transfer is refused with the recipient not found | No such player, or not one reachable from your game | Confirm the recipient id before sending; do not retry with the same id |
90
+ | A refusal naming the item's policy | The item is soulbound or account-bound and cannot move | This is your own `transfer_policy` doing its job; there is nothing to retry |
91
+ | `accept` / `reject` refused | The transfer is instant (already complete) or already resolved | Only escrow transfers accept these; there is nothing pending to act on |
92
+ | `cancel` refused | The escrow transfer was already claimed or already cancelled | Re-read its state; the window to pull it back has closed |
93
+ | The call times out | Unknown — it may have moved the value | Do not resend; re-read both sides' inventories and the transfer's state to see what happened |
94
+
95
+ ## What to read next
96
+
97
+ - [`inventory-and-catalogs.md`](inventory-and-catalogs.md) — currencies, items, shops and loot, for one player.
98
+ - [`game-economy-tutorial.md`](game-economy-tutorial.md) — build a shop, step by step.