@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.
Files changed (102) hide show
  1. package/README.md +21 -3
  2. package/dist/crowdy-client.d.ts.map +1 -1
  3. package/dist/crowdy-client.js +5 -1
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/kit/blueprints/combat.d.ts +75 -0
  8. package/dist/kit/blueprints/combat.d.ts.map +1 -0
  9. package/dist/kit/blueprints/combat.js +351 -0
  10. package/dist/kit/blueprints/core.d.ts +222 -0
  11. package/dist/kit/blueprints/core.d.ts.map +1 -0
  12. package/dist/kit/blueprints/core.js +185 -0
  13. package/dist/kit/blueprints/decks.d.ts +50 -0
  14. package/dist/kit/blueprints/decks.d.ts.map +1 -0
  15. package/dist/kit/blueprints/decks.js +163 -0
  16. package/dist/kit/blueprints/economy.d.ts +88 -0
  17. package/dist/kit/blueprints/economy.d.ts.map +1 -0
  18. package/dist/kit/blueprints/economy.js +533 -0
  19. package/dist/kit/blueprints/guild.d.ts +51 -0
  20. package/dist/kit/blueprints/guild.d.ts.map +1 -0
  21. package/dist/kit/blueprints/guild.js +50 -0
  22. package/dist/kit/blueprints/index.d.ts +21 -0
  23. package/dist/kit/blueprints/index.d.ts.map +1 -0
  24. package/dist/kit/blueprints/index.js +20 -0
  25. package/dist/kit/blueprints/inventory.d.ts +38 -0
  26. package/dist/kit/blueprints/inventory.d.ts.map +1 -0
  27. package/dist/kit/blueprints/inventory.js +157 -0
  28. package/dist/kit/blueprints/leaderboards.d.ts +49 -0
  29. package/dist/kit/blueprints/leaderboards.d.ts.map +1 -0
  30. package/dist/kit/blueprints/leaderboards.js +126 -0
  31. package/dist/kit/blueprints/locks.d.ts +82 -0
  32. package/dist/kit/blueprints/locks.d.ts.map +1 -0
  33. package/dist/kit/blueprints/locks.js +155 -0
  34. package/dist/kit/blueprints/loot.d.ts +84 -0
  35. package/dist/kit/blueprints/loot.d.ts.map +1 -0
  36. package/dist/kit/blueprints/loot.js +228 -0
  37. package/dist/kit/blueprints/matches.d.ts +59 -0
  38. package/dist/kit/blueprints/matches.d.ts.map +1 -0
  39. package/dist/kit/blueprints/matches.js +246 -0
  40. package/dist/kit/blueprints/npcs.d.ts +71 -0
  41. package/dist/kit/blueprints/npcs.d.ts.map +1 -0
  42. package/dist/kit/blueprints/npcs.js +122 -0
  43. package/dist/kit/blueprints/plots.d.ts +54 -0
  44. package/dist/kit/blueprints/plots.d.ts.map +1 -0
  45. package/dist/kit/blueprints/plots.js +146 -0
  46. package/dist/kit/blueprints/progression.d.ts +68 -0
  47. package/dist/kit/blueprints/progression.d.ts.map +1 -0
  48. package/dist/kit/blueprints/progression.js +324 -0
  49. package/dist/kit/blueprints/quests.d.ts +65 -0
  50. package/dist/kit/blueprints/quests.d.ts.map +1 -0
  51. package/dist/kit/blueprints/quests.js +284 -0
  52. package/dist/kit/blueprints/worldsim.d.ts +84 -0
  53. package/dist/kit/blueprints/worldsim.d.ts.map +1 -0
  54. package/dist/kit/blueprints/worldsim.js +461 -0
  55. package/dist/kit/combat.d.ts +103 -0
  56. package/dist/kit/combat.d.ts.map +1 -0
  57. package/dist/kit/combat.js +151 -0
  58. package/dist/kit/decks.d.ts +123 -0
  59. package/dist/kit/decks.d.ts.map +1 -0
  60. package/dist/kit/decks.js +138 -0
  61. package/dist/kit/economy.d.ts +244 -0
  62. package/dist/kit/economy.d.ts.map +1 -0
  63. package/dist/kit/economy.js +365 -0
  64. package/dist/kit/features.d.ts +60 -0
  65. package/dist/kit/features.d.ts.map +1 -0
  66. package/dist/kit/features.js +65 -0
  67. package/dist/kit/index.d.ts +13 -2
  68. package/dist/kit/index.d.ts.map +1 -1
  69. package/dist/kit/index.js +12 -1
  70. package/dist/kit/inventory.d.ts +5 -0
  71. package/dist/kit/inventory.d.ts.map +1 -1
  72. package/dist/kit/inventory.js +14 -1
  73. package/dist/kit/kit.d.ts +58 -2
  74. package/dist/kit/kit.d.ts.map +1 -1
  75. package/dist/kit/kit.js +24 -2
  76. package/dist/kit/leaderboards.d.ts +66 -0
  77. package/dist/kit/leaderboards.d.ts.map +1 -0
  78. package/dist/kit/leaderboards.js +94 -0
  79. package/dist/kit/loot.d.ts +106 -0
  80. package/dist/kit/loot.d.ts.map +1 -0
  81. package/dist/kit/loot.js +120 -0
  82. package/dist/kit/matches.d.ts +140 -0
  83. package/dist/kit/matches.d.ts.map +1 -0
  84. package/dist/kit/matches.js +253 -0
  85. package/dist/kit/objects.js +1 -1
  86. package/dist/kit/plots.js +1 -1
  87. package/dist/kit/progression.d.ts +181 -0
  88. package/dist/kit/progression.d.ts.map +1 -0
  89. package/dist/kit/progression.js +265 -0
  90. package/dist/kit/quests.d.ts +110 -0
  91. package/dist/kit/quests.d.ts.map +1 -0
  92. package/dist/kit/quests.js +158 -0
  93. package/dist/kit/social.d.ts +267 -0
  94. package/dist/kit/social.d.ts.map +1 -0
  95. package/dist/kit/social.js +230 -0
  96. package/dist/kit/worldsim.d.ts +225 -0
  97. package/dist/kit/worldsim.d.ts.map +1 -0
  98. package/dist/kit/worldsim.js +231 -0
  99. package/package.json +1 -1
  100. package/dist/kit/blueprints.d.ts +0 -370
  101. package/dist/kit/blueprints.d.ts.map +0 -1
  102. package/dist/kit/blueprints.js +0 -643
@@ -0,0 +1,225 @@
1
+ import type { GameModelAPI } from '../domains/gameModel.js';
2
+ import type { Scalars, SeedPropertyInput } from '../generated/graphql.js';
3
+ import { type KitInvokeResult } from './shared.js';
4
+ /** Options for {@link WorldsimKit}. Must match the deployed worldsim blueprint. */
5
+ export interface WorldsimKitOptions {
6
+ /** The `typePrefix` the worldsim blueprint was deployed with. */
7
+ typePrefix?: string;
8
+ }
9
+ /** A parsed view of the world clock/weather state. */
10
+ export interface KitWorldState {
11
+ containerId: string;
12
+ timeOfDay: number;
13
+ day: number;
14
+ weather: string;
15
+ }
16
+ /** A parsed view of one resource node. */
17
+ export interface KitResourceNode {
18
+ containerId: string;
19
+ displayName: string;
20
+ nodeId: string;
21
+ resourceItemId: string;
22
+ amount: number;
23
+ maxAmount: number;
24
+ regenRate: number;
25
+ x: number;
26
+ y: number;
27
+ z: number;
28
+ }
29
+ /** A parsed view of one crop / production job. */
30
+ export interface KitCrop {
31
+ containerId: string;
32
+ displayName: string;
33
+ ownerUserId: string | null;
34
+ stage: number;
35
+ maxStage: number;
36
+ outputItemId: string;
37
+ outputQty: number;
38
+ ready: boolean;
39
+ }
40
+ /** A parsed view of one wave spawner. */
41
+ export interface KitWaveSpawner {
42
+ containerId: string;
43
+ displayName: string;
44
+ wave: number;
45
+ nextWaveSize: number;
46
+ }
47
+ /**
48
+ * Runtime helpers for the {@link worldsimBlueprint} conventions: the world
49
+ * clock/weather singleton, regenerating resource nodes players gather from,
50
+ * crops that mature server-side, and wave counters the host reads. The
51
+ * simulation itself runs in automations — these helpers create/read state
52
+ * and drive the player-facing functions.
53
+ *
54
+ * Obtained via `client.kit(appId).worldsim`.
55
+ */
56
+ export declare class WorldsimKit {
57
+ private readonly appId;
58
+ private readonly gameModel;
59
+ private readonly names;
60
+ constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, options?: WorldsimKitOptions);
61
+ /**
62
+ * Find-or-create the WorldState singleton (admin). `anchorChunk` is where
63
+ * the clock's spatial time-changed ping is emitted.
64
+ */
65
+ ensureWorld(options?: {
66
+ anchorChunk?: {
67
+ x: number;
68
+ y: number;
69
+ z: number;
70
+ };
71
+ displayName?: string;
72
+ }): Promise<{
73
+ __typename?: "GmContainer";
74
+ containerId: string;
75
+ appId: string;
76
+ sessionId: string | null;
77
+ typeName: string;
78
+ displayName: string;
79
+ description: string | null;
80
+ ownerUserId: string | null;
81
+ metadataJson: string;
82
+ }>;
83
+ /** Read the world clock/weather state. */
84
+ worldState(): Promise<KitWorldState>;
85
+ /** Force the weather (app admins only — the policy denies everyone else). */
86
+ setWeather(weather: string): Promise<KitInvokeResult<string>>;
87
+ /** Create a resource node (admin). */
88
+ createNode(input: {
89
+ displayName: string;
90
+ nodeId: string;
91
+ resourceItemId: string;
92
+ amount?: number;
93
+ maxAmount?: number;
94
+ regenRate?: number;
95
+ position?: {
96
+ x: number;
97
+ y: number;
98
+ z: number;
99
+ };
100
+ properties?: SeedPropertyInput[];
101
+ }): Promise<{
102
+ __typename?: "GmContainer";
103
+ containerId: string;
104
+ appId: string;
105
+ sessionId: string | null;
106
+ typeName: string;
107
+ displayName: string;
108
+ description: string | null;
109
+ ownerUserId: string | null;
110
+ metadataJson: string;
111
+ }>;
112
+ /** List resource nodes with parsed state. */
113
+ nodes(): Promise<KitResourceNode[]>;
114
+ /**
115
+ * Gather from a node into a caller-owned stack of the node's resource;
116
+ * the node decrement and the grant commit atomically. Resolves with the
117
+ * node's remaining amount.
118
+ */
119
+ gather(input: {
120
+ nodeId: string;
121
+ amount: number;
122
+ toStackId: string;
123
+ }): Promise<KitInvokeResult<number>>;
124
+ /** Plant a crop / start a production job (member). */
125
+ plant(input: {
126
+ ownerUserId: Scalars['BigInt']['input'];
127
+ outputItemId: string;
128
+ outputQty?: number;
129
+ maxStage?: number;
130
+ displayName?: string;
131
+ sessionId?: string;
132
+ }): Promise<{
133
+ __typename?: "GmContainer";
134
+ containerId: string;
135
+ appId: string;
136
+ sessionId: string | null;
137
+ typeName: string;
138
+ displayName: string;
139
+ description: string | null;
140
+ ownerUserId: string | null;
141
+ metadataJson: string;
142
+ }>;
143
+ /** List a player's crops (all crops when `ownerUserId` is null). */
144
+ crops(ownerUserId: Scalars['BigInt']['input'] | null): Promise<KitCrop[]>;
145
+ /**
146
+ * Harvest a grown crop into a caller-owned stack of the output item;
147
+ * resets the stage for regrowth. Resolves with the yield quantity.
148
+ */
149
+ harvest(cropId: string, toStackId: string): Promise<KitInvokeResult<number>>;
150
+ /** Create a wave spawner (admin; blueprint deployed with `waves`). */
151
+ createSpawner(input: {
152
+ displayName: string;
153
+ nextWaveSize?: number;
154
+ }): Promise<{
155
+ __typename?: "GmContainer";
156
+ containerId: string;
157
+ appId: string;
158
+ sessionId: string | null;
159
+ typeName: string;
160
+ displayName: string;
161
+ description: string | null;
162
+ ownerUserId: string | null;
163
+ metadataJson: string;
164
+ }>;
165
+ /** List wave spawners (the host reads these to spawn entities). */
166
+ spawners(): Promise<KitWaveSpawner[]>;
167
+ /** Run one of the worldsim automations immediately (admin; for testing). */
168
+ runNow(automationName: string): Promise<{
169
+ __typename?: "GmAutomationRun";
170
+ runId: string;
171
+ appId: string;
172
+ automationId: string;
173
+ automationName: string;
174
+ triggerSource: string;
175
+ parentRunId: string | null;
176
+ cascadeDepth: number;
177
+ startedAt: string;
178
+ finishedAt: string | null;
179
+ durationUs: number;
180
+ targets: number;
181
+ invocations: number;
182
+ mutations: number;
183
+ fnCalls: number;
184
+ gasUsed: number;
185
+ success: boolean;
186
+ errorMessage: string | null;
187
+ circuitAction: string | null;
188
+ computeUnits: number;
189
+ }>;
190
+ /** Pause or resume one of the worldsim automations (admin). */
191
+ setEnabled(automationName: string, enabled: boolean): Promise<{
192
+ __typename?: "GmAutomation";
193
+ automationId: string;
194
+ appId: string;
195
+ name: string;
196
+ description: string | null;
197
+ enabled: boolean;
198
+ functionName: string;
199
+ targetMode: string;
200
+ selfContainerId: string | null;
201
+ targetTypeName: string | null;
202
+ sessionId: string | null;
203
+ paramsJson: string;
204
+ selectorJson: string | null;
205
+ runAsUserId: string | null;
206
+ triggerType: string;
207
+ scheduleKind: string | null;
208
+ intervalMs: number | null;
209
+ cronExpr: string | null;
210
+ maxTargets: number;
211
+ maxFnDepth: number | null;
212
+ gasLimit: number | null;
213
+ runTimeoutMs: number | null;
214
+ maxRunsPerMinute: number;
215
+ failureThreshold: number;
216
+ cooldownMs: number;
217
+ circuitState: string;
218
+ consecutiveFailures: number;
219
+ pausedUntil: string | null;
220
+ lastError: string | null;
221
+ lastRunAt: string | null;
222
+ nextRunAt: string | null;
223
+ }>;
224
+ }
225
+ //# sourceMappingURL=worldsim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worldsim.d.ts","sourceRoot":"","sources":["../../src/kit/worldsim.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,231 @@
1
+ import { worldsimNames } from './blueprints/index.js';
2
+ import { kitContainerProperties, kitInvoke, } from './shared.js';
3
+ /**
4
+ * Runtime helpers for the {@link worldsimBlueprint} conventions: the world
5
+ * clock/weather singleton, regenerating resource nodes players gather from,
6
+ * crops that mature server-side, and wave counters the host reads. The
7
+ * simulation itself runs in automations — these helpers create/read state
8
+ * and drive the player-facing functions.
9
+ *
10
+ * Obtained via `client.kit(appId).worldsim`.
11
+ */
12
+ export class WorldsimKit {
13
+ constructor(appId, gameModel, options = {}) {
14
+ this.appId = appId;
15
+ this.gameModel = gameModel;
16
+ this.names = worldsimNames(options.typePrefix ?? '');
17
+ }
18
+ /**
19
+ * Find-or-create the WorldState singleton (admin). `anchorChunk` is where
20
+ * the clock's spatial time-changed ping is emitted.
21
+ */
22
+ async ensureWorld(options = {}) {
23
+ const existing = await this.gameModel.containers({
24
+ appId: this.appId,
25
+ typeName: this.names.worldStateType,
26
+ });
27
+ if (existing.length > 0)
28
+ return existing[0];
29
+ return this.gameModel.createContainer({
30
+ appId: this.appId,
31
+ typeName: this.names.worldStateType,
32
+ displayName: options.displayName ?? 'World',
33
+ properties: options.anchorChunk
34
+ ? [
35
+ { key: 'cx', valueType: 'int', valueJson: String(options.anchorChunk.x) },
36
+ { key: 'cy', valueType: 'int', valueJson: String(options.anchorChunk.y) },
37
+ { key: 'cz', valueType: 'int', valueJson: String(options.anchorChunk.z) },
38
+ ]
39
+ : [],
40
+ });
41
+ }
42
+ /** Read the world clock/weather state. */
43
+ async worldState() {
44
+ const containers = await this.gameModel.containers({
45
+ appId: this.appId,
46
+ typeName: this.names.worldStateType,
47
+ });
48
+ if (containers.length === 0) {
49
+ throw new Error(`No ${this.names.worldStateType} exists yet — run kit.worldsim.ensureWorld() as admin`);
50
+ }
51
+ const props = await kitContainerProperties(this.gameModel, String(this.appId), containers[0].containerId);
52
+ return {
53
+ containerId: containers[0].containerId,
54
+ timeOfDay: Number(props.time_of_day ?? 0),
55
+ day: Number(props.day ?? 0),
56
+ weather: String(props.weather ?? 'clear'),
57
+ };
58
+ }
59
+ /** Force the weather (app admins only — the policy denies everyone else). */
60
+ async setWeather(weather) {
61
+ const state = await this.worldState();
62
+ return kitInvoke(this.gameModel, {
63
+ appId: String(this.appId),
64
+ functionName: this.names.setWeatherFn,
65
+ selfContainerId: state.containerId,
66
+ params: { weather },
67
+ });
68
+ }
69
+ /** Create a resource node (admin). */
70
+ async createNode(input) {
71
+ const maxAmount = input.maxAmount ?? 100;
72
+ return this.gameModel.createContainer({
73
+ appId: this.appId,
74
+ typeName: this.names.nodeType,
75
+ displayName: input.displayName,
76
+ properties: [
77
+ { key: 'node_id', valueType: 'string', valueJson: JSON.stringify(input.nodeId) },
78
+ {
79
+ key: 'resource_item_id',
80
+ valueType: 'string',
81
+ valueJson: JSON.stringify(input.resourceItemId),
82
+ },
83
+ { key: 'amount', valueType: 'int', valueJson: String(input.amount ?? maxAmount) },
84
+ { key: 'max_amount', valueType: 'int', valueJson: String(maxAmount) },
85
+ { key: 'regen_rate', valueType: 'int', valueJson: String(input.regenRate ?? 1) },
86
+ ...(input.position
87
+ ? [
88
+ { key: 'x', valueType: 'float', valueJson: String(input.position.x) },
89
+ { key: 'y', valueType: 'float', valueJson: String(input.position.y) },
90
+ { key: 'z', valueType: 'float', valueJson: String(input.position.z) },
91
+ ]
92
+ : []),
93
+ ...(input.properties ?? []),
94
+ ],
95
+ });
96
+ }
97
+ /** List resource nodes with parsed state. */
98
+ async nodes() {
99
+ const containers = await this.gameModel.containers({
100
+ appId: this.appId,
101
+ typeName: this.names.nodeType,
102
+ });
103
+ return Promise.all(containers.map(async (c) => {
104
+ const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
105
+ return {
106
+ containerId: c.containerId,
107
+ displayName: c.displayName,
108
+ nodeId: String(props.node_id ?? ''),
109
+ resourceItemId: String(props.resource_item_id ?? ''),
110
+ amount: Number(props.amount ?? 0),
111
+ maxAmount: Number(props.max_amount ?? 0),
112
+ regenRate: Number(props.regen_rate ?? 0),
113
+ x: Number(props.x ?? 0),
114
+ y: Number(props.y ?? 0),
115
+ z: Number(props.z ?? 0),
116
+ };
117
+ }));
118
+ }
119
+ /**
120
+ * Gather from a node into a caller-owned stack of the node's resource;
121
+ * the node decrement and the grant commit atomically. Resolves with the
122
+ * node's remaining amount.
123
+ */
124
+ async gather(input) {
125
+ return kitInvoke(this.gameModel, {
126
+ appId: String(this.appId),
127
+ functionName: this.names.gatherNodeFn,
128
+ selfContainerId: input.nodeId,
129
+ params: { amount: input.amount, to_stack_id: input.toStackId },
130
+ });
131
+ }
132
+ /** Plant a crop / start a production job (member). */
133
+ async plant(input) {
134
+ return this.gameModel.createContainer({
135
+ appId: this.appId,
136
+ typeName: this.names.cropType,
137
+ displayName: input.displayName ?? `Crop ${input.outputItemId}`,
138
+ ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
139
+ properties: [
140
+ { key: 'owner_user_id', valueType: 'int', valueJson: String(input.ownerUserId) },
141
+ {
142
+ key: 'output_item_id',
143
+ valueType: 'string',
144
+ valueJson: JSON.stringify(input.outputItemId),
145
+ },
146
+ { key: 'output_qty', valueType: 'int', valueJson: String(input.outputQty ?? 1) },
147
+ { key: 'max_stage', valueType: 'int', valueJson: String(input.maxStage ?? 3) },
148
+ ],
149
+ });
150
+ }
151
+ /** List a player's crops (all crops when `ownerUserId` is null). */
152
+ async crops(ownerUserId) {
153
+ const containers = await this.gameModel.containers({
154
+ appId: this.appId,
155
+ typeName: this.names.cropType,
156
+ });
157
+ const filtered = ownerUserId === null
158
+ ? containers
159
+ : containers.filter((c) => c.ownerUserId != null && String(c.ownerUserId) === String(ownerUserId));
160
+ return Promise.all(filtered.map(async (c) => {
161
+ const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
162
+ const stage = Number(props.stage ?? 0);
163
+ const maxStage = Number(props.max_stage ?? 0);
164
+ return {
165
+ containerId: c.containerId,
166
+ displayName: c.displayName,
167
+ ownerUserId: c.ownerUserId != null ? String(c.ownerUserId) : null,
168
+ stage,
169
+ maxStage,
170
+ outputItemId: String(props.output_item_id ?? ''),
171
+ outputQty: Number(props.output_qty ?? 0),
172
+ ready: maxStage > 0 && stage >= maxStage,
173
+ };
174
+ }));
175
+ }
176
+ /**
177
+ * Harvest a grown crop into a caller-owned stack of the output item;
178
+ * resets the stage for regrowth. Resolves with the yield quantity.
179
+ */
180
+ async harvest(cropId, toStackId) {
181
+ return kitInvoke(this.gameModel, {
182
+ appId: String(this.appId),
183
+ functionName: this.names.harvestFn,
184
+ selfContainerId: cropId,
185
+ params: { to_stack_id: toStackId },
186
+ });
187
+ }
188
+ /** Create a wave spawner (admin; blueprint deployed with `waves`). */
189
+ async createSpawner(input) {
190
+ return this.gameModel.createContainer({
191
+ appId: this.appId,
192
+ typeName: this.names.spawnerType,
193
+ displayName: input.displayName,
194
+ properties: [
195
+ {
196
+ key: 'next_wave_size',
197
+ valueType: 'int',
198
+ valueJson: String(input.nextWaveSize ?? 5),
199
+ },
200
+ ],
201
+ });
202
+ }
203
+ /** List wave spawners (the host reads these to spawn entities). */
204
+ async spawners() {
205
+ const containers = await this.gameModel.containers({
206
+ appId: this.appId,
207
+ typeName: this.names.spawnerType,
208
+ });
209
+ return Promise.all(containers.map(async (c) => {
210
+ const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
211
+ return {
212
+ containerId: c.containerId,
213
+ displayName: c.displayName,
214
+ wave: Number(props.wave ?? 0),
215
+ nextWaveSize: Number(props.next_wave_size ?? 0),
216
+ };
217
+ }));
218
+ }
219
+ /** Run one of the worldsim automations immediately (admin; for testing). */
220
+ async runNow(automationName) {
221
+ return this.gameModel.runAutomation({ appId: this.appId, name: automationName });
222
+ }
223
+ /** Pause or resume one of the worldsim automations (admin). */
224
+ async setEnabled(automationName, enabled) {
225
+ return this.gameModel.setAutomationEnabled({
226
+ appId: this.appId,
227
+ name: automationName,
228
+ enabled,
229
+ });
230
+ }
231
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdedkingdoms/crowdyjs",
3
- "version": "8.2.0",
3
+ "version": "8.3.0",
4
4
  "description": "Client SDK for Crowded Kingdoms GraphQL API with UDP proxy support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",