@kradle/challenges-sdk 0.23.0 → 0.24.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/CHANGELOG.md +22 -1
- package/LLM_README.md +34 -11
- package/README.md +14 -0
- package/dist/engine.d.ts +2 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +4 -1
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/builder.d.ts.map +1 -1
- package/dist/runtime/builder.js +25 -6
- package/dist/runtime/builder.js.map +1 -1
- package/dist/runtime/dimensions.d.ts +24 -0
- package/dist/runtime/dimensions.d.ts.map +1 -0
- package/dist/runtime/dimensions.js +47 -0
- package/dist/runtime/dimensions.js.map +1 -0
- package/dist/runtime/reducer.d.ts.map +1 -1
- package/dist/runtime/reducer.js +65 -28
- package/dist/runtime/reducer.js.map +1 -1
- package/dist/runtime/types.d.ts +22 -4
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/wire.d.ts +20 -1
- package/dist/runtime/wire.d.ts.map +1 -1
- package/dist/runtime/wire.js +1 -0
- package/dist/runtime/wire.js.map +1 -1
- package/dist/runtime/world.d.ts +13 -4
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +40 -25
- package/dist/runtime/world.js.map +1 -1
- package/dist/structures.d.ts.map +1 -1
- package/dist/structures.js +3 -1
- package/dist/structures.js.map +1 -1
- package/dist/test/harness.d.ts +3 -2
- package/dist/test/harness.d.ts.map +1 -1
- package/dist/test/harness.js +18 -10
- package/dist/test/harness.js.map +1 -1
- package/dist/test/helpers.d.ts.map +1 -1
- package/dist/test/helpers.js +2 -1
- package/dist/test/helpers.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/reducer.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_ACHIEVEMENTS = exports.MAX_TRANSITIONS_PER_EVENT = exports.MAX_FILL_VOLUME = exports.MAX_BATCH_EFFECTS = void 0;
|
|
4
|
+
exports.assertJson = assertJson;
|
|
5
|
+
exports.parseBlockState = parseBlockState;
|
|
6
|
+
exports.blockSpecString = blockSpecString;
|
|
7
|
+
exports.splitBatches = splitBatches;
|
|
8
|
+
exports.createReducer = createReducer;
|
|
9
|
+
const dimensions_js_1 = require("./dimensions.js");
|
|
2
10
|
// The reducer: one locked definition, one `init()` per run, one `reduce(state,
|
|
3
11
|
// event)` per engine event. Everything a rule sees comes through a context
|
|
4
12
|
// built for the reduction; everything a rule asks for leaves as actions.
|
|
@@ -15,15 +23,8 @@
|
|
|
15
23
|
// the game-over hook, the judge data, `game_over`.
|
|
16
24
|
// - An author error rolls the reduction back and ends the run as
|
|
17
25
|
// `error_challenge` without another author callback.
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.MAX_ACHIEVEMENTS = exports.MAX_TRANSITIONS_PER_EVENT = exports.MAX_FILL_VOLUME = exports.MAX_BATCH_EFFECTS = void 0;
|
|
20
|
-
exports.assertJson = assertJson;
|
|
21
|
-
exports.parseBlockState = parseBlockState;
|
|
22
|
-
exports.blockSpecString = blockSpecString;
|
|
23
|
-
exports.splitBatches = splitBatches;
|
|
24
|
-
exports.createReducer = createReducer;
|
|
25
|
-
const dialog_js_1 = require("./dialog.js");
|
|
26
26
|
const chat_js_1 = require("./chat.js");
|
|
27
|
+
const dialog_js_1 = require("./dialog.js");
|
|
27
28
|
const errors_js_1 = require("./errors.js");
|
|
28
29
|
const time_js_1 = require("./time.js");
|
|
29
30
|
const types_js_1 = require("./types.js");
|
|
@@ -103,7 +104,7 @@ function deepFreeze(value, seen = new WeakSet()) {
|
|
|
103
104
|
for (const x of Object.values(value))
|
|
104
105
|
deepFreeze(x, seen);
|
|
105
106
|
}
|
|
106
|
-
const posKey =
|
|
107
|
+
const posKey = dimensions_js_1.positionKey;
|
|
107
108
|
/** `minecraft:oak_stairs[facing=east,half=bottom]` -> `{ id, props }`. */
|
|
108
109
|
function parseBlockState(state) {
|
|
109
110
|
const i = state.indexOf("[");
|
|
@@ -338,6 +339,7 @@ function viewOf(r, p) {
|
|
|
338
339
|
}
|
|
339
340
|
function createReducer(def) {
|
|
340
341
|
const config = def.config;
|
|
342
|
+
const dimensions = (0, dimensions_js_1.enabledDimensions)(config.challengeConfig?.dimensions);
|
|
341
343
|
const roleNames = Object.keys(config.roles);
|
|
342
344
|
const declaredZones = Object.keys(def.zones);
|
|
343
345
|
const derivedScores = def.outcome.scores !== undefined;
|
|
@@ -488,6 +490,21 @@ function createReducer(def) {
|
|
|
488
490
|
}
|
|
489
491
|
};
|
|
490
492
|
const push = (raw) => {
|
|
493
|
+
for (const value of [
|
|
494
|
+
raw,
|
|
495
|
+
...["at", "from", "to", "dest"].map((key) => raw[key]),
|
|
496
|
+
]) {
|
|
497
|
+
if (value &&
|
|
498
|
+
typeof value === "object" &&
|
|
499
|
+
"dimension" in value &&
|
|
500
|
+
value.dimension !== undefined &&
|
|
501
|
+
!dimensions.includes(value.dimension))
|
|
502
|
+
throw (0, errors_js_1.apiError)("invalid_value", "The target dimension is disabled");
|
|
503
|
+
}
|
|
504
|
+
if (raw.kind === "fill" || raw.kind === "clone")
|
|
505
|
+
(0, world_js_1.bounds)({ from: raw.from, to: raw.to });
|
|
506
|
+
if (raw.kind === "clone" && (0, dimensions_js_1.dimensionOf)(raw.from) !== (0, dimensions_js_1.dimensionOf)(raw.dest))
|
|
507
|
+
throw (0, errors_js_1.apiError)("invalid_value", "A clone cannot cross dimensions");
|
|
491
508
|
// A plain copy: an author's argument may be a view (`p.pos`, `g.params.box`).
|
|
492
509
|
const effect = compact(snapshot(raw));
|
|
493
510
|
if (r.batch)
|
|
@@ -580,6 +597,7 @@ function createReducer(def) {
|
|
|
580
597
|
throw (0, errors_js_1.notDeclared)("zones", zone, declaredZones);
|
|
581
598
|
return p.zones.includes(zone);
|
|
582
599
|
}
|
|
600
|
+
(0, world_js_1.bounds)(zone);
|
|
583
601
|
return p.pos !== null && (0, world_js_1.inBox)(p.pos, zone);
|
|
584
602
|
},
|
|
585
603
|
countItems(p, match) {
|
|
@@ -617,6 +635,7 @@ function createReducer(def) {
|
|
|
617
635
|
get worldTime() {
|
|
618
636
|
return s.world.time;
|
|
619
637
|
},
|
|
638
|
+
dimensionTime: (dimension) => (dimension === dimensions_js_1.OVERWORLD ? s.world.time : s.world.times?.[dimension]),
|
|
620
639
|
entities: (filter) => (0, world_js_1.entitiesIn)(s.world, filter).map(world_js_1.freezeObservation),
|
|
621
640
|
entity(id) {
|
|
622
641
|
const e = s.world.entities[id];
|
|
@@ -826,17 +845,17 @@ function createReducer(def) {
|
|
|
826
845
|
write("summon");
|
|
827
846
|
push({ kind: "summon", entity, at: { ...at }, nbt: opts?.nbt });
|
|
828
847
|
},
|
|
829
|
-
killEntities(entities) {
|
|
848
|
+
killEntities(entities, dimension) {
|
|
830
849
|
write("killEntities");
|
|
831
|
-
push({ kind: "kill_entities", entities });
|
|
850
|
+
push({ kind: "kill_entities", entities, dimension });
|
|
832
851
|
},
|
|
833
|
-
time(value) {
|
|
852
|
+
time(value, dimension) {
|
|
834
853
|
write("time");
|
|
835
|
-
push({ kind: "time", value });
|
|
854
|
+
push({ kind: "time", value, dimension });
|
|
836
855
|
},
|
|
837
|
-
gamerule(rule, value) {
|
|
856
|
+
gamerule(rule, value, dimension) {
|
|
838
857
|
write("gamerule");
|
|
839
|
-
push({ kind: "gamerule", rule, value });
|
|
858
|
+
push({ kind: "gamerule", rule, value, dimension });
|
|
840
859
|
},
|
|
841
860
|
setSpawn(at) {
|
|
842
861
|
write("setSpawn");
|
|
@@ -846,6 +865,7 @@ function createReducer(def) {
|
|
|
846
865
|
write("worldBorder");
|
|
847
866
|
push({
|
|
848
867
|
kind: "worldborder",
|
|
868
|
+
dimension: opts.dimension,
|
|
849
869
|
center: opts.center,
|
|
850
870
|
size: opts.size,
|
|
851
871
|
seconds: opts.over === undefined ? undefined : (0, time_js_1.toTicks)(opts.over) / 20,
|
|
@@ -866,11 +886,11 @@ function createReducer(def) {
|
|
|
866
886
|
}));
|
|
867
887
|
push({ kind: "container", at: { ...at }, items: out });
|
|
868
888
|
},
|
|
869
|
-
command(cmd, name) {
|
|
889
|
+
command(cmd, name, dimension) {
|
|
870
890
|
write("command");
|
|
871
891
|
r.actions.push({ type: "log", message: `raw command: ${cmd}` });
|
|
872
892
|
if (name === undefined) {
|
|
873
|
-
push({ kind: "command", cmd });
|
|
893
|
+
push({ kind: "command", cmd, dimension });
|
|
874
894
|
return;
|
|
875
895
|
}
|
|
876
896
|
if (typeof name !== "string")
|
|
@@ -879,7 +899,7 @@ function createReducer(def) {
|
|
|
879
899
|
throw (0, errors_js_1.apiError)("lifecycle", `command("${cmd}", "${name}"): a result needs a running game, not .setup (status ${s.status})`);
|
|
880
900
|
const id = `cmd:${s.nextId++}`;
|
|
881
901
|
s.commands[id] = { name };
|
|
882
|
-
push({ kind: "command", cmd, id });
|
|
902
|
+
push({ kind: "command", cmd, id, dimension });
|
|
883
903
|
},
|
|
884
904
|
// ---- flow
|
|
885
905
|
startPhase(name) {
|
|
@@ -1283,11 +1303,19 @@ function createReducer(def) {
|
|
|
1283
1303
|
const out = [];
|
|
1284
1304
|
if (w.spawn)
|
|
1285
1305
|
out.push({ kind: "spawn", at: { ...w.spawn } });
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1306
|
+
for (const dimension of dimensions) {
|
|
1307
|
+
const scope = dimension === dimensions_js_1.OVERWORLD ? {} : { dimension };
|
|
1308
|
+
if (w.time !== false)
|
|
1309
|
+
out.push({ kind: "time", value: w.time, ...scope });
|
|
1310
|
+
out.push({ kind: "gamerule", rule: "minecraft:advance_time", value: w.daylightCycle, ...scope });
|
|
1311
|
+
out.push({ kind: "gamerule", rule: "minecraft:spawn_mobs", value: w.mobSpawning, ...scope });
|
|
1312
|
+
out.push({
|
|
1313
|
+
kind: "gamerule",
|
|
1314
|
+
rule: "minecraft:natural_health_regeneration",
|
|
1315
|
+
value: w.naturalRegeneration,
|
|
1316
|
+
...scope,
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1291
1319
|
return out;
|
|
1292
1320
|
}
|
|
1293
1321
|
function worldPlayers(s) {
|
|
@@ -1665,6 +1693,8 @@ function createReducer(def) {
|
|
|
1665
1693
|
if (r.s.status !== "PLAYING")
|
|
1666
1694
|
return;
|
|
1667
1695
|
for (const { m, before, after } of edges) {
|
|
1696
|
+
if ((0, dimensions_js_1.dimensionOf)(m.from) !== (0, dimensions_js_1.dimensionOf)(m.to))
|
|
1697
|
+
fire(r, "dimensionChanged", { player: viewOf(r, m.p), from: m.from, to: { ...m.to } });
|
|
1668
1698
|
for (const zone of after)
|
|
1669
1699
|
if (!before.includes(zone))
|
|
1670
1700
|
fire(r, "zoneEntered", { player: viewOf(r, m.p), zone });
|
|
@@ -1789,6 +1819,8 @@ function createReducer(def) {
|
|
|
1789
1819
|
return;
|
|
1790
1820
|
}
|
|
1791
1821
|
const missing = missingCapabilities(e.capabilities);
|
|
1822
|
+
if (dimensions.length > 1 && !e.capabilities.includes("dimensions"))
|
|
1823
|
+
missing.push("dimensions");
|
|
1792
1824
|
if (def.setup && !e.capabilities.includes("batch"))
|
|
1793
1825
|
missing.push("batch");
|
|
1794
1826
|
if (missing.length > 0) {
|
|
@@ -1849,6 +1881,8 @@ function createReducer(def) {
|
|
|
1849
1881
|
delete s.dialogs[player];
|
|
1850
1882
|
r.actions.push({ type: "effect", effect: { kind: "clear_dialog", player } });
|
|
1851
1883
|
}
|
|
1884
|
+
if (e.times)
|
|
1885
|
+
s.world = { ...s.world, times: { ...s.world.times, ...e.times } };
|
|
1852
1886
|
if (e.entities)
|
|
1853
1887
|
s.world = (0, world_js_1.moveEntities)(s.world, e.entities);
|
|
1854
1888
|
if (e.time !== undefined && e.time !== s.world.time)
|
|
@@ -2127,11 +2161,10 @@ function createReducer(def) {
|
|
|
2127
2161
|
s.world = (0, world_js_1.applyChunk)(s.world, e);
|
|
2128
2162
|
break;
|
|
2129
2163
|
case "chunk_unloaded": {
|
|
2130
|
-
s.world = (0, world_js_1.removeChunk)(s.world, e.x, e.z);
|
|
2164
|
+
s.world = (0, world_js_1.removeChunk)(s.world, e.x, e.z, e.dimension);
|
|
2131
2165
|
// The containers of the chunk are unknown now.
|
|
2132
2166
|
for (const key of Object.keys(s.containers)) {
|
|
2133
|
-
|
|
2134
|
-
if (x >> 4 === e.x && z >> 4 === e.z)
|
|
2167
|
+
if ((0, dimensions_js_1.keyInChunk)(key, e.x, e.z, e.dimension))
|
|
2135
2168
|
delete s.containers[key];
|
|
2136
2169
|
}
|
|
2137
2170
|
break;
|
|
@@ -2141,6 +2174,7 @@ function createReducer(def) {
|
|
|
2141
2174
|
if (playing()) {
|
|
2142
2175
|
fire(r, "blocksChanged", () => ({
|
|
2143
2176
|
changes: e.changes.map((c) => compact({
|
|
2177
|
+
dimension: c.dimension,
|
|
2144
2178
|
x: c.x,
|
|
2145
2179
|
y: c.y,
|
|
2146
2180
|
z: c.z,
|
|
@@ -2165,10 +2199,13 @@ function createReducer(def) {
|
|
|
2165
2199
|
const from = { ...e.from };
|
|
2166
2200
|
const to = { ...e.to };
|
|
2167
2201
|
const { lo, hi } = (0, world_js_1.bounds)({ from, to });
|
|
2168
|
-
const dest = { x: Math.floor(e.dest.x), y: Math.floor(e.dest.y), z: Math.floor(e.dest.z) };
|
|
2202
|
+
const dest = { ...e.dest, x: Math.floor(e.dest.x), y: Math.floor(e.dest.y), z: Math.floor(e.dest.z) };
|
|
2169
2203
|
s.world = (0, world_js_1.cloneBlocks)(s.world, { from, to }, dest, e.mode);
|
|
2170
2204
|
if (playing()) {
|
|
2171
|
-
const box = {
|
|
2205
|
+
const box = {
|
|
2206
|
+
from: dest,
|
|
2207
|
+
to: { ...dest, x: dest.x + hi.x - lo.x, y: dest.y + hi.y - lo.y, z: dest.z + hi.z - lo.z },
|
|
2208
|
+
};
|
|
2172
2209
|
// A move clears the source first: an author who applies the entries in order gets the vanilla result on an overlap.
|
|
2173
2210
|
fire(r, "blocksChanged", {
|
|
2174
2211
|
changes: e.mode === "move"
|