@crowdedkingdoms/crowdyjs 8.2.0 → 8.3.0
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 +21 -3
- package/dist/crowdy-client.d.ts.map +1 -1
- package/dist/crowdy-client.js +5 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/kit/blueprints/combat.d.ts +75 -0
- package/dist/kit/blueprints/combat.d.ts.map +1 -0
- package/dist/kit/blueprints/combat.js +351 -0
- package/dist/kit/blueprints/core.d.ts +222 -0
- package/dist/kit/blueprints/core.d.ts.map +1 -0
- package/dist/kit/blueprints/core.js +185 -0
- package/dist/kit/blueprints/decks.d.ts +50 -0
- package/dist/kit/blueprints/decks.d.ts.map +1 -0
- package/dist/kit/blueprints/decks.js +163 -0
- package/dist/kit/blueprints/economy.d.ts +88 -0
- package/dist/kit/blueprints/economy.d.ts.map +1 -0
- package/dist/kit/blueprints/economy.js +533 -0
- package/dist/kit/blueprints/guild.d.ts +51 -0
- package/dist/kit/blueprints/guild.d.ts.map +1 -0
- package/dist/kit/blueprints/guild.js +50 -0
- package/dist/kit/blueprints/index.d.ts +21 -0
- package/dist/kit/blueprints/index.d.ts.map +1 -0
- package/dist/kit/blueprints/index.js +20 -0
- package/dist/kit/blueprints/inventory.d.ts +38 -0
- package/dist/kit/blueprints/inventory.d.ts.map +1 -0
- package/dist/kit/blueprints/inventory.js +157 -0
- package/dist/kit/blueprints/leaderboards.d.ts +49 -0
- package/dist/kit/blueprints/leaderboards.d.ts.map +1 -0
- package/dist/kit/blueprints/leaderboards.js +126 -0
- package/dist/kit/blueprints/locks.d.ts +82 -0
- package/dist/kit/blueprints/locks.d.ts.map +1 -0
- package/dist/kit/blueprints/locks.js +155 -0
- package/dist/kit/blueprints/loot.d.ts +84 -0
- package/dist/kit/blueprints/loot.d.ts.map +1 -0
- package/dist/kit/blueprints/loot.js +228 -0
- package/dist/kit/blueprints/matches.d.ts +59 -0
- package/dist/kit/blueprints/matches.d.ts.map +1 -0
- package/dist/kit/blueprints/matches.js +246 -0
- package/dist/kit/blueprints/npcs.d.ts +71 -0
- package/dist/kit/blueprints/npcs.d.ts.map +1 -0
- package/dist/kit/blueprints/npcs.js +122 -0
- package/dist/kit/blueprints/plots.d.ts +54 -0
- package/dist/kit/blueprints/plots.d.ts.map +1 -0
- package/dist/kit/blueprints/plots.js +146 -0
- package/dist/kit/blueprints/progression.d.ts +68 -0
- package/dist/kit/blueprints/progression.d.ts.map +1 -0
- package/dist/kit/blueprints/progression.js +324 -0
- package/dist/kit/blueprints/quests.d.ts +65 -0
- package/dist/kit/blueprints/quests.d.ts.map +1 -0
- package/dist/kit/blueprints/quests.js +284 -0
- package/dist/kit/blueprints/worldsim.d.ts +84 -0
- package/dist/kit/blueprints/worldsim.d.ts.map +1 -0
- package/dist/kit/blueprints/worldsim.js +461 -0
- package/dist/kit/combat.d.ts +103 -0
- package/dist/kit/combat.d.ts.map +1 -0
- package/dist/kit/combat.js +151 -0
- package/dist/kit/decks.d.ts +123 -0
- package/dist/kit/decks.d.ts.map +1 -0
- package/dist/kit/decks.js +138 -0
- package/dist/kit/economy.d.ts +244 -0
- package/dist/kit/economy.d.ts.map +1 -0
- package/dist/kit/economy.js +365 -0
- package/dist/kit/features.d.ts +60 -0
- package/dist/kit/features.d.ts.map +1 -0
- package/dist/kit/features.js +65 -0
- package/dist/kit/index.d.ts +13 -2
- package/dist/kit/index.d.ts.map +1 -1
- package/dist/kit/index.js +12 -1
- package/dist/kit/inventory.d.ts +5 -0
- package/dist/kit/inventory.d.ts.map +1 -1
- package/dist/kit/inventory.js +14 -1
- package/dist/kit/kit.d.ts +58 -2
- package/dist/kit/kit.d.ts.map +1 -1
- package/dist/kit/kit.js +24 -2
- package/dist/kit/leaderboards.d.ts +66 -0
- package/dist/kit/leaderboards.d.ts.map +1 -0
- package/dist/kit/leaderboards.js +94 -0
- package/dist/kit/loot.d.ts +106 -0
- package/dist/kit/loot.d.ts.map +1 -0
- package/dist/kit/loot.js +120 -0
- package/dist/kit/matches.d.ts +140 -0
- package/dist/kit/matches.d.ts.map +1 -0
- package/dist/kit/matches.js +253 -0
- package/dist/kit/objects.js +1 -1
- package/dist/kit/plots.js +1 -1
- package/dist/kit/progression.d.ts +181 -0
- package/dist/kit/progression.d.ts.map +1 -0
- package/dist/kit/progression.js +265 -0
- package/dist/kit/quests.d.ts +110 -0
- package/dist/kit/quests.d.ts.map +1 -0
- package/dist/kit/quests.js +158 -0
- package/dist/kit/social.d.ts +267 -0
- package/dist/kit/social.d.ts.map +1 -0
- package/dist/kit/social.js +230 -0
- package/dist/kit/worldsim.d.ts +225 -0
- package/dist/kit/worldsim.d.ts.map +1 -0
- package/dist/kit/worldsim.js +231 -0
- package/package.json +1 -1
- package/dist/kit/blueprints.d.ts +0 -370
- package/dist/kit/blueprints.d.ts.map +0 -1
- package/dist/kit/blueprints.js +0 -643
package/dist/kit/kit.d.ts
CHANGED
|
@@ -1,17 +1,51 @@
|
|
|
1
|
+
import type { ChannelsAPI } from '../domains/channels.js';
|
|
1
2
|
import type { GameAppsAPI } from '../domains/gameApps.js';
|
|
2
3
|
import type { GameModelAPI } from '../domains/gameModel.js';
|
|
4
|
+
import type { TeamsAPI } from '../domains/teams.js';
|
|
5
|
+
import type { UdpAPI } from '../domains/udp.js';
|
|
3
6
|
import type { GameModelSeedMutation, GameModelUpsertAutomationMutation, GameModelUpsertAutomationTriggerMutation, Scalars } from '../generated/graphql.js';
|
|
4
|
-
import { type KitBlueprint } from './blueprints.js';
|
|
7
|
+
import { type KitBlueprint } from './blueprints/index.js';
|
|
8
|
+
import { CombatKit, type CombatKitOptions } from './combat.js';
|
|
9
|
+
import { DecksKit, type DecksKitOptions } from './decks.js';
|
|
10
|
+
import { EconomyKit, type EconomyKitOptions } from './economy.js';
|
|
11
|
+
import { FeaturesKit } from './features.js';
|
|
5
12
|
import { InventoryKit, type InventoryKitOptions } from './inventory.js';
|
|
13
|
+
import { LeaderboardsKit, type LeaderboardsKitOptions } from './leaderboards.js';
|
|
14
|
+
import { LootKit, type LootKitOptions } from './loot.js';
|
|
6
15
|
import { NpcsKit, type NpcsKitOptions } from './npcs.js';
|
|
7
16
|
import { ObjectsKit, type ObjectsKitOptions } from './objects.js';
|
|
8
17
|
import { PlotsKit, type PlotsKitOptions } from './plots.js';
|
|
18
|
+
import { MatchesKit, type MatchesKitOptions } from './matches.js';
|
|
19
|
+
import { ProgressionKit, type ProgressionKitOptions } from './progression.js';
|
|
20
|
+
import { QuestsKit, type QuestsKitOptions } from './quests.js';
|
|
21
|
+
import { SocialKit, type SocialKitOptions } from './social.js';
|
|
22
|
+
import { WorldsimKit, type WorldsimKitOptions } from './worldsim.js';
|
|
9
23
|
/** Options for {@link GameKitClient}, configuring the runtime helpers to match your deployed blueprints. */
|
|
10
24
|
export interface GameKitOptions {
|
|
11
25
|
inventory?: InventoryKitOptions;
|
|
12
26
|
objects?: ObjectsKitOptions;
|
|
13
27
|
npcs?: NpcsKitOptions;
|
|
14
28
|
plots?: PlotsKitOptions;
|
|
29
|
+
economy?: EconomyKitOptions;
|
|
30
|
+
progression?: ProgressionKitOptions;
|
|
31
|
+
loot?: LootKitOptions;
|
|
32
|
+
quests?: QuestsKitOptions;
|
|
33
|
+
combat?: CombatKitOptions;
|
|
34
|
+
matches?: MatchesKitOptions;
|
|
35
|
+
decks?: DecksKitOptions;
|
|
36
|
+
worldsim?: WorldsimKitOptions;
|
|
37
|
+
social?: SocialKitOptions;
|
|
38
|
+
leaderboards?: LeaderboardsKitOptions;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The extra (non-model) domains some kit helpers compose: channels + udp for
|
|
42
|
+
* matches (notify-to-pull) and social chat, teams for parties/guilds.
|
|
43
|
+
* `client.kit(appId)` wires them automatically.
|
|
44
|
+
*/
|
|
45
|
+
export interface GameKitDomains {
|
|
46
|
+
channels?: ChannelsAPI;
|
|
47
|
+
teams?: TeamsAPI;
|
|
48
|
+
udp?: UdpAPI;
|
|
15
49
|
}
|
|
16
50
|
/** The result of {@link GameKitClient.deploy}: the seed outcome plus each automation/trigger upserted. */
|
|
17
51
|
export interface KitDeployResult {
|
|
@@ -70,7 +104,29 @@ export declare class GameKitClient {
|
|
|
70
104
|
readonly npcs: NpcsKit;
|
|
71
105
|
/** Plot helpers (buy/rent land with transactional, enforced grid grants). */
|
|
72
106
|
readonly plots: PlotsKit;
|
|
73
|
-
|
|
107
|
+
/** Economy helpers (wallets, shops, escrow trades, player market). */
|
|
108
|
+
readonly economy: EconomyKit;
|
|
109
|
+
/** Progression helpers (xp/levels, skills, achievements, rating). */
|
|
110
|
+
readonly progression: ProgressionKit;
|
|
111
|
+
/** Loot helpers (server-rolled weighted tables, atomic claims). */
|
|
112
|
+
readonly loot: LootKit;
|
|
113
|
+
/** Quest helpers (catalog, progress, atomic reward turn-in, daily resets). */
|
|
114
|
+
readonly quests: QuestsKit;
|
|
115
|
+
/** Combat helpers (server-authoritative attacks, status effects, respawn). */
|
|
116
|
+
readonly combat: CombatKit;
|
|
117
|
+
/** Match helpers (lobbies, rounds, turns, scores, notify-to-pull channels). */
|
|
118
|
+
readonly matches: MatchesKit;
|
|
119
|
+
/** Deck helpers (hidden hands via owner visibility, server-dealt shuffles). */
|
|
120
|
+
readonly decks: DecksKit;
|
|
121
|
+
/** World simulation helpers (clock/weather, nodes, crops, wave counters). */
|
|
122
|
+
readonly worldsim: WorldsimKit;
|
|
123
|
+
/** Social helpers (parties, guilds, chat over teams + channels). */
|
|
124
|
+
readonly social: SocialKit;
|
|
125
|
+
/** Leaderboard helpers (trusted submits, client-side ranking, seasons). */
|
|
126
|
+
readonly leaderboards: LeaderboardsKit;
|
|
127
|
+
/** Monetization helpers (feature keys, tier grants, featureGate policies). */
|
|
128
|
+
readonly features: FeaturesKit;
|
|
129
|
+
constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, gameApps: GameAppsAPI, options?: GameKitOptions, domains?: GameKitDomains);
|
|
74
130
|
/**
|
|
75
131
|
* Helpers for an additional lockable object type deployed under a different
|
|
76
132
|
* type name (e.g. both `Door` and `Chest` lock blueprints in one app).
|
package/dist/kit/kit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kit.d.ts","sourceRoot":"","sources":["../../src/kit/kit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EACV,qBAAqB,EACrB,iCAAiC,EACjC,wCAAwC,EACxC,OAAO,EACR,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"kit.d.ts","sourceRoot":"","sources":["../../src/kit/kit.ts"],"names":[],"mappings":"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"}
|
package/dist/kit/kit.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import { mergeBlueprints } from './blueprints.js';
|
|
1
|
+
import { mergeBlueprints } from './blueprints/index.js';
|
|
2
|
+
import { CombatKit } from './combat.js';
|
|
3
|
+
import { DecksKit } from './decks.js';
|
|
4
|
+
import { EconomyKit } from './economy.js';
|
|
5
|
+
import { FeaturesKit } from './features.js';
|
|
2
6
|
import { InventoryKit } from './inventory.js';
|
|
7
|
+
import { LeaderboardsKit } from './leaderboards.js';
|
|
8
|
+
import { LootKit } from './loot.js';
|
|
3
9
|
import { NpcsKit } from './npcs.js';
|
|
4
10
|
import { ObjectsKit } from './objects.js';
|
|
5
11
|
import { PlotsKit } from './plots.js';
|
|
12
|
+
import { MatchesKit } from './matches.js';
|
|
13
|
+
import { ProgressionKit } from './progression.js';
|
|
14
|
+
import { QuestsKit } from './quests.js';
|
|
15
|
+
import { SocialKit } from './social.js';
|
|
16
|
+
import { WorldsimKit } from './worldsim.js';
|
|
6
17
|
/**
|
|
7
18
|
* App-scoped **Game Kit** facade returned by `client.kit(appId)` — high-level
|
|
8
19
|
* building blocks that map traditional game concepts (inventory, lockable
|
|
@@ -42,13 +53,24 @@ import { PlotsKit } from './plots.js';
|
|
|
42
53
|
* ```
|
|
43
54
|
*/
|
|
44
55
|
export class GameKitClient {
|
|
45
|
-
constructor(appId, gameModel, gameApps, options = {}) {
|
|
56
|
+
constructor(appId, gameModel, gameApps, options = {}, domains = {}) {
|
|
46
57
|
this.appId = appId;
|
|
47
58
|
this.gameModel = gameModel;
|
|
48
59
|
this.inventory = new InventoryKit(appId, gameModel, options.inventory);
|
|
49
60
|
this.objects = new ObjectsKit(appId, gameModel, options.objects);
|
|
50
61
|
this.npcs = new NpcsKit(appId, gameModel, options.npcs);
|
|
51
62
|
this.plots = new PlotsKit(appId, gameModel, gameApps, options.plots);
|
|
63
|
+
this.economy = new EconomyKit(appId, gameModel, options.economy);
|
|
64
|
+
this.progression = new ProgressionKit(appId, gameModel, options.progression);
|
|
65
|
+
this.loot = new LootKit(appId, gameModel, options.loot);
|
|
66
|
+
this.quests = new QuestsKit(appId, gameModel, options.quests);
|
|
67
|
+
this.combat = new CombatKit(appId, gameModel, options.combat);
|
|
68
|
+
this.matches = new MatchesKit(appId, gameModel, domains.channels, domains.udp, options.matches);
|
|
69
|
+
this.decks = new DecksKit(appId, gameModel, options.decks);
|
|
70
|
+
this.worldsim = new WorldsimKit(appId, gameModel, options.worldsim);
|
|
71
|
+
this.social = new SocialKit(appId, domains.teams, domains.channels, domains.udp, gameApps, options.social);
|
|
72
|
+
this.leaderboards = new LeaderboardsKit(appId, gameModel, options.leaderboards);
|
|
73
|
+
this.features = new FeaturesKit(appId, gameModel);
|
|
52
74
|
}
|
|
53
75
|
/**
|
|
54
76
|
* Helpers for an additional lockable object type deployed under a different
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { GameModelAPI } from '../domains/gameModel.js';
|
|
2
|
+
import type { Scalars } from '../generated/graphql.js';
|
|
3
|
+
import { type KitInvokeResult } from './shared.js';
|
|
4
|
+
/** Options for {@link LeaderboardsKit}. Must match the deployed blueprint. */
|
|
5
|
+
export interface LeaderboardsKitOptions {
|
|
6
|
+
/** The `typePrefix` the leaderboards blueprint was deployed with. */
|
|
7
|
+
typePrefix?: string;
|
|
8
|
+
}
|
|
9
|
+
/** A parsed view of one leaderboard entry. */
|
|
10
|
+
export interface KitLeaderboardEntry {
|
|
11
|
+
containerId: string;
|
|
12
|
+
displayName: string;
|
|
13
|
+
ownerUserId: string | null;
|
|
14
|
+
boardId: string;
|
|
15
|
+
score: number;
|
|
16
|
+
season: number;
|
|
17
|
+
/** 1-based position AFTER client-side sorting (not the stamped `rank` property). */
|
|
18
|
+
position: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Runtime helpers for the {@link leaderboardsBlueprint} conventions: ensure
|
|
22
|
+
* per-player entries, submit scores (trusted — host by default), and rank.
|
|
23
|
+
* There is no server-side ORDER BY on container lists, so reads fetch a
|
|
24
|
+
* board's entries and sort client-side — fine for the few hundred entries a
|
|
25
|
+
* per-app board holds.
|
|
26
|
+
*
|
|
27
|
+
* Obtained via `client.kit(appId).leaderboards`.
|
|
28
|
+
*/
|
|
29
|
+
export declare class LeaderboardsKit {
|
|
30
|
+
private readonly appId;
|
|
31
|
+
private readonly gameModel;
|
|
32
|
+
private readonly names;
|
|
33
|
+
constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, options?: LeaderboardsKitOptions);
|
|
34
|
+
/** Find-or-create a player's entry on a board. */
|
|
35
|
+
ensureEntry(ownerUserId: Scalars['BigInt']['input'], boardId: string, options?: {
|
|
36
|
+
displayName?: string;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
__typename?: "GmContainer";
|
|
39
|
+
containerId: string;
|
|
40
|
+
appId: string;
|
|
41
|
+
sessionId: string | null;
|
|
42
|
+
typeName: string;
|
|
43
|
+
displayName: string;
|
|
44
|
+
description: string | null;
|
|
45
|
+
ownerUserId: string | null;
|
|
46
|
+
metadataJson: string;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Submit a score — a **trusted** call (host by default per the blueprint's
|
|
50
|
+
* `submitAuthority`). Resolves with the entry's (possibly kept-best)
|
|
51
|
+
* score.
|
|
52
|
+
*/
|
|
53
|
+
submit(entryId: string, points: number): Promise<KitInvokeResult<number>>;
|
|
54
|
+
/** All entries of one board, sorted best-first with 1-based positions. */
|
|
55
|
+
board(boardId: string): Promise<KitLeaderboardEntry[]>;
|
|
56
|
+
/** The top `n` of a board (client-side ranking). */
|
|
57
|
+
top(boardId: string, n?: number): Promise<KitLeaderboardEntry[]>;
|
|
58
|
+
/**
|
|
59
|
+
* The entries around one player on a board (`radius` above and below),
|
|
60
|
+
* for "your neighborhood" widgets.
|
|
61
|
+
*/
|
|
62
|
+
around(boardId: string, userId: Scalars['BigInt']['input'], radius?: number): Promise<KitLeaderboardEntry[]>;
|
|
63
|
+
/** The board's current season (max season across its entries; 1 when empty). */
|
|
64
|
+
season(boardId: string): Promise<number>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=leaderboards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leaderboards.d.ts","sourceRoot":"","sources":["../../src/kit/leaderboards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAKvD,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAErB,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;gBAGvB,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY,EACxC,OAAO,GAAE,sBAA2B;IAKtC,kDAAkD;IAC5C,WAAW,CACf,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACvC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO;;;;;;;;;;;IAqBxC;;;;OAIG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAS/E,0EAA0E;IACpE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA6B5D,oDAAoD;IAC9C,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,SAAK,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAIlE;;;OAGG;IACG,MAAM,CACV,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAClC,MAAM,SAAI,GACT,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAOjC,gFAAgF;IAC1E,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAI/C"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { leaderboardsNames, } from './blueprints/index.js';
|
|
2
|
+
import { kitContainerProperties, kitInvoke, } from './shared.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runtime helpers for the {@link leaderboardsBlueprint} conventions: ensure
|
|
5
|
+
* per-player entries, submit scores (trusted — host by default), and rank.
|
|
6
|
+
* There is no server-side ORDER BY on container lists, so reads fetch a
|
|
7
|
+
* board's entries and sort client-side — fine for the few hundred entries a
|
|
8
|
+
* per-app board holds.
|
|
9
|
+
*
|
|
10
|
+
* Obtained via `client.kit(appId).leaderboards`.
|
|
11
|
+
*/
|
|
12
|
+
export class LeaderboardsKit {
|
|
13
|
+
constructor(appId, gameModel, options = {}) {
|
|
14
|
+
this.appId = appId;
|
|
15
|
+
this.gameModel = gameModel;
|
|
16
|
+
this.names = leaderboardsNames(options.typePrefix ?? '');
|
|
17
|
+
}
|
|
18
|
+
/** Find-or-create a player's entry on a board. */
|
|
19
|
+
async ensureEntry(ownerUserId, boardId, options = {}) {
|
|
20
|
+
const entries = await this.board(boardId);
|
|
21
|
+
const mine = entries.find((e) => e.ownerUserId === String(ownerUserId));
|
|
22
|
+
if (mine) {
|
|
23
|
+
return this.gameModel.container({
|
|
24
|
+
appId: this.appId,
|
|
25
|
+
containerId: mine.containerId,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return this.gameModel.createContainer({
|
|
29
|
+
appId: this.appId,
|
|
30
|
+
typeName: this.names.entryType,
|
|
31
|
+
displayName: options.displayName ?? `${boardId} ${ownerUserId}`,
|
|
32
|
+
properties: [
|
|
33
|
+
{ key: 'owner_user_id', valueType: 'int', valueJson: String(ownerUserId) },
|
|
34
|
+
{ key: 'board_id', valueType: 'string', valueJson: JSON.stringify(boardId) },
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Submit a score — a **trusted** call (host by default per the blueprint's
|
|
40
|
+
* `submitAuthority`). Resolves with the entry's (possibly kept-best)
|
|
41
|
+
* score.
|
|
42
|
+
*/
|
|
43
|
+
async submit(entryId, points) {
|
|
44
|
+
return kitInvoke(this.gameModel, {
|
|
45
|
+
appId: String(this.appId),
|
|
46
|
+
functionName: this.names.submitFn,
|
|
47
|
+
selfContainerId: entryId,
|
|
48
|
+
params: { points },
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** All entries of one board, sorted best-first with 1-based positions. */
|
|
52
|
+
async board(boardId) {
|
|
53
|
+
const containers = await this.gameModel.containers({
|
|
54
|
+
appId: this.appId,
|
|
55
|
+
typeName: this.names.entryType,
|
|
56
|
+
});
|
|
57
|
+
const rows = await Promise.all(containers.map(async (c) => {
|
|
58
|
+
const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
|
|
59
|
+
return {
|
|
60
|
+
containerId: c.containerId,
|
|
61
|
+
displayName: c.displayName,
|
|
62
|
+
ownerUserId: c.ownerUserId != null ? String(c.ownerUserId) : null,
|
|
63
|
+
boardId: String(props.board_id ?? ''),
|
|
64
|
+
score: Number(props.score ?? 0),
|
|
65
|
+
season: Number(props.season ?? 1),
|
|
66
|
+
position: 0,
|
|
67
|
+
};
|
|
68
|
+
}));
|
|
69
|
+
return rows
|
|
70
|
+
.filter((r) => r.boardId === boardId)
|
|
71
|
+
.sort((a, b) => b.score - a.score)
|
|
72
|
+
.map((r, i) => ({ ...r, position: i + 1 }));
|
|
73
|
+
}
|
|
74
|
+
/** The top `n` of a board (client-side ranking). */
|
|
75
|
+
async top(boardId, n = 10) {
|
|
76
|
+
return (await this.board(boardId)).slice(0, n);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The entries around one player on a board (`radius` above and below),
|
|
80
|
+
* for "your neighborhood" widgets.
|
|
81
|
+
*/
|
|
82
|
+
async around(boardId, userId, radius = 2) {
|
|
83
|
+
const entries = await this.board(boardId);
|
|
84
|
+
const index = entries.findIndex((e) => e.ownerUserId === String(userId));
|
|
85
|
+
if (index === -1)
|
|
86
|
+
return [];
|
|
87
|
+
return entries.slice(Math.max(0, index - radius), index + radius + 1);
|
|
88
|
+
}
|
|
89
|
+
/** The board's current season (max season across its entries; 1 when empty). */
|
|
90
|
+
async season(boardId) {
|
|
91
|
+
const entries = await this.board(boardId);
|
|
92
|
+
return entries.reduce((max, e) => Math.max(max, e.season), 1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { GameModelAPI } from '../domains/gameModel.js';
|
|
2
|
+
import type { Scalars } from '../generated/graphql.js';
|
|
3
|
+
import { type KitInvokeResult } from './shared.js';
|
|
4
|
+
/** Options for {@link LootKit}. Must match the deployed loot blueprint. */
|
|
5
|
+
export interface LootKitOptions {
|
|
6
|
+
/** The `typePrefix` the loot blueprint was deployed with. */
|
|
7
|
+
typePrefix?: string;
|
|
8
|
+
}
|
|
9
|
+
/** A parsed view of one loot roll. */
|
|
10
|
+
export interface KitLootRoll {
|
|
11
|
+
containerId: string;
|
|
12
|
+
displayName: string;
|
|
13
|
+
ownerUserId: string | null;
|
|
14
|
+
tableId: string;
|
|
15
|
+
/** Empty until rolled. */
|
|
16
|
+
rolledItemId: string;
|
|
17
|
+
rolledQty: number;
|
|
18
|
+
claimed: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Runtime helpers for the {@link lootBlueprint} conventions: create durable
|
|
22
|
+
* `LootRoll` containers, roll them (trusted — app admins by default, or the
|
|
23
|
+
* blueprint's event-drop automations), and claim results atomically into an
|
|
24
|
+
* item stack. The weighted selection runs entirely server-side from a stored
|
|
25
|
+
* seed, so clients can neither pick their loot nor claim it twice.
|
|
26
|
+
*
|
|
27
|
+
* Obtained via `client.kit(appId).loot`.
|
|
28
|
+
*/
|
|
29
|
+
export declare class LootKit {
|
|
30
|
+
private readonly appId;
|
|
31
|
+
private readonly gameModel;
|
|
32
|
+
private readonly names;
|
|
33
|
+
private readonly typePrefix;
|
|
34
|
+
constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, options?: LootKitOptions);
|
|
35
|
+
/**
|
|
36
|
+
* Create an unrolled `LootRoll` for a table, owned by `ownerUserId` (who
|
|
37
|
+
* will claim it). Event-drop automations pick from the pool of unrolled
|
|
38
|
+
* rolls — create a few ahead of time for tables wired to `drops`.
|
|
39
|
+
*/
|
|
40
|
+
createRoll(input: {
|
|
41
|
+
ownerUserId: Scalars['BigInt']['input'];
|
|
42
|
+
tableId: string;
|
|
43
|
+
displayName?: string;
|
|
44
|
+
sessionId?: string;
|
|
45
|
+
}): Promise<{
|
|
46
|
+
__typename?: "GmContainer";
|
|
47
|
+
containerId: string;
|
|
48
|
+
appId: string;
|
|
49
|
+
sessionId: string | null;
|
|
50
|
+
typeName: string;
|
|
51
|
+
displayName: string;
|
|
52
|
+
description: string | null;
|
|
53
|
+
ownerUserId: string | null;
|
|
54
|
+
metadataJson: string;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Roll a table on an unrolled `LootRoll` — a **trusted** call (default
|
|
58
|
+
* blueprint authority: app admins). Resolves with the rolled item id.
|
|
59
|
+
*
|
|
60
|
+
* @param tableId - The roll container's table (derives the function name);
|
|
61
|
+
* read from the container when omitted.
|
|
62
|
+
*/
|
|
63
|
+
roll(rollId: string, tableId?: string): Promise<KitInvokeResult<string>>;
|
|
64
|
+
/**
|
|
65
|
+
* Claim a rolled loot into a caller-owned stack of the rolled item. The
|
|
66
|
+
* claimed flag and the grant commit atomically. Resolves with the granted
|
|
67
|
+
* quantity.
|
|
68
|
+
*/
|
|
69
|
+
claim(rollId: string, toStackId: string): Promise<KitInvokeResult<number>>;
|
|
70
|
+
/** Read one roll's state. */
|
|
71
|
+
state(rollId: string): Promise<KitLootRoll>;
|
|
72
|
+
/**
|
|
73
|
+
* List a player's rolls, optionally filtered to one table and/or to
|
|
74
|
+
* unclaimed rolled loot (the "your drops" screen).
|
|
75
|
+
*/
|
|
76
|
+
rolls(ownerUserId: Scalars['BigInt']['input'], options?: {
|
|
77
|
+
tableId?: string;
|
|
78
|
+
unclaimedOnly?: boolean;
|
|
79
|
+
}): Promise<KitLootRoll[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Roll/claim audit history from the model event log (each roll records its
|
|
82
|
+
* seed, item, and quantity as applied mutations).
|
|
83
|
+
*/
|
|
84
|
+
history(options?: {
|
|
85
|
+
tableId?: string;
|
|
86
|
+
limit?: number;
|
|
87
|
+
}): Promise<{
|
|
88
|
+
__typename?: "GmEvent";
|
|
89
|
+
eventId: string;
|
|
90
|
+
sessionId: string | null;
|
|
91
|
+
functionName: string;
|
|
92
|
+
selfContainerId: string | null;
|
|
93
|
+
callerUserId: string | null;
|
|
94
|
+
callerKind: string;
|
|
95
|
+
automationId: string | null;
|
|
96
|
+
paramsJson: string;
|
|
97
|
+
mutationsAppliedJson: string;
|
|
98
|
+
permissionEffectsAppliedJson: string;
|
|
99
|
+
returnValueJson: string | null;
|
|
100
|
+
success: boolean;
|
|
101
|
+
errorMessage: string | null;
|
|
102
|
+
executedAt: string;
|
|
103
|
+
}[]>;
|
|
104
|
+
private toRoll;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=loot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loot.d.ts","sourceRoot":"","sources":["../../src/kit/loot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,qBAAa,OAAO;IAKhB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGjB,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY,EACxC,OAAO,GAAE,cAAmB;IAM9B;;;;OAIG;IACG,UAAU,CAAC,KAAK,EAAE;QACtB,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;;;;;;;;;;;IAqBD;;;;;;OAMG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAU9E;;;;OAIG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAShF,6BAA6B;IACvB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAYjD;;;OAGG;IACG,KAAK,CACT,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACvC,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1D,OAAO,CAAC,WAAW,EAAE,CAAC;IAwBzB;;;OAGG;IACG,OAAO,CACX,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;;;;;;;;;;;;;;;;;YAYtC,MAAM;CAoBrB"}
|
package/dist/kit/loot.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { lootNames, lootRollFn } from './blueprints/index.js';
|
|
2
|
+
import { kitContainerProperties, kitInvoke, } from './shared.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runtime helpers for the {@link lootBlueprint} conventions: create durable
|
|
5
|
+
* `LootRoll` containers, roll them (trusted — app admins by default, or the
|
|
6
|
+
* blueprint's event-drop automations), and claim results atomically into an
|
|
7
|
+
* item stack. The weighted selection runs entirely server-side from a stored
|
|
8
|
+
* seed, so clients can neither pick their loot nor claim it twice.
|
|
9
|
+
*
|
|
10
|
+
* Obtained via `client.kit(appId).loot`.
|
|
11
|
+
*/
|
|
12
|
+
export class LootKit {
|
|
13
|
+
constructor(appId, gameModel, options = {}) {
|
|
14
|
+
this.appId = appId;
|
|
15
|
+
this.gameModel = gameModel;
|
|
16
|
+
this.typePrefix = options.typePrefix ?? '';
|
|
17
|
+
this.names = lootNames(this.typePrefix);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create an unrolled `LootRoll` for a table, owned by `ownerUserId` (who
|
|
21
|
+
* will claim it). Event-drop automations pick from the pool of unrolled
|
|
22
|
+
* rolls — create a few ahead of time for tables wired to `drops`.
|
|
23
|
+
*/
|
|
24
|
+
async createRoll(input) {
|
|
25
|
+
return this.gameModel.createContainer({
|
|
26
|
+
appId: this.appId,
|
|
27
|
+
typeName: this.names.rollType,
|
|
28
|
+
displayName: input.displayName ?? `Roll ${input.tableId}`,
|
|
29
|
+
...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
|
|
30
|
+
properties: [
|
|
31
|
+
{
|
|
32
|
+
key: 'owner_user_id',
|
|
33
|
+
valueType: 'int',
|
|
34
|
+
valueJson: String(input.ownerUserId),
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'table_id',
|
|
38
|
+
valueType: 'string',
|
|
39
|
+
valueJson: JSON.stringify(input.tableId),
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Roll a table on an unrolled `LootRoll` — a **trusted** call (default
|
|
46
|
+
* blueprint authority: app admins). Resolves with the rolled item id.
|
|
47
|
+
*
|
|
48
|
+
* @param tableId - The roll container's table (derives the function name);
|
|
49
|
+
* read from the container when omitted.
|
|
50
|
+
*/
|
|
51
|
+
async roll(rollId, tableId) {
|
|
52
|
+
const table = tableId ?? (await this.state(rollId)).tableId;
|
|
53
|
+
return kitInvoke(this.gameModel, {
|
|
54
|
+
appId: String(this.appId),
|
|
55
|
+
functionName: lootRollFn(table, this.typePrefix),
|
|
56
|
+
selfContainerId: rollId,
|
|
57
|
+
params: {},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Claim a rolled loot into a caller-owned stack of the rolled item. The
|
|
62
|
+
* claimed flag and the grant commit atomically. Resolves with the granted
|
|
63
|
+
* quantity.
|
|
64
|
+
*/
|
|
65
|
+
async claim(rollId, toStackId) {
|
|
66
|
+
return kitInvoke(this.gameModel, {
|
|
67
|
+
appId: String(this.appId),
|
|
68
|
+
functionName: this.names.claimFn,
|
|
69
|
+
selfContainerId: rollId,
|
|
70
|
+
params: { to_stack_id: toStackId },
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** Read one roll's state. */
|
|
74
|
+
async state(rollId) {
|
|
75
|
+
const container = await this.gameModel.container({
|
|
76
|
+
appId: this.appId,
|
|
77
|
+
containerId: rollId,
|
|
78
|
+
});
|
|
79
|
+
return this.toRoll(container.containerId, container.displayName, container.ownerUserId != null ? String(container.ownerUserId) : null);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* List a player's rolls, optionally filtered to one table and/or to
|
|
83
|
+
* unclaimed rolled loot (the "your drops" screen).
|
|
84
|
+
*/
|
|
85
|
+
async rolls(ownerUserId, options = {}) {
|
|
86
|
+
const containers = await this.gameModel.containers({
|
|
87
|
+
appId: this.appId,
|
|
88
|
+
typeName: this.names.rollType,
|
|
89
|
+
});
|
|
90
|
+
const mine = containers.filter((c) => c.ownerUserId != null && String(c.ownerUserId) === String(ownerUserId));
|
|
91
|
+
const rolls = await Promise.all(mine.map((c) => this.toRoll(c.containerId, c.displayName, c.ownerUserId != null ? String(c.ownerUserId) : null)));
|
|
92
|
+
return rolls.filter((r) => (options.tableId === undefined || r.tableId === options.tableId) &&
|
|
93
|
+
(!options.unclaimedOnly || (!r.claimed && r.rolledItemId !== '')));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Roll/claim audit history from the model event log (each roll records its
|
|
97
|
+
* seed, item, and quantity as applied mutations).
|
|
98
|
+
*/
|
|
99
|
+
async history(options = {}) {
|
|
100
|
+
return this.gameModel.events({
|
|
101
|
+
appId: this.appId,
|
|
102
|
+
functionName: options.tableId !== undefined
|
|
103
|
+
? lootRollFn(options.tableId, this.typePrefix)
|
|
104
|
+
: this.names.claimFn,
|
|
105
|
+
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async toRoll(containerId, displayName, ownerUserId) {
|
|
109
|
+
const props = await kitContainerProperties(this.gameModel, String(this.appId), containerId);
|
|
110
|
+
return {
|
|
111
|
+
containerId,
|
|
112
|
+
displayName,
|
|
113
|
+
ownerUserId,
|
|
114
|
+
tableId: String(props.table_id ?? ''),
|
|
115
|
+
rolledItemId: String(props.rolled_item_id ?? ''),
|
|
116
|
+
rolledQty: Number(props.rolled_qty ?? 0),
|
|
117
|
+
claimed: props.claimed === true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|