@kradle/challenges-sdk 0.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 ADDED
@@ -0,0 +1,489 @@
1
+ <!-- This file is for human consumption. If you are an LLM or any AI Agent, make sure to read LLM_README.md for an exhaustive explanation of this package. -->
2
+
3
+ # @kradle/challenges-sdk
4
+
5
+ A TypeScript framework for creating Minecraft datapack-based challenges with event-driven game logic, score tracking, and player role management. Built on top of [Sandstone](https://sandstone.dev/).
6
+
7
+ ## Getting started
8
+
9
+ We strongly recommend using [Kradle's CLI](https://github.com/kradle-ai/cli) to create challenges with the CLI. Make sure to read the CLI's README
10
+
11
+ If you still want to perform a manual installation, you also need to install the Sandstone peer-dependency:
12
+ ```bash
13
+ npm install @kradle/challenges-sdk sandstone@0.14.0-alpha.13
14
+ ```
15
+
16
+ ## Quick Start
17
+
18
+ Like for installation, we strongly recommend using Kradle's CLI to bootstrap a challenge:
19
+
20
+ ```bash
21
+ # Will create a challenge in challenges/my-challenge/
22
+ kradle challenge create my-challenge
23
+ ```
24
+
25
+
26
+ ## API Overview
27
+
28
+ ### `createChallenge(config)`
29
+
30
+ Creates a new challenge with the specified configuration.
31
+
32
+ ```typescript
33
+ createChallenge({
34
+ name: string; // Challenge name (used for datapack)
35
+ kradle_challenge_path: string; // Output directory for generated datapack
36
+ roles: readonly string[]; // Player roles (e.g., ["attacker", "defender"])
37
+ GAME_DURATION?: number; // Duration in ticks (default: 6000 = 5 minutes)
38
+ custom_variables: Record<string, VariableDefinition>;
39
+ })
40
+ ```
41
+
42
+ ### Fluent Builder Methods
43
+
44
+ The challenge builder uses a fluent API:
45
+
46
+ ```typescript
47
+ createChallenge(config)
48
+ .events(callback) // Define lifecycle event handlers
49
+ .custom_events(callback) // Define score/advancement-triggered events
50
+ .end_condition(callback) // Define when the game ends
51
+ .win_conditions(callback) // Define win conditions per role
52
+ ```
53
+
54
+ ## Variables
55
+
56
+ Variables are the core mechanism for tracking game state. All variables are automatically updated each tick.
57
+
58
+ ### Built-in Variables
59
+
60
+ These variables are always available:
61
+
62
+ | Variable | Type | Description |
63
+ |----------|------|-------------|
64
+ | `death_count` | individual | Number of times the player has died |
65
+ | `has_never_died` | individual | 1 if player hasn't died, 0 otherwise |
66
+ | `alive_players` | global | Count of living participants |
67
+ | `main_score` | individual | Primary score displayed on sidebar |
68
+ | `game_timer` | global | Ticks elapsed since game start |
69
+ | `game_state` | global | Current state (0=CREATED, 1=OFF, 2=ON) |
70
+ | `player_count` | global | Total number of participants |
71
+ | `player_number` | individual | Unique player ID (1 to N) |
72
+
73
+ ### Custom Variable Types
74
+
75
+ #### Individual Variables (per-player)
76
+
77
+ Track values for each player separately.
78
+
79
+ **Objective-based** (uses Minecraft statistics):
80
+ ```typescript
81
+ pigs_killed: {
82
+ type: "individual",
83
+ objective_type: "minecraft.killed:minecraft.pig",
84
+ default: 0,
85
+ }
86
+ ```
87
+
88
+ **Dummy** (computed values):
89
+ ```typescript
90
+ current_height: {
91
+ type: "individual",
92
+ objective_type: "dummy",
93
+ updater: (value) => {
94
+ value.set(Actions.getPlayerPosition().y)
95
+ },
96
+ }
97
+ ```
98
+
99
+ #### Global Variables (shared)
100
+
101
+ Track values across all players.
102
+
103
+ ```typescript
104
+ max_score: {
105
+ type: "global",
106
+ hidden: false, // optional: hide from scoreboard
107
+ default: 0,
108
+ updater: (value, { main_score }) => {
109
+ value.set(0);
110
+ forEveryPlayer(() => {
111
+ _.if(main_score.greaterThan(value), () => {
112
+ value.set(main_score);
113
+ });
114
+ });
115
+ },
116
+ }
117
+ ```
118
+
119
+ ### Updater Functions
120
+
121
+ Updaters run every tick and receive `(currentValue, allVariables)`:
122
+
123
+ ```typescript
124
+ updater: (value, { main_score, death_count, game_timer }) => {
125
+ // Set value based on other variables
126
+ value.set(0);
127
+ _.if(main_score.greaterThan(10), () => {
128
+ value.set(1);
129
+ });
130
+ }
131
+ ```
132
+
133
+ If you track a Minecraft objective, you do not need an updater!
134
+
135
+ ## Events
136
+
137
+ ### Lifecycle Events
138
+
139
+ Lifecycle events are triggered once on specific occasions.
140
+
141
+ ```typescript
142
+ .events((variables, roles) => ({
143
+ start_challenge: () => {
144
+ // Runs once when the challenge starts
145
+ Actions.setTime({ time: "day" });
146
+ Actions.announce({ message: "Game starting!" });
147
+ },
148
+
149
+ init_participants: () => {
150
+ // Runs 1s after the challenge starts
151
+ Actions.give({ target: "all", item: "minecraft:diamond_sword", count: 1 });
152
+ Actions.setAttribute({ target: "all", attribute_: "generic.max_health", value: 40 });
153
+ },
154
+
155
+ on_tick: () => {
156
+ // Runs once every tick
157
+ },
158
+
159
+ end_challenge: () => {
160
+ // Runs when the challenge ends
161
+ Actions.announce({ message: "Game over!" });
162
+ },
163
+ }))
164
+ ```
165
+
166
+ ### Custom Events
167
+
168
+ Custom events trigger actions based on score thresholds or Minecraft advancements.
169
+
170
+ #### Score-based events
171
+
172
+ Score events watch a variable and trigger when it reaches a target value.
173
+
174
+ - **`score`**: The variable to watch.
175
+ - **`target`** (optional): The target value. If omitted, triggers on any score change
176
+ - **`mode`**:
177
+ - `"fire_once"`: Triggers once when the score reaches the target (per player for individual variables)
178
+ - `"repeatable"`: Triggers every tick while the score is at target
179
+
180
+ For individual variables, events fire per-player; for global variables, events fire globally.
181
+
182
+ ```typescript
183
+ .custom_events((variables, roles) => [
184
+ {
185
+ score: variables.diamonds,
186
+ target: 5,
187
+ mode: "fire_once",
188
+ actions: () => {
189
+ Actions.announce({ message: "Someone collected 5 diamonds!" });
190
+ },
191
+ },
192
+ ])
193
+ ```
194
+
195
+ If `target` is omitted, the event triggers whenever the score changes (useful for reacting to any increment).
196
+
197
+ #### Advancement-based events
198
+
199
+ Advancement events trigger when a Minecraft advancement criterion is met (e.g., player attacks, item picked up). The criteria follow the [Minecraft Advancement JSON format](https://minecraft.fandom.com/wiki/Advancement/JSON_format).
200
+
201
+ Advancement-based events always fire per-player.
202
+
203
+ - **`criteria`**: Array of advancement triggers with optional conditions
204
+ - **`mode`**:
205
+ - `"fire_once"`: Triggers once per player when the advancement is granted
206
+ - `"repeatable"`: Triggers every time the advancement criterion is met (advancement is auto-revoked to allow re-triggering)
207
+
208
+ ```typescript
209
+ .custom_events((variables, roles) => [
210
+ {
211
+ criteria: [
212
+ {
213
+ trigger: "minecraft:player_hurt_entity",
214
+ conditions: {
215
+ entity: { type: "minecraft:player" } // Only PvP hits
216
+ }
217
+ }
218
+ ],
219
+ mode: "repeatable",
220
+ actions: () => {
221
+ Actions.increment({ variable: variables.pvp_hits });
222
+ },
223
+ },
224
+ ])
225
+ ```
226
+
227
+ ## End Conditions
228
+
229
+ Define when the game ends:
230
+
231
+ ```typescript
232
+ .end_condition(({ objective_complete }) => objective_complete.equalTo(1))
233
+ ```
234
+
235
+ Multiple conditions can be combined:
236
+ ```typescript
237
+ .end_condition(({ alive_players, objective_complete }) =>
238
+ _.or(
239
+ alive_players.equalTo(1),
240
+ objective_complete.equalTo(1)
241
+ )
242
+ )
243
+ ```
244
+
245
+ Ending conditions are evaluated once per tick, at the global level (not individually). It means you should not check for individual variables here - instead, you should aggregate these individual variables into a global custom variable, that you then check in the ending condition.
246
+
247
+ ## Win Conditions
248
+
249
+ Define how winners are determined per role:
250
+
251
+ ```typescript
252
+ .win_conditions((variables, { attacker, defender }) => ({
253
+ [attacker]: variables.kills.greaterOrEqualThan(5),
254
+ [defender]: variables.survived.equalTo(1),
255
+ }))
256
+ ```
257
+
258
+ ## Actions
259
+
260
+ Actions are higher-level functions that wrap common Minecraft operations, designed to work seamlessly with Kradle's challenge system. They handle target mapping, formatting, and integration with Kradle's interface automatically.
261
+
262
+ For more advanced use cases, you can always fall back to Sandstone's lower-level functions directly (e.g., `give`, `tellraw`, `effect`, `kill`, `execute`). See the [Sandstone Integration](#sandstone-integration) section below.
263
+
264
+ ### Communication
265
+ ```typescript
266
+ // Simple string message
267
+ Actions.announce({ message: "Hello everyone!" });
268
+
269
+ // Formatted JSONTextComponent message
270
+ Actions.announce({
271
+ message: [
272
+ { text: "Player ", color: "white" },
273
+ { selector: "@s", color: "gold", bold: true },
274
+ { text: " scored!", color: "green" }
275
+ ]
276
+ });
277
+
278
+ // Send to specific target (only visible in-game, not in Kradle's interface)
279
+ Actions.tellraw({ target: "all", message: ["Hello ", { text: "world", color: "gold" }] });
280
+ Actions.tellraw({ target: "self", message: { text: "You win!", color: "green", bold: true } });
281
+ ```
282
+
283
+ ### Items & Inventory
284
+ ```typescript
285
+ Actions.give({ target: "self", item: "minecraft:diamond_sword", count: 1 });
286
+ Actions.giveLoot({
287
+ target: "self",
288
+ items: [
289
+ { name: "minecraft:diamond", count: 5, weight: 1 },
290
+ { name: "minecraft:iron_ingot", count: 10, weight: 3 }
291
+ ]
292
+ });
293
+ Actions.clear({ target: "self" });
294
+
295
+ // Count items - returns a Score variable
296
+ const count = Actions.countItems({ target: "self", item: "minecraft:diamond" });
297
+ // Use in conditions or set to custom variables
298
+ _.if(count.greaterThan(5), () => { /* ... */ });
299
+
300
+ // Get player position - returns { x, y, z } Score variables
301
+ const pos = Actions.getCurrentPlayerPosition();
302
+ _.if(pos.y.greaterThan(100), () => { /* player is high up */ });
303
+ ```
304
+
305
+ ### Entities
306
+ ```typescript
307
+ Actions.summonMultiple({ entity: "minecraft:zombie", count: 5, x: 0, y: 64, z: 0, absolute: true });
308
+ Actions.kill({ selector: Selector("@e", { type: "minecraft:zombie" }) });
309
+ Actions.teleport({ target: "self", x: 0, y: 100, z: 0, absolute: true });
310
+ ```
311
+
312
+ ### World
313
+ ```typescript
314
+ Actions.setBlock({ block: "minecraft:diamond_block", x: 0, y: 64, z: 0, absolute: true });
315
+ Actions.fill({
316
+ block: "minecraft:stone",
317
+ x1: 0, y1: 64, z1: 0,
318
+ x2: 10, y2: 64, z2: 10,
319
+ absolute: true,
320
+ mode: "fill" // "fill", "line", or "pyramid"
321
+ });
322
+ Actions.setTime({ time: "day" }); // or "night" or specific tick value
323
+ Actions.gamerule({ rule: "doDaylightCycle", value: false });
324
+ ```
325
+
326
+ ### Scores
327
+ ```typescript
328
+ Actions.set({ variable: variables.main_score, value: 10 });
329
+ Actions.set({ variable: variables.main_score, value: variables.diamonds });
330
+ Actions.increment({ variable: variables.counter });
331
+ Actions.decrement({ variable: variables.counter });
332
+ ```
333
+
334
+ ### Player Attributes
335
+ ```typescript
336
+ Actions.setAttribute({ target: "self", attribute_: "generic.max_health", value: 40 });
337
+ Actions.setAttribute({ target: "self", attribute_: "generic.movement_speed", value: 0.2 });
338
+ ```
339
+
340
+ ### Custom Commands
341
+ ```typescript
342
+ Actions.custom(() => {
343
+ // Any Sandstone code here
344
+ execute.as("@a").run.effect.give("@s", "speed", 10, 1);
345
+ });
346
+ ```
347
+
348
+ ## Utilities
349
+
350
+ ### `forEveryPlayer(callback)`
351
+
352
+ Execute code for each participant at their location:
353
+
354
+ ```typescript
355
+ import { forEveryPlayer } from "@kradle/challenges-sdk";
356
+
357
+ forEveryPlayer(() => {
358
+ // Runs as each player, at their position
359
+ execute.run.particle("minecraft:flame", rel(0, 1, 0));
360
+ });
361
+ ```
362
+
363
+ ## Example: Battle Royale
364
+
365
+ ```typescript
366
+ import { createChallenge, Actions, forEveryPlayer } from "@kradle/challenges-sdk";
367
+ import { _, Selector } from "sandstone";
368
+
369
+ createChallenge({
370
+ name: "battle-royale",
371
+ kradle_challenge_path: "./output",
372
+ roles: ["fighter"] as const,
373
+ GAME_DURATION: 5 * 60 * 20,
374
+ custom_variables: {
375
+ kills: {
376
+ type: "individual",
377
+ objective_type: "playerKillCount",
378
+ default: 0,
379
+ },
380
+ sole_survivor: {
381
+ type: "individual",
382
+ updater: (value, { alive_players, has_never_died }) => {
383
+ value.set(0);
384
+ _.if(_.and(
385
+ alive_players.equalTo(1),
386
+ has_never_died.equalTo(1)
387
+ ), () => {
388
+ value.set(1);
389
+ });
390
+ },
391
+ },
392
+ },
393
+ })
394
+ .events(() => ({
395
+ start_challenge: () => {
396
+ Actions.setTime({ time: "day" });
397
+ Actions.announce({ message: "Last player standing wins!" });
398
+ },
399
+ init_participants: () => {
400
+ Actions.give({ target: "all", item: "minecraft:stone_sword", count: 1 });
401
+ Actions.give({ target: "all", item: "minecraft:leather_chestplate", count: 1 });
402
+ },
403
+ }))
404
+ .custom_events(({ kills }) => [
405
+ {
406
+ score: kills,
407
+ target: 1,
408
+ mode: "fire_once",
409
+ actions: () => {
410
+ Actions.announce({ message: "First blood!" });
411
+ },
412
+ },
413
+ ])
414
+ .end_condition(({ alive_players }) => alive_players.equalTo(1))
415
+ .win_conditions(({ sole_survivor }, { fighter }) => ({
416
+ [fighter]: sole_survivor.equalTo(1),
417
+ }));
418
+ ```
419
+
420
+ ## Example: Capture the Flag
421
+
422
+ ```typescript
423
+ import { createChallenge, Actions } from "@kradle/challenges-sdk";
424
+ import { _, Selector, rel } from "sandstone";
425
+ import type { Score } from "sandstone";
426
+
427
+ createChallenge({
428
+ name: "capture-the-flag",
429
+ kradle_challenge_path: "./output",
430
+ roles: ["red_team", "blue_team"] as const,
431
+ GAME_DURATION: 5 * 60 * 20,
432
+ custom_variables: {
433
+ holds_enemy_flag: {
434
+ type: "individual",
435
+ updater: (value: Score) => {
436
+ value.set(0);
437
+ // Check if player holds the enemy team's banner
438
+ _.if(Selector("@s", {
439
+ nbt: { Inventory: [{ id: "minecraft:red_banner" }] }
440
+ }), () => {
441
+ value.set(1);
442
+ });
443
+ },
444
+ },
445
+ at_home_base: {
446
+ type: "individual",
447
+ updater: (value: Score) => {
448
+ value.set(0);
449
+ _.if(_.block(rel(0, -1, 0), "minecraft:blue_wool"), () => {
450
+ value.set(1);
451
+ });
452
+ },
453
+ },
454
+ captured_flag: {
455
+ type: "individual",
456
+ updater: (value, { holds_enemy_flag, at_home_base }) => {
457
+ value.set(0);
458
+ _.if(_.and(
459
+ holds_enemy_flag.equalTo(1),
460
+ at_home_base.equalTo(1)
461
+ ), () => {
462
+ value.set(1);
463
+ });
464
+ },
465
+ },
466
+ },
467
+ })
468
+ .events(() => ({
469
+ start_challenge: () => {
470
+ Actions.announce({ message: "Capture the enemy flag!" });
471
+ },
472
+ }))
473
+ .custom_events(({ captured_flag }) => [
474
+ {
475
+ score: captured_flag,
476
+ target: 1,
477
+ mode: "fire_once",
478
+ actions: () => {
479
+ Actions.announce({ message: "Flag captured!" });
480
+ },
481
+ },
482
+ ])
483
+ .end_condition(({ captured_flag }) => captured_flag.equalTo(1))
484
+ .win_conditions(({ captured_flag }, { red_team, blue_team }) => ({
485
+ [red_team]: captured_flag.equalTo(1),
486
+ [blue_team]: captured_flag.equalTo(0),
487
+ }));
488
+ ```
489
+
@@ -0,0 +1,230 @@
1
+ import { type GAMERULES, type JSONTextComponent, type Score, SelectorClass } from "sandstone";
2
+ import type { ATTRIBUTES, BLOCKS, ENTITY_TYPES, ITEMS } from "sandstone/arguments/generated";
3
+ import type { LiteralStringUnion } from "./utils";
4
+ export type TargetNames = LiteralStringUnion<"all" | "self"> | SelectorClass<any, any>;
5
+ export declare function mapTarget(target: string | SelectorClass): SelectorClass<any, any> | string;
6
+ export declare const Actions: {
7
+ /**
8
+ * Send a chat message to everyone.
9
+ * @param {JSONTextComponent} message - The message to send.
10
+ */
11
+ announce: ({ message }: {
12
+ message: JSONTextComponent;
13
+ }) => void;
14
+ /**
15
+ * Clear the inventory of a target.
16
+ * @param {TargetNames} target - The target to clear the inventory of.
17
+ */
18
+ clear: ({ target }: {
19
+ target: TargetNames;
20
+ }) => void;
21
+ /**
22
+ * Custom action allowing to run any Sandstone command.
23
+ *
24
+ * @param {() => void} callback - The function to execute.
25
+ */
26
+ custom: (callback: () => void) => void;
27
+ /**
28
+ * Fill a region with a block.
29
+ * @param {BLOCKS} block - The block to fill the region with.
30
+ * @param {number} x1 - The x coordinate of the region.
31
+ * @param {number} y1 - The y coordinate of the region.
32
+ * @param {number} z1 - The z coordinate of the region.
33
+ * @param {number} x2 - The x coordinate of the region.
34
+ * @param {number} y2 - The y coordinate of the region.
35
+ * @param {number} z2 - The z coordinate of the region.
36
+ * @param {boolean} absolute - Whether the coordinates are absolute or relative.
37
+ */
38
+ fill: ({ block, x1, y1, z1, x2, y2, z2, absolute, mode, }: {
39
+ block: BLOCKS;
40
+ x1: number;
41
+ y1: number;
42
+ z1: number;
43
+ x2: number;
44
+ y2: number;
45
+ z2: number;
46
+ absolute: boolean;
47
+ mode: "fill" | "line" | "pyramid";
48
+ }) => void;
49
+ /**
50
+ * Give an item to a target.
51
+ * @param {ITEMS} item - The item to give.
52
+ * @param {TargetNames} target - The target to give the item to.
53
+ * @param {number} count - The number of items to give.
54
+ */
55
+ give: ({ item, target, count }: {
56
+ item: ITEMS;
57
+ target: TargetNames;
58
+ count?: number;
59
+ }) => void;
60
+ /**
61
+ * Give loot to a target with a weighted chance for selecting one of the items.
62
+ * @param {{ name: ITEMS, count: number, weight: number }[]} items - The items to give.
63
+ * @param {TargetNames} target - The target to give the item to.
64
+ */
65
+ giveLoot: ({ items, target }: {
66
+ items: [{
67
+ name: ITEMS;
68
+ count: number;
69
+ weight: number;
70
+ }];
71
+ target: TargetNames;
72
+ }) => void;
73
+ /**
74
+ * Set a gamerule.
75
+ * @param {GAMERULES} rule - The name of the gamerule.
76
+ * @param {boolean | number} value - The value to set the gamerule to.
77
+ */
78
+ gamerule: ({ rule, value }: {
79
+ rule: GAMERULES;
80
+ value: boolean | number;
81
+ }) => void;
82
+ /**
83
+ * Kill entities matching a selector.
84
+ * @param {SelectorArgument} selector - The entities to kill.
85
+ */
86
+ kill: ({ selector }: {
87
+ selector: TargetNames;
88
+ }) => void;
89
+ /**
90
+ * Set an attribute for a target.
91
+ * @param {ATTRIBUTES} attribute_ - The attribute to set.
92
+ * @param {number} value - The value to set the attribute to.
93
+ * @param {TargetNames} target - The target to set the attribute for.
94
+ */
95
+ setAttribute: ({ attribute_, value, target }: {
96
+ attribute_: ATTRIBUTES;
97
+ value: number;
98
+ target: TargetNames;
99
+ }) => void;
100
+ /**
101
+ * Set the time of day.
102
+ * @param {'day' | 'night'} time_ - The time to set.
103
+ */
104
+ setTime: ({ time }: {
105
+ time: "day" | "night";
106
+ }) => void;
107
+ /**
108
+ * Summon multiple entities at a specific location.
109
+ */
110
+ summonMultiple: (params: {
111
+ entity: ENTITY_TYPES;
112
+ count: number;
113
+ x: number;
114
+ y: number;
115
+ z: number;
116
+ absolute: boolean;
117
+ }) => void;
118
+ /**
119
+ * Set the end state of the challenge.
120
+ * @param {string} end_state - The end state to set.
121
+ */
122
+ setEndState: ({ endState }: {
123
+ endState: string;
124
+ }) => void;
125
+ /**
126
+ * Set a block at a specific location.
127
+ */
128
+ setBlock: (params: {
129
+ block: BLOCKS;
130
+ x: number;
131
+ y: number;
132
+ z: number;
133
+ absolute: boolean;
134
+ }) => void;
135
+ /**
136
+ * Teleport entities to a specific location.
137
+ * @param {TargetNames} target - The entities to teleport.
138
+ * @param {number} x - The x coordinate of the destination.
139
+ * @param {number} y - The y coordinate of the destination.
140
+ * @param {number} z - The z coordinate of the destination.
141
+ * @param {boolean} absolute - Whether the coordinates are absolute or relative.
142
+ */
143
+ teleport: ({ target, x, y, z, absolute, }: {
144
+ target: TargetNames;
145
+ x: number;
146
+ y: number;
147
+ z: number;
148
+ absolute: boolean;
149
+ }) => void;
150
+ /**
151
+ * Send a chat message to a target.
152
+ * @param {JSONTextComponent} message - The message to send.
153
+ * @param {TargetNames} target - The target to send the message to.
154
+ */
155
+ tellraw: ({ message, target }: {
156
+ message: JSONTextComponent;
157
+ target: TargetNames;
158
+ }) => void;
159
+ /**
160
+ * Increment a score variable by 1.
161
+ * @param variable - The score variable to increment.
162
+ */
163
+ increment: ({ variable }: {
164
+ variable: Score;
165
+ }) => void;
166
+ /**
167
+ * Decrement a score variable by 1.
168
+ * @param variable - The score variable to decrement.
169
+ */
170
+ decrement: ({ variable }: {
171
+ variable: Score;
172
+ }) => void;
173
+ /**
174
+ * Set a score variable to a specific value.
175
+ * @param variable - The score variable to set.
176
+ * @param value - The value to set the score variable to, which can be a number or another score variable.
177
+ */
178
+ set: ({ variable, value }: {
179
+ variable: Score;
180
+ value: number | Score;
181
+ }) => void;
182
+ /**
183
+ * log a message with the watcher
184
+ * @param {string} message - The message to send.
185
+ * @param {Score} variable - The variable to log.
186
+ * @param {boolean} store - Whether to store the variable in the backend.
187
+ */
188
+ log_variable: ({ message, variable, store }: {
189
+ message: string;
190
+ variable: Score;
191
+ store: boolean;
192
+ }) => void;
193
+ /**
194
+ * Summon an item at a specific location.
195
+ * @param {ITEMS} item - The item to summon.
196
+ * @param {number} x - The x coordinate of the location.
197
+ * @param {number} y - The y coordinate of the location.
198
+ * @param {number} z - The z coordinate of the location.
199
+ * @param {boolean} absolute - Whether the coordinates are absolute or relative.
200
+ */
201
+ summonItem: ({ item, x, y, z, absolute }: {
202
+ item: ITEMS;
203
+ x: number;
204
+ y: number;
205
+ z: number;
206
+ absolute: boolean;
207
+ }) => void;
208
+ /**
209
+ * Count the number of a specific item in a target's inventory.
210
+ * @param params - The parameters object.
211
+ * @param params.target - The target to count items for.
212
+ * @param params.item - The item to count.
213
+ * @returns The variable containing the item count.
214
+ */
215
+ countItems: ({ target, item }: {
216
+ target: TargetNames;
217
+ item: ITEMS;
218
+ }) => Score<string | undefined>;
219
+ /**
220
+ * Get the current player's position as x, y, z Score variables.
221
+ * Must be called in a player context (e.g., inside forEveryPlayer or when @s is a player).
222
+ * @returns An object with x, y, z Score variables containing the player's coordinates.
223
+ */
224
+ getCurrentPlayerPosition: () => {
225
+ x: Score<string | undefined>;
226
+ y: Score<string | undefined>;
227
+ z: Score<string | undefined>;
228
+ };
229
+ };
230
+ //# sourceMappingURL=actions.d.ts.map