@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.
- package/README.md +54 -0
- package/dist/game.d.ts +156 -22
- package/dist/gem-web-sdk.bridge.js +1 -1
- package/dist/gem-web-sdk.esm.js +2 -2
- 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 +2 -2
- package/dist/index.d.ts +89 -6
- package/dist/sdk.d.ts +156 -22
- package/docs/achievements.md +232 -0
- package/docs/analytics.md +271 -0
- package/docs/api/api-reference-game.md +15308 -0
- package/docs/api/api-reference-server.md +4397 -0
- package/docs/api/reference.json +24130 -0
- package/docs/arcade-economy.md +263 -0
- package/docs/async-opponents.md +396 -0
- package/docs/brand-art.md +334 -0
- package/docs/cross-promotion.md +137 -0
- package/docs/daily-challenges.md +530 -0
- package/docs/dedicated-server-flow.md +879 -0
- package/docs/deprecation-policy.md +124 -0
- package/docs/friends.md +233 -0
- package/docs/game-economy-tutorial.md +326 -0
- package/docs/getting-started.md +552 -0
- package/docs/inventory-and-catalogs.md +1035 -0
- package/docs/leaderboards.md +277 -0
- package/docs/manifest.json +135 -0
- package/docs/match-session.md +288 -0
- package/docs/p2p-and-parties.md +783 -0
- package/docs/platform-rules.md +372 -0
- package/docs/player-sign-in.md +89 -0
- package/docs/room-shapes.md +195 -0
- package/docs/rooms-and-matches.md +779 -0
- package/docs/saving-player-progress.md +457 -0
- package/docs/server-bundles.md +1041 -0
- package/docs/serverless-functions.md +748 -0
- package/docs/trading-and-gifting.md +98 -0
- package/docs/what-a-game-must-do.md +1231 -0
- package/package.json +7 -2
- package/schema/bridge.v1.json +440 -7
- package/schema/capabilities.public.json +189 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Gems, Tickets and Achievement Points
|
|
2
|
+
|
|
3
|
+
The arcade runs three things across every game, and a player should be able to tell them apart at
|
|
4
|
+
a glance:
|
|
5
|
+
|
|
6
|
+
> **Gems = progress. Tickets = cosmetics. Achievement Points = prestige.**
|
|
7
|
+
|
|
8
|
+
You do not have to use any of them. A game with no platform currency and no achievements is a
|
|
9
|
+
complete game, and the currencies your core loop runs on — gold, XP, energy, materials, cards — are
|
|
10
|
+
yours to design however you like ([inventory-and-catalogs.md](inventory-and-catalogs.md)). Read this
|
|
11
|
+
page before you design a reward a player carries out of your game, a price they pay with something
|
|
12
|
+
earned elsewhere, or an achievement. The rules below decide which of the three a reward can be, and
|
|
13
|
+
most of them are enforced at upload, so a design that ignores them is refused rather than shipped.
|
|
14
|
+
|
|
15
|
+
## 1. The three, side by side
|
|
16
|
+
|
|
17
|
+
| | **Gems** (`GEMS`) | **Tickets** (`ARCADE_TICKETS`) | **Achievement Points** |
|
|
18
|
+
| ------------------ | ------------------------------------------------------ | ----------------------------------------------- | --------------------------------------------------------- |
|
|
19
|
+
| What it is | the arcade's progression currency | the arcade's cosmetics currency | permanent prestige: the **Achievement Score** |
|
|
20
|
+
| Which games pay it | any game with a server or a serverless function | any game with a server or a serverless function | an achievement, from any game with a server or a function |
|
|
21
|
+
| What it buys | anything a game prices in it | cosmetic items only | nothing — it is never spent |
|
|
22
|
+
| Sold for money | never | never | never |
|
|
23
|
+
| A Boost raises it | yes — the grants and the caps | yes — the grants and the caps | never |
|
|
24
|
+
|
|
25
|
+
A player earns Gems across the arcade's games and spends them on progress anywhere: upgrades, unlocks,
|
|
26
|
+
extra attempts, resources, characters, cards. A player earns Tickets by playing almost anything and
|
|
27
|
+
spends them on how they look: skins, outfits, visual effects, decorations, emotes, profile
|
|
28
|
+
cosmetics. Achievement points are what a player has done, summed across every game into the
|
|
29
|
+
Achievement Score; they are never bought, boosted or spent, and nothing takes them away except the
|
|
30
|
+
platform, for fraud or moderation.
|
|
31
|
+
|
|
32
|
+
## 2. What your game keeps for itself
|
|
33
|
+
|
|
34
|
+
The arcade does not replace your economy. The currencies and resources your core loop runs on —
|
|
35
|
+
gold, XP, wood, energy, lives, cards — stay your game's own: defined in your game config, minted and
|
|
36
|
+
priced by you, invisible to every other game. Nothing on this page applies to them.
|
|
37
|
+
|
|
38
|
+
What you map onto the three is the layer above that loop — the part that would otherwise become a
|
|
39
|
+
platform-wide currency of your own:
|
|
40
|
+
|
|
41
|
+
| If your design has… | Use |
|
|
42
|
+
| ----------------------------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
43
|
+
| a premium or meta currency that speeds up or unlocks progress | **Gems**: price that progress in `GEMS` |
|
|
44
|
+
| a cosmetics currency, or a shop of skins | **Tickets**: price the cosmetics in `ARCADE_TICKETS` |
|
|
45
|
+
| a trophy count, a mastery rank or a completion percentage that says "this player is good" | **achievements**, whose points join the Achievement Score |
|
|
46
|
+
|
|
47
|
+
⚠️ **Do not build a second Gems or a second Tickets.** A game-local premium or cosmetic
|
|
48
|
+
meta-currency — "Crystals" that buy your upgrades, "Shards" that buy your skins, earned and hoarded
|
|
49
|
+
the way a player would earn and hoard the arcade's — competes with the arcade's own, splits the
|
|
50
|
+
player between two wallets that mean the same thing, and sidesteps every rule on this page: the Gem
|
|
51
|
+
Source approval, the cosmetics-only line and the platform's caps. The release review checks for one.
|
|
52
|
+
A currency that is part of play is fine: coins picked up in a level and spent in that run's shop,
|
|
53
|
+
energy that paces a session, materials a crafting tree consumes.
|
|
54
|
+
|
|
55
|
+
## 3. Which kind of game is yours
|
|
56
|
+
|
|
57
|
+
There are four shapes:
|
|
58
|
+
|
|
59
|
+
| Shape | Grants Gems | Prices in Gems | For example |
|
|
60
|
+
| -------------- | ----------- | -------------- | --------------------------------------------------------------------------------------- |
|
|
61
|
+
| **Gem Source** | yes | no | a game with a controlled daily activity that feeds progress to the arcade |
|
|
62
|
+
| **Balanced** | yes | yes | a Gem Source whose own progression also spends Gems |
|
|
63
|
+
| **Gem Sink** | no | yes | a progression-heavy game: upgrades, characters, cards bought with Gems earned elsewhere |
|
|
64
|
+
| **No-Gem** | no | no | a game that stays out of Gems entirely |
|
|
65
|
+
|
|
66
|
+
The shapes describe what a game does, not what it may do: a Gem Source that starts pricing its own
|
|
67
|
+
progress in Gems is Balanced. Every shape may pay Tickets, price its cosmetics in Tickets and carry
|
|
68
|
+
achievements. **Gems can be your game's soft currency** — award them for play and price your
|
|
69
|
+
progression in them.
|
|
70
|
+
|
|
71
|
+
Which platform currencies **your** game may grant or price is the platform's answer, and it can
|
|
72
|
+
change: `gemctl platform config --game <id>` lists them under `platform_grants` and
|
|
73
|
+
`platform_prices`, each with a note on what the arcade wants it used for. A mapping onto a currency
|
|
74
|
+
the platform will not let your game pay is refused at upload, and the refusal names the ones it
|
|
75
|
+
will.
|
|
76
|
+
|
|
77
|
+
## 4. Earning needs server authority
|
|
78
|
+
|
|
79
|
+
A platform currency or an achievement is paid only on the say-so of code a player cannot modify.
|
|
80
|
+
Your game never grants one directly. A progression in your game config carries a `platform_grants`
|
|
81
|
+
mapping, and when that progression moves, the platform pays under its own authority
|
|
82
|
+
([inventory-and-catalogs.md](inventory-and-catalogs.md#platform-grants-awarding-a-platform-wide-currency)).
|
|
83
|
+
What may move it:
|
|
84
|
+
|
|
85
|
+
- **Your game server** — a platform-allocated dedicated server, through the progression add and max
|
|
86
|
+
routes.
|
|
87
|
+
- **Your serverless function**, called by the player it pays, on a progression that sets
|
|
88
|
+
`function_may_grant: true`. It may pay Gems and Tickets and unlock achievements for **that player
|
|
89
|
+
only**, and never for a guest. A function a player calls may also change only that player's own
|
|
90
|
+
state — any write it aims at another player is refused. Opting in makes the function's own checks
|
|
91
|
+
the only thing deciding a reward was earned, so read
|
|
92
|
+
[serverless-functions.md](serverless-functions.md) before you set it.
|
|
93
|
+
- **Never the browser.** A mapped progression cannot be `client_writable`, and nothing else in your
|
|
94
|
+
config — a recipe, a loot-table entry, another progression's reward — may write it.
|
|
95
|
+
|
|
96
|
+
So a browser-only game with neither a server nor a function pays nothing platform-wide. That is the
|
|
97
|
+
rule read strictly, not a gap: a browser credential is public, and anything it could pay, a modified
|
|
98
|
+
client could pay itself.
|
|
99
|
+
|
|
100
|
+
**Achievements hold the same line, harder.** An achievement that awards points may not sit on a
|
|
101
|
+
progression anything in your config writes: a recipe priced in Gems that adds to it would sell the
|
|
102
|
+
achievement. Points are never bought, boosted, spent, decayed or expired, and the platform removes
|
|
103
|
+
them only for fraud or moderation ([achievements.md](achievements.md)).
|
|
104
|
+
|
|
105
|
+
## 5. Spending: price each item in the currency it deserves
|
|
106
|
+
|
|
107
|
+
Any game may sell an item or a recipe for a platform currency, with no server and no approval: the
|
|
108
|
+
item or recipe carries `platform_prices`, and the player pays through the arcade's purchase sheet or
|
|
109
|
+
your own purchase screen
|
|
110
|
+
([inventory-and-catalogs.md](inventory-and-catalogs.md#16-selling-for-a-platform-currency)). What a
|
|
111
|
+
currency may price is a platform setting on that currency, its **spend scope**:
|
|
112
|
+
|
|
113
|
+
- **Gems — `any`.** Price progress in `GEMS`: an extra life, an upgrade, a character, a pack of
|
|
114
|
+
cards, another attempt.
|
|
115
|
+
- **Tickets — `cosmetic_only`.** A Tickets price is accepted only on an item your config declares
|
|
116
|
+
`category: cosmetic`, or on a recipe that grants cosmetic items and nothing else. A Tickets price
|
|
117
|
+
on anything that grants a currency, moves a progression, grants a non-cosmetic item, opens into
|
|
118
|
+
other items (a bundle or a loot box) or rolls a loot table is refused at upload — a loot table
|
|
119
|
+
even when every entry in it is cosmetic.
|
|
120
|
+
|
|
121
|
+
So a Tickets price on an item is always the pair `currency: ARCADE_TICKETS` and
|
|
122
|
+
`category: cosmetic`; on a recipe, every item it grants declares `category: cosmetic`.
|
|
123
|
+
|
|
124
|
+
**`category` defaults to `progression`**, so an item is a cosmetic only because you said so. The
|
|
125
|
+
platform takes that at your word and the release review checks it: an item that changes what a
|
|
126
|
+
player can do, labelled `cosmetic` so it can sell for Tickets, breaks platform policy.
|
|
127
|
+
|
|
128
|
+
**A cosmetic can still wait for progress.** "Reach level 10 to unlock the dragon skin" is a recipe
|
|
129
|
+
with a prerequisite and a Tickets price, and the platform refuses a locked player with
|
|
130
|
+
`recipe_locked` before it takes anything ([game-economy-tutorial.md](game-economy-tutorial.md)).
|
|
131
|
+
|
|
132
|
+
**Take the scope from the refusal, not from this page.** The platform owns each currency's scope and
|
|
133
|
+
can change it. A refusal names the scope that applied, and `gemctl platform config` lists which
|
|
134
|
+
currencies your game may price in at all. A scope changed after you published stops the prices it
|
|
135
|
+
no longer admits: the purchase is refused and the price leaves the catalog, with nothing charged.
|
|
136
|
+
|
|
137
|
+
**The arcade sells cosmetics of its own for Tickets, and never sells prestige.** Besides your game's
|
|
138
|
+
shop, the arcade has a Tickets shop of its own profile cosmetics. Every arcade item is either a
|
|
139
|
+
**shop** item — a cosmetic priced in Tickets — or **earned**: a default, a free claim, an achievement
|
|
140
|
+
or Achievement Score reward. An earned item can never be given a price, in Tickets, Gems or anything
|
|
141
|
+
else, so what a player shows off for what they did cannot be bought.
|
|
142
|
+
|
|
143
|
+
## 6. Every number is the platform's, and it moves
|
|
144
|
+
|
|
145
|
+
Each platform currency carries settings the arcade holds per currency and can change at any time,
|
|
146
|
+
without a release of this SDK or of your game:
|
|
147
|
+
|
|
148
|
+
- which games may grant it;
|
|
149
|
+
- how much one grant may pay, how much one game may pay one player per window, and how much all
|
|
150
|
+
games together may pay one player per day — the **daily maximum**;
|
|
151
|
+
- the most a player may hold — the **holdings cap**;
|
|
152
|
+
- whether games may price in it, and what it may price;
|
|
153
|
+
- whether a Boost raises it;
|
|
154
|
+
- whether the arcade shows it in its header and wallet.
|
|
155
|
+
|
|
156
|
+
**Author against `gemctl platform config`, never against a number you remember.** For your game it
|
|
157
|
+
lists every currency a `platform_grants` mapping may target, with its current ceilings, every
|
|
158
|
+
currency a price may name, and a note on when to reach for each. A currency it does not list for a
|
|
159
|
+
site cannot be used there.
|
|
160
|
+
|
|
161
|
+
Your game declares no cap of its own. You choose only what each firing pays; the ceilings bound it,
|
|
162
|
+
and the order's `platform_grant` entry — `fired`, `clamped` or `suppressed` — is the receipt for what
|
|
163
|
+
landed:
|
|
164
|
+
|
|
165
|
+
- **A ceiling trims; it does not refuse.** For every platform currency, a firing that would cross
|
|
166
|
+
the per-firing cap, the per-game cap or the daily maximum pays what is left of it and reads
|
|
167
|
+
`clamped`; once the day is spent it pays 0. When the player reaches the daily maximum, the arcade
|
|
168
|
+
tells them in its own chrome, and that notice is never relayed into your game
|
|
169
|
+
([daily-challenges.md](daily-challenges.md)), though it can read how much more it may pay
|
|
170
|
+
([the earn allowance](inventory-and-catalogs.md#showing-how-much-more-a-player-can-earn)).
|
|
171
|
+
- **The holdings cap is all or nothing.** A grant that would take the player's balance past it pays
|
|
172
|
+
nothing and reads `clamped` with `clamped_by: holdings_cap`. Nothing a player already holds is
|
|
173
|
+
ever taken away.
|
|
174
|
+
|
|
175
|
+
Your reward screen may say what the mapping pays; the receipt, never your screen, says what the
|
|
176
|
+
player got.
|
|
177
|
+
|
|
178
|
+
## 7. Boosts: the one thing a player buys with money
|
|
179
|
+
|
|
180
|
+
Nothing in the arcade sells Gems or Tickets, alone or in a bundle, and nothing sells achievement
|
|
181
|
+
points. The one real-money product is a **Boost**, which a player buys from the arcade, never from
|
|
182
|
+
your game:
|
|
183
|
+
|
|
184
|
+
- **It multiplies what Gems and Tickets grants pay, and the ceilings with them.** A player on a 2×
|
|
185
|
+
Boost earns twice as much per grant, may earn twice as much per window and per day, and may hold
|
|
186
|
+
more. When it ends, what they earned stays theirs.
|
|
187
|
+
- **It never touches achievement points.** An unlock credits the same points for every player.
|
|
188
|
+
- **Your game does nothing to apply it.** The platform multiplies your mapping's payout itself.
|
|
189
|
+
Keep `amount` at the unboosted figure; the receipt reports what landed.
|
|
190
|
+
- **None is on sale yet.** The first Boost, `booster_x2_30d`, is inactive until the arcade launches
|
|
191
|
+
it, so today every player earns at the unboosted rate. Design for both.
|
|
192
|
+
|
|
193
|
+
⚠️ **Show a Boost; never gate on one.** Your game may tell a player they are boosted — "2× Tickets"
|
|
194
|
+
beside a reward, from `gem.player.boost`
|
|
195
|
+
([what-a-game-must-do.md](what-a-game-must-do.md#the-signed-in-players-boost-show-it-never-gate-on-it))
|
|
196
|
+
— and must never make content, difficulty, power, access, prices, matchmaking or odds depend on
|
|
197
|
+
whether they are. A Boost buys a faster stream of the arcade's currencies and nothing else. A level,
|
|
198
|
+
a character or an advantage behind it is paying to win, and the release review refuses it: the full
|
|
199
|
+
rule is [platform-rules.md](platform-rules.md#8-a-players-boost-is-for-display-never-a-gate).
|
|
200
|
+
|
|
201
|
+
## 8. The arcade owns the display of every platform currency
|
|
202
|
+
|
|
203
|
+
The arcade draws the player's platform currencies in its own chrome while your game runs, and
|
|
204
|
+
animates every payout into the right total. Gems and Tickets follow the same rules:
|
|
205
|
+
|
|
206
|
+
- **No counter.** Keep no balance, running total or wallet of a platform currency on any screen of
|
|
207
|
+
yours. Read `gem.platform.currencies.get()` to decide whether a price is affordable, never to draw
|
|
208
|
+
a number.
|
|
209
|
+
- **No celebration of your own.** At a payout, cue the arcade's wallet with `gem.cueReward`, naming
|
|
210
|
+
the currency that paid — `currencySlug: 'GEMS'` from the gem on your reward screen,
|
|
211
|
+
`'ARCADE_TICKETS'` from the ticket. If it returns `false`, do nothing
|
|
212
|
+
([inventory-and-catalogs.md](inventory-and-catalogs.md#showing-the-reward-land-in-the-arcades-wallet)).
|
|
213
|
+
- **No "daily max" of your own making.** Your game cannot see what every other game paid the player,
|
|
214
|
+
and must not compute a maximum. To show how much more your game can pay, read
|
|
215
|
+
`gem.platform.earnAllowance.get()` (one consolidated figure, display only); the arcade still tells
|
|
216
|
+
the player when they reach the maximum.
|
|
217
|
+
- **No top-up or payment screen of your own.** Never draw a "get more Gems" or "buy Tickets" offer,
|
|
218
|
+
a checkout, a wallet top-up, or anything shaped like the arcade's purchase sheet: a game screen
|
|
219
|
+
that looks like platform payment chrome is an imitation of it, and players cannot tell the two
|
|
220
|
+
apart. Your shop's own Buy button is yours. When a purchase is refused for
|
|
221
|
+
`insufficient_funds`, say so in your shop's own words ("Not enough Tickets") and stop there.
|
|
222
|
+
- **No amount at all when you are not connected to the arcade.** Hide every platform price and
|
|
223
|
+
reward unless `gem.awaitBridge()` settled `connected`.
|
|
224
|
+
- **Draw a currency with the art the SDK ships**: the icon beside an amount, the hero only on a
|
|
225
|
+
reward presentation ([brand-art.md](brand-art.md)).
|
|
226
|
+
|
|
227
|
+
**The Achievement Score is the arcade's to total, too.** Your game shows its own achievements and
|
|
228
|
+
never computes the score, restates it, or turns it into a currency of its own.
|
|
229
|
+
|
|
230
|
+
## 9. What the arcade does not have
|
|
231
|
+
|
|
232
|
+
- **No Stars, Coins, Tokens or Supporter Seals.** All four are retired. None of them can be
|
|
233
|
+
granted, priced in or bought: a config naming one is refused at upload, and a mapping onto one
|
|
234
|
+
that is still live reads `suppressed`. The Achievement Score is the arcade's measure of prestige.
|
|
235
|
+
- **No Gems or Tickets for money**, alone or in a bundle, and no achievement points or earned
|
|
236
|
+
items for anything a player pays for.
|
|
237
|
+
- **No content behind a Boost.** A Boost is shown, never checked.
|
|
238
|
+
|
|
239
|
+
## 10. When an upload or a grant is refused
|
|
240
|
+
|
|
241
|
+
| What you get | What happened | What to do |
|
|
242
|
+
| ---------------------------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
243
|
+
| a mapping refused, naming the currencies your game may pay | the platform does not let your game grant that currency | target one it lists — `gemctl platform config` has the current set |
|
|
244
|
+
| a receipt `suppressed`, reason `not_allowlisted…` | the platform stopped letting your game grant that currency | target a currency `gemctl platform config` lists; paid balances stay |
|
|
245
|
+
| a price refused, naming the spend scope `cosmetic_only` | a Tickets price on something that is not a cosmetic | price it in `GEMS`, or mark the item `category: cosmetic` if it changes only looks |
|
|
246
|
+
| a receipt `suppressed`, reason `functions_not_opted_in` | your function wrote a paying progression that has not opted in | read [serverless-functions.md](serverless-functions.md), then set `function_may_grant: true` |
|
|
247
|
+
| a receipt `suppressed`, reason `function_gems_not_enabled` | an older receipt, from before functions could pay Gems | nothing — a function pays Gems now, so its next firing pays |
|
|
248
|
+
| `403 function_foreign_entity_write` | a function a player called wrote another player | take the player from the call's context, never its input |
|
|
249
|
+
| a receipt `clamped` | a ceiling trimmed the payout, or the day was already spent | nothing — show what landed; `gemctl platform config` has the ceilings |
|
|
250
|
+
| a receipt `clamped`, `clamped_by: holdings_cap` | the player already holds as much as they may | nothing — the player spends before they earn more |
|
|
251
|
+
|
|
252
|
+
## What to read next
|
|
253
|
+
|
|
254
|
+
- [`inventory-and-catalogs.md`](inventory-and-catalogs.md) — platform grants (§13) and selling for a
|
|
255
|
+
platform currency (§16), in full.
|
|
256
|
+
- [`game-economy-tutorial.md`](game-economy-tutorial.md) — a shop, step by step, including a
|
|
257
|
+
cosmetic sold for Tickets.
|
|
258
|
+
- [`daily-challenges.md`](daily-challenges.md) — the commonest thing that pays a platform currency.
|
|
259
|
+
- [`achievements.md`](achievements.md) — achievements, their points and the Achievement Score.
|
|
260
|
+
- [`serverless-functions.md`](serverless-functions.md) — paying a player from a game with no
|
|
261
|
+
dedicated server, and what a function a player calls may change.
|
|
262
|
+
- [`platform-rules.md`](platform-rules.md) — the Boost rule, among the rest.
|
|
263
|
+
- [`brand-art.md`](brand-art.md) — the art for every platform currency, and the rules for drawing it.
|