@kradle/challenges-sdk 0.5.2 → 0.6.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/LLM_README.md +594 -40
- package/README.md +62 -4
- package/dist/actions.d.ts +562 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +679 -3
- package/dist/actions.js.map +1 -1
- package/dist/api_utils.d.ts +20 -0
- package/dist/api_utils.d.ts.map +1 -1
- package/dist/api_utils.js +36 -1
- package/dist/api_utils.js.map +1 -1
- package/dist/challenge.d.ts +1 -0
- package/dist/challenge.d.ts.map +1 -1
- package/dist/challenge.js +68 -25
- package/dist/challenge.js.map +1 -1
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +29 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ If you still want to perform a manual installation, you also need to install the
|
|
|
13
13
|
npm install @kradle/challenges-sdk sandstone@0.14.0-alpha.13
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
Add `"type": "module"` to your project's `package.json`. Challenge files use ES module syntax (`import …`) and Node otherwise reparses them as ES modules at every CI run with a `MODULE_TYPELESS_PACKAGE_JSON` warning + per-file overhead.
|
|
17
|
+
|
|
16
18
|
## Quick Start
|
|
17
19
|
|
|
18
20
|
Like for installation, we strongly recommend using Kradle's CLI to bootstrap a challenge:
|
|
@@ -22,6 +24,31 @@ Like for installation, we strongly recommend using Kradle's CLI to bootstrap a c
|
|
|
22
24
|
kradle challenge create my-challenge
|
|
23
25
|
```
|
|
24
26
|
|
|
27
|
+
## Local Development
|
|
28
|
+
|
|
29
|
+
Working on the SDK locally and want to test against a real challenge project (e.g. `team-kradle-challenges`)?
|
|
30
|
+
|
|
31
|
+
**Use `npm pack` + tarball install — not `npm link`.**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# 1. In the SDK repo
|
|
35
|
+
npm run build
|
|
36
|
+
npm pack # produces kradle-challenges-sdk-<version>.tgz
|
|
37
|
+
|
|
38
|
+
# 2. In the consumer project
|
|
39
|
+
npm install /absolute/path/to/kradle-challenges-sdk-<version>.tgz
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
After every SDK change, repeat both steps (a one-line script is fine).
|
|
43
|
+
|
|
44
|
+
### Why not `npm link`?
|
|
45
|
+
|
|
46
|
+
`sandstone` is a peer dependency. `npm link` keeps the SDK's own `node_modules` in play, so the SDK ends up resolving `sandstone` from one location while the consumer resolves it from another. You end up with **two `sandstone` instances loaded in the same process**, which produces some confusing failure modes:
|
|
47
|
+
|
|
48
|
+
- `instanceof SelectorClass` returns `false` for selectors created by the consumer (they're instances of the *other* `SelectorClass`).
|
|
49
|
+
- The runtime `Flow` registry gets split, so `_.if(...)` calls inside `forEveryPlayer` throw `Entering child function without registering a root function`.
|
|
50
|
+
|
|
51
|
+
`npm pack` + install gives the consumer a single flat `sandstone` install, which is what production users get. No duplication, no `instanceof` surprises, no flow-registry split.
|
|
25
52
|
|
|
26
53
|
## API Overview
|
|
27
54
|
|
|
@@ -46,12 +73,14 @@ The challenge builder uses a fluent API:
|
|
|
46
73
|
|
|
47
74
|
```typescript
|
|
48
75
|
createChallenge(config)
|
|
49
|
-
.events(callback)
|
|
50
|
-
.custom_events(callback)
|
|
51
|
-
.end_condition(callback)
|
|
52
|
-
.win_conditions(callback)
|
|
76
|
+
.events(callback) // Lifecycle events; call Actions.setEndStates from on_tick
|
|
77
|
+
.custom_events(callback) // OPTIONAL — score-threshold side effects (announce, sound, etc.)
|
|
78
|
+
.end_condition(callback) // OPTIONAL — when the game should end (auto-includes GAME_DURATION timer)
|
|
79
|
+
.win_conditions(callback) // Per-role win conditions
|
|
53
80
|
```
|
|
54
81
|
|
|
82
|
+
> For the standard "win / loss / timeout" pattern, call `Actions.setEndStates({ ... })` from inside `events.on_tick` and feed its return value into `.end_condition()` so the game ends as soon as any end-state fires. See the API reference for the full signature.
|
|
83
|
+
|
|
55
84
|
## Variables
|
|
56
85
|
|
|
57
86
|
Variables are the core mechanism for tracking game state. All variables are automatically updated each tick.
|
|
@@ -291,6 +320,7 @@ Actions.giveLoot({
|
|
|
291
320
|
{ name: "minecraft:iron_ingot", count: 10, weight: 3 }
|
|
292
321
|
]
|
|
293
322
|
});
|
|
323
|
+
|
|
294
324
|
Actions.clear({ target: "self" });
|
|
295
325
|
|
|
296
326
|
// Count items - returns a Score variable
|
|
@@ -314,6 +344,34 @@ const spawn = Actions.getLocation({ name: "spawn" });
|
|
|
314
344
|
Actions.teleport({ target: "all", toEntity: spawn });
|
|
315
345
|
```
|
|
316
346
|
|
|
347
|
+
### Selectors
|
|
348
|
+
```typescript
|
|
349
|
+
// "Is @s standing on the block at (x, y, z)?" — returns a Selector usable
|
|
350
|
+
// inside _.if(...). Use this instead of Selector("@s", { x, y, z }) which
|
|
351
|
+
// silently passes for everyone (Minecraft selector x/y/z without dx/dy/dz
|
|
352
|
+
// is the origin for distance math, not a position constraint).
|
|
353
|
+
_.if(Actions.standingOnBlock({ x: PAD.x, y: PAD.y, z: PAD.z, role: "alice" }), () => {
|
|
354
|
+
// Alice is on the pad above (PAD.x, PAD.y, PAD.z). Run trigger logic here.
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Cross-player score aggregation
|
|
359
|
+
```typescript
|
|
360
|
+
// Compute the maximum across all players' per-player scores. Returns an
|
|
361
|
+
// anonymous Score the caller can write into a global custom_variable.
|
|
362
|
+
// Lets `Actions.setEndStates` / `.end_condition` reference "any player has X"
|
|
363
|
+
// semantics correctly (those checks run as the server entity, so per-player
|
|
364
|
+
// scores read 0 there).
|
|
365
|
+
max_score: {
|
|
366
|
+
type: "global",
|
|
367
|
+
default: 0,
|
|
368
|
+
updater: (value, { score }) => {
|
|
369
|
+
value.set(Actions.maxPlayerScore({ score }));
|
|
370
|
+
// Pass `min: -1000` if your per-player score can go below 0.
|
|
371
|
+
},
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
317
375
|
### Locations
|
|
318
376
|
```typescript
|
|
319
377
|
// Get a location marker by name (must be defined in config.ts locations)
|