@kradle/challenges-sdk 0.21.1 → 0.23.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 +38 -1
- package/LLM_README.md +138 -14
- package/README.md +108 -4
- package/dist/engine.d.ts +1 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/builder.d.ts.map +1 -1
- package/dist/runtime/builder.js +1 -0
- package/dist/runtime/builder.js.map +1 -1
- package/dist/runtime/dialog.d.ts +83 -0
- package/dist/runtime/dialog.d.ts.map +1 -0
- package/dist/runtime/dialog.js +95 -0
- package/dist/runtime/dialog.js.map +1 -0
- package/dist/runtime/reducer.d.ts +18 -1
- package/dist/runtime/reducer.d.ts.map +1 -1
- package/dist/runtime/reducer.js +153 -4
- package/dist/runtime/reducer.js.map +1 -1
- package/dist/runtime/types.d.ts +76 -5
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/wire.d.ts +64 -2
- package/dist/runtime/wire.d.ts.map +1 -1
- package/dist/runtime/wire.js +2 -0
- package/dist/runtime/wire.js.map +1 -1
- package/dist/runtime/world.d.ts +75 -1
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +253 -3
- package/dist/runtime/world.js.map +1 -1
- package/dist/test/harness.d.ts +24 -0
- package/dist/test/harness.d.ts.map +1 -1
- package/dist/test/harness.js +50 -2
- package/dist/test/harness.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Duration } from "./time.js";
|
|
2
|
+
/** A field in a native Minecraft dialog. */
|
|
3
|
+
export type DialogInput = {
|
|
4
|
+
/** The input key in the response. Use letters, digits, underscores, or hyphens. */
|
|
5
|
+
id: string;
|
|
6
|
+
/** The visible label. */
|
|
7
|
+
label: string;
|
|
8
|
+
} & DialogControl;
|
|
9
|
+
/** The native input control. */
|
|
10
|
+
type DialogControl =
|
|
11
|
+
/** A text field. */
|
|
12
|
+
{
|
|
13
|
+
/** A text field. */
|
|
14
|
+
type: "text";
|
|
15
|
+
/** The initial text; empty by default. */
|
|
16
|
+
initial?: string;
|
|
17
|
+
/** The maximum length, from 1 to 1024; 32 by default. */
|
|
18
|
+
maxLength?: number;
|
|
19
|
+
}
|
|
20
|
+
/** A checkbox. */
|
|
21
|
+
| {
|
|
22
|
+
/** A checkbox. */
|
|
23
|
+
type: "boolean";
|
|
24
|
+
/** The initial value; false by default. */
|
|
25
|
+
initial?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** An option list. */
|
|
28
|
+
| {
|
|
29
|
+
/** A list with one selected option. */
|
|
30
|
+
type: "singleOption";
|
|
31
|
+
/** The choices, from 1 to 32. */
|
|
32
|
+
options: {
|
|
33
|
+
/** The value in the response. */
|
|
34
|
+
id: string;
|
|
35
|
+
/** The visible text. */
|
|
36
|
+
label: string;
|
|
37
|
+
}[];
|
|
38
|
+
/** The initial option ID; the first option by default. */
|
|
39
|
+
initial?: string;
|
|
40
|
+
}
|
|
41
|
+
/** A number slider. */
|
|
42
|
+
| {
|
|
43
|
+
/** A number slider. */
|
|
44
|
+
type: "numberRange";
|
|
45
|
+
/** The minimum value. */
|
|
46
|
+
min: number;
|
|
47
|
+
/** The maximum value, greater than the minimum. */
|
|
48
|
+
max: number;
|
|
49
|
+
/** The initial value; the minimum by default. */
|
|
50
|
+
initial?: number;
|
|
51
|
+
/** The positive step size; continuous without it. */
|
|
52
|
+
step?: number;
|
|
53
|
+
};
|
|
54
|
+
/** A native Minecraft dialog with one response per display. */
|
|
55
|
+
export interface Dialog {
|
|
56
|
+
/** The dialog ID in the response. */
|
|
57
|
+
id: string;
|
|
58
|
+
/** The visible title, up to 256 characters. */
|
|
59
|
+
title: string;
|
|
60
|
+
/** Optional text below the title, up to 8192 characters. */
|
|
61
|
+
body?: string;
|
|
62
|
+
/** The input fields, at most 16. */
|
|
63
|
+
inputs?: DialogInput[];
|
|
64
|
+
/** The buttons, from 1 to 32. */
|
|
65
|
+
buttons: {
|
|
66
|
+
/** The button ID in the response. */
|
|
67
|
+
id: string;
|
|
68
|
+
/** The visible label. */
|
|
69
|
+
label: string;
|
|
70
|
+
}[];
|
|
71
|
+
/** The response window; 60 seconds by default, at most one hour. */
|
|
72
|
+
timeout?: Duration;
|
|
73
|
+
}
|
|
74
|
+
/** The values submitted through a native dialog. */
|
|
75
|
+
export type DialogValues = Record<string, string | boolean | number>;
|
|
76
|
+
/** A dialog without the author-facing duration. */
|
|
77
|
+
export type DialogSpec = Omit<Dialog, "timeout">;
|
|
78
|
+
/** Checks the author definition before the SDK sends it. */
|
|
79
|
+
export declare function validateDialog(value: unknown): asserts value is Dialog;
|
|
80
|
+
/** Checks the values before the SDK calls challenge code. */
|
|
81
|
+
export declare function validDialogValues(d: DialogSpec, values: unknown): values is DialogValues;
|
|
82
|
+
export {};
|
|
83
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/runtime/dialog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,4CAA4C;AAC5C,MAAM,MAAM,WAAW,GAAG;IACzB,mFAAmF;IACnF,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;CACd,GAAG,aAAa,CAAC;AAElB,gCAAgC;AAChC,KAAK,aAAa;AACjB,oBAAoB;AAClB;IACA,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CAClB;AACH,kBAAkB;GAChB;IACA,kBAAkB;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;CACjB;AACH,sBAAsB;GACpB;IACA,uCAAuC;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,iCAAiC;IACjC,OAAO,EAAE;QACR,iCAAiC;QACjC,EAAE,EAAE,MAAM,CAAC;QACX,wBAAwB;QACxB,KAAK,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;IACJ,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;CAChB;AACH,uBAAuB;GACrB;IACA,uBAAuB;IACvB,IAAI,EAAE,aAAa,CAAC;IACpB,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEL,+DAA+D;AAC/D,MAAM,WAAW,MAAM;IACtB,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,iCAAiC;IACjC,OAAO,EAAE;QACR,qCAAqC;QACrC,EAAE,EAAE,MAAM,CAAC;QACX,yBAAyB;QACzB,KAAK,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;IACJ,oEAAoE;IACpE,OAAO,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,oDAAoD;AACpD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAErE,mDAAmD;AACnD,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAOjD,4DAA4D;AAC5D,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CA0CtE;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,YAAY,CAkBxF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateDialog = validateDialog;
|
|
4
|
+
exports.validDialogValues = validDialogValues;
|
|
5
|
+
const errors_js_1 = require("./errors.js");
|
|
6
|
+
const id = (v) => typeof v === "string" && /^[a-zA-Z0-9_-]{1,64}$/.test(v);
|
|
7
|
+
const text = (v, max = 256) => typeof v === "string" && v.length <= max;
|
|
8
|
+
const finiteFloat = (v) => typeof v === "number" && Number.isFinite(Math.fround(v));
|
|
9
|
+
const object = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
10
|
+
/** Checks the author definition before the SDK sends it. */
|
|
11
|
+
function validateDialog(value) {
|
|
12
|
+
const fail = () => {
|
|
13
|
+
throw (0, errors_js_1.apiError)("bad_dialog", "dialog: invalid definition, IDs, or input limits");
|
|
14
|
+
};
|
|
15
|
+
if (!object(value) || !id(value.id) || !text(value.title) || (value.body !== undefined && !text(value.body, 8192)))
|
|
16
|
+
fail();
|
|
17
|
+
const d = value;
|
|
18
|
+
if (!Array.isArray(d.buttons) || d.buttons.length < 1 || d.buttons.length > 32)
|
|
19
|
+
fail();
|
|
20
|
+
if (new Set(d.buttons.map((b) => b?.id)).size !== d.buttons.length)
|
|
21
|
+
fail();
|
|
22
|
+
for (const b of d.buttons)
|
|
23
|
+
if (!object(b) || !id(b.id) || !text(b.label))
|
|
24
|
+
fail();
|
|
25
|
+
if (d.inputs !== undefined && (!Array.isArray(d.inputs) || d.inputs.length > 16))
|
|
26
|
+
fail();
|
|
27
|
+
const inputs = d.inputs ?? [];
|
|
28
|
+
if (new Set(inputs.map((i) => i?.id)).size !== inputs.length)
|
|
29
|
+
fail();
|
|
30
|
+
for (const i of inputs) {
|
|
31
|
+
if (!object(i) || !id(i.id) || i.id === "__proto__" || !text(i.label))
|
|
32
|
+
fail();
|
|
33
|
+
switch (i.type) {
|
|
34
|
+
case "text": {
|
|
35
|
+
const max = i.maxLength ?? 32;
|
|
36
|
+
if (!Number.isInteger(max) || max < 1 || max > 1024 || (i.initial !== undefined && !text(i.initial, max)))
|
|
37
|
+
fail();
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case "boolean":
|
|
41
|
+
if (i.initial !== undefined && typeof i.initial !== "boolean")
|
|
42
|
+
fail();
|
|
43
|
+
break;
|
|
44
|
+
case "singleOption":
|
|
45
|
+
if (!Array.isArray(i.options) || i.options.length < 1 || i.options.length > 32)
|
|
46
|
+
fail();
|
|
47
|
+
if (new Set(i.options.map((o) => o?.id)).size !== i.options.length)
|
|
48
|
+
fail();
|
|
49
|
+
for (const o of i.options)
|
|
50
|
+
if (!object(o) || !id(o.id) || !text(o.label))
|
|
51
|
+
fail();
|
|
52
|
+
if (i.initial !== undefined && !i.options.some((o) => o.id === i.initial))
|
|
53
|
+
fail();
|
|
54
|
+
break;
|
|
55
|
+
case "numberRange":
|
|
56
|
+
if (!finiteFloat(i.min) || !finiteFloat(i.max) || Math.fround(i.min) >= Math.fround(i.max))
|
|
57
|
+
fail();
|
|
58
|
+
if (i.initial !== undefined && (!finiteFloat(i.initial) || i.initial < i.min || i.initial > i.max))
|
|
59
|
+
fail();
|
|
60
|
+
if (i.step !== undefined && (!finiteFloat(i.step) || Math.fround(i.step) <= 0))
|
|
61
|
+
fail();
|
|
62
|
+
break;
|
|
63
|
+
default:
|
|
64
|
+
fail();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (inputs.reduce((sum, i) => sum + (i.type === "text" ? (i.maxLength ?? 32) : 0), 0) > 8192)
|
|
68
|
+
fail();
|
|
69
|
+
if (JSON.stringify(d).length > 32768)
|
|
70
|
+
fail();
|
|
71
|
+
}
|
|
72
|
+
/** Checks the values before the SDK calls challenge code. */
|
|
73
|
+
function validDialogValues(d, values) {
|
|
74
|
+
if (!object(values))
|
|
75
|
+
return false;
|
|
76
|
+
const inputs = d.inputs ?? [];
|
|
77
|
+
if (Object.keys(values).length !== inputs.length)
|
|
78
|
+
return false;
|
|
79
|
+
return inputs.every((i) => {
|
|
80
|
+
if (!Object.hasOwn(values, i.id))
|
|
81
|
+
return false;
|
|
82
|
+
const v = values[i.id];
|
|
83
|
+
switch (i.type) {
|
|
84
|
+
case "text":
|
|
85
|
+
return text(v, i.maxLength ?? 32);
|
|
86
|
+
case "boolean":
|
|
87
|
+
return typeof v === "boolean";
|
|
88
|
+
case "singleOption":
|
|
89
|
+
return typeof v === "string" && i.options.some((o) => o.id === v);
|
|
90
|
+
case "numberRange":
|
|
91
|
+
return finiteFloat(v) && v >= Math.fround(i.min) && v <= Math.fround(i.max);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/runtime/dialog.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DialogSpec } from "./dialog.js";
|
|
1
2
|
import { type Duration, type Ticks } from "./time.js";
|
|
2
3
|
import type { BlockSpec, BlockState, ChallengeConfig, Handlers, Outcome, PhaseSpec, StateDecl, World } from "./types.js";
|
|
3
4
|
import type { Action, BlockId, Box, Capability, Effect, EndReason, Event, ItemId, ItemStack, Json, RuntimeManifest, Status, Vec3 } from "./wire.js";
|
|
@@ -171,6 +172,13 @@ export interface State {
|
|
|
171
172
|
} & Vec3>;
|
|
172
173
|
/** Pending named batches: transport id to public name. */
|
|
173
174
|
batches: Record<string, string>;
|
|
175
|
+
/** Named commands that wait for their result, by request id. */
|
|
176
|
+
commands: Record<string, {
|
|
177
|
+
/** The name given to `g.command`. */
|
|
178
|
+
name: string;
|
|
179
|
+
/** The transport id of the batch the command went out in. */
|
|
180
|
+
batch?: string;
|
|
181
|
+
}>;
|
|
174
182
|
/** The containers the mirror holds, by "x,y,z": the block and its slots. */
|
|
175
183
|
containers: Record<string, {
|
|
176
184
|
/** The container's block id. */
|
|
@@ -180,7 +188,16 @@ export interface State {
|
|
|
180
188
|
}>;
|
|
181
189
|
/** The world mirror. */
|
|
182
190
|
world: WorldState;
|
|
183
|
-
/** The
|
|
191
|
+
/** The current native dialog for each participant. */
|
|
192
|
+
dialogs: Record<string, {
|
|
193
|
+
/** The unique display ID. */
|
|
194
|
+
requestId: string;
|
|
195
|
+
/** The displayed fields and buttons. */
|
|
196
|
+
dialog: DialogSpec;
|
|
197
|
+
/** The first tick that refuses a response. */
|
|
198
|
+
expires: number;
|
|
199
|
+
}>;
|
|
200
|
+
/** The next request id (walks, batches, commands, dialogs). */
|
|
184
201
|
nextId: number;
|
|
185
202
|
/** The winners once the game ended. */
|
|
186
203
|
winners: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/runtime/reducer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/runtime/reducer.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/reducer.js
CHANGED
|
@@ -22,6 +22,7 @@ exports.parseBlockState = parseBlockState;
|
|
|
22
22
|
exports.blockSpecString = blockSpecString;
|
|
23
23
|
exports.splitBatches = splitBatches;
|
|
24
24
|
exports.createReducer = createReducer;
|
|
25
|
+
const dialog_js_1 = require("./dialog.js");
|
|
25
26
|
const chat_js_1 = require("./chat.js");
|
|
26
27
|
const errors_js_1 = require("./errors.js");
|
|
27
28
|
const time_js_1 = require("./time.js");
|
|
@@ -197,7 +198,9 @@ function splitBatches(effects) {
|
|
|
197
198
|
for (const e of effects) {
|
|
198
199
|
const v = fillVolume(e);
|
|
199
200
|
if (v > exports.MAX_FILL_VOLUME) {
|
|
200
|
-
throw (0, errors_js_1.apiError)("fill_too_large", `a ${e.kind} of ${v} blocks exceeds ${exports.MAX_FILL_VOLUME}; split it`, {
|
|
201
|
+
throw (0, errors_js_1.apiError)("fill_too_large", `a ${e.kind} of ${v} blocks exceeds ${exports.MAX_FILL_VOLUME}; split it`, {
|
|
202
|
+
path: "setup",
|
|
203
|
+
});
|
|
201
204
|
}
|
|
202
205
|
if (current.length >= exports.MAX_BATCH_EFFECTS || volume + v > exports.MAX_FILL_VOLUME) {
|
|
203
206
|
out.push(current);
|
|
@@ -366,8 +369,10 @@ function createReducer(def) {
|
|
|
366
369
|
votes: Object.fromEntries(voteIds.map((id) => [id, { open: false, round: 0, cast: {} }])),
|
|
367
370
|
walks: {},
|
|
368
371
|
batches: {},
|
|
372
|
+
commands: {},
|
|
369
373
|
containers: {},
|
|
370
374
|
world: (0, world_js_1.emptyWorld)(),
|
|
375
|
+
dialogs: {},
|
|
371
376
|
nextId: 0,
|
|
372
377
|
winners: [],
|
|
373
378
|
endState: "",
|
|
@@ -617,6 +622,7 @@ function createReducer(def) {
|
|
|
617
622
|
const e = s.world.entities[id];
|
|
618
623
|
return e ? (0, world_js_1.freezeObservation)(e) : undefined;
|
|
619
624
|
},
|
|
625
|
+
blockNbt: (at) => s.world.blockNbt[posKey(at)],
|
|
620
626
|
containerContents(at) {
|
|
621
627
|
const c = s.containers[posKey(at)];
|
|
622
628
|
return c ? countsOf(c.slots) : undefined;
|
|
@@ -634,6 +640,36 @@ function createReducer(def) {
|
|
|
634
640
|
const abstaining = players().filter((p) => !p.eliminated && v.cast[p.name] === undefined);
|
|
635
641
|
return { counts, leaders, abstaining };
|
|
636
642
|
},
|
|
643
|
+
dialog(player, definition) {
|
|
644
|
+
write("dialog");
|
|
645
|
+
if (s.status !== "PLAYING")
|
|
646
|
+
throw (0, errors_js_1.apiError)("dialog_stage", "dialog: the game must be in play");
|
|
647
|
+
if (!s.capabilities.includes("dialogs"))
|
|
648
|
+
throw (0, errors_js_1.unavailableError)("dialogs_unavailable", "dialog: this server does not support dialog responses");
|
|
649
|
+
const p = s.players[player?.name];
|
|
650
|
+
if (!p?.human || !p.connected)
|
|
651
|
+
throw (0, errors_js_1.apiError)("dialog_player", "dialog: select a connected human participant");
|
|
652
|
+
(0, dialog_js_1.validateDialog)(definition);
|
|
653
|
+
const timeoutTicks = (0, time_js_1.toTicks)(definition.timeout ?? "60s");
|
|
654
|
+
if (!Number.isInteger(timeoutTicks) || timeoutTicks < 1 || timeoutTicks > 72000)
|
|
655
|
+
throw (0, errors_js_1.apiError)("dialog_timeout", "dialog: timeout must be from one tick to one hour");
|
|
656
|
+
const { timeout: _timeout, ...dialog } = compact(snapshot(definition));
|
|
657
|
+
const requestId = `dialog:${s.nextId++}`;
|
|
658
|
+
s.dialogs ??= {};
|
|
659
|
+
s.dialogs[p.name] = { requestId, dialog, expires: s.tick + timeoutTicks };
|
|
660
|
+
push({ kind: "dialog", player: p.name, requestId, dialog, timeoutTicks });
|
|
661
|
+
},
|
|
662
|
+
clearDialog(player) {
|
|
663
|
+
write("clearDialog");
|
|
664
|
+
const p = s.players[player?.name];
|
|
665
|
+
if (!p?.human)
|
|
666
|
+
throw (0, errors_js_1.apiError)("dialog_player", "clearDialog: select a human participant");
|
|
667
|
+
if (!s.capabilities.includes("dialogs"))
|
|
668
|
+
throw (0, errors_js_1.unavailableError)("dialogs_unavailable", "clearDialog: this server does not support dialog responses");
|
|
669
|
+
if (s.dialogs)
|
|
670
|
+
delete s.dialogs[p.name];
|
|
671
|
+
push({ kind: "clear_dialog", player: p.name });
|
|
672
|
+
},
|
|
637
673
|
// ---- notifications
|
|
638
674
|
say(message) {
|
|
639
675
|
notify("say");
|
|
@@ -830,10 +866,20 @@ function createReducer(def) {
|
|
|
830
866
|
}));
|
|
831
867
|
push({ kind: "container", at: { ...at }, items: out });
|
|
832
868
|
},
|
|
833
|
-
command(cmd) {
|
|
869
|
+
command(cmd, name) {
|
|
834
870
|
write("command");
|
|
835
871
|
r.actions.push({ type: "log", message: `raw command: ${cmd}` });
|
|
836
|
-
|
|
872
|
+
if (name === undefined) {
|
|
873
|
+
push({ kind: "command", cmd });
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
if (typeof name !== "string")
|
|
877
|
+
throw (0, errors_js_1.apiError)("invalid_value", "command: the name must be a string", { value: name });
|
|
878
|
+
if (s.status !== "PLAYING")
|
|
879
|
+
throw (0, errors_js_1.apiError)("lifecycle", `command("${cmd}", "${name}"): a result needs a running game, not .setup (status ${s.status})`);
|
|
880
|
+
const id = `cmd:${s.nextId++}`;
|
|
881
|
+
s.commands[id] = { name };
|
|
882
|
+
push({ kind: "command", cmd, id });
|
|
837
883
|
},
|
|
838
884
|
// ---- flow
|
|
839
885
|
startPhase(name) {
|
|
@@ -936,6 +982,11 @@ function createReducer(def) {
|
|
|
936
982
|
// The transport id is unique for the run; the public name repeats once its batch is done.
|
|
937
983
|
const id = `batch:${s.nextId++}`;
|
|
938
984
|
s.batches[id] = name;
|
|
985
|
+
for (const e of effects) {
|
|
986
|
+
const c = e.kind === "command" && e.id !== undefined ? s.commands[e.id] : undefined;
|
|
987
|
+
if (c)
|
|
988
|
+
c.batch = id;
|
|
989
|
+
}
|
|
939
990
|
r.actions.push({ type: "batch", id, effects });
|
|
940
991
|
},
|
|
941
992
|
};
|
|
@@ -978,6 +1029,19 @@ function createReducer(def) {
|
|
|
978
1029
|
run(r, "handler", local, g, e);
|
|
979
1030
|
resolvePhaseRequest(r);
|
|
980
1031
|
}
|
|
1032
|
+
/** A named command's answer: it leaves the pending set and reaches `on.commandResult`. An unknown id is ignored. */
|
|
1033
|
+
function commandDone(r, id, ok, value, error) {
|
|
1034
|
+
const c = r.s.commands[id];
|
|
1035
|
+
if (!c)
|
|
1036
|
+
return;
|
|
1037
|
+
delete r.s.commands[id];
|
|
1038
|
+
fire(r, "commandResult", () => compact({
|
|
1039
|
+
name: c.name,
|
|
1040
|
+
ok,
|
|
1041
|
+
value: ok && value !== undefined ? snapshot(value) : undefined,
|
|
1042
|
+
error: ok ? undefined : (error ?? "the command failed"),
|
|
1043
|
+
}));
|
|
1044
|
+
}
|
|
981
1045
|
/** The contexts of a reduction, one per mode, built on first use. */
|
|
982
1046
|
const ctxCache = new WeakMap();
|
|
983
1047
|
function ctxOf(r, mode) {
|
|
@@ -1186,8 +1250,14 @@ function createReducer(def) {
|
|
|
1186
1250
|
assertJson(judge, "judgeContext");
|
|
1187
1251
|
gameOver.judgeContext = judge;
|
|
1188
1252
|
}
|
|
1253
|
+
clearDialogs(s, r.actions);
|
|
1189
1254
|
r.actions.push(gameOver);
|
|
1190
1255
|
}
|
|
1256
|
+
function clearDialogs(s, actions) {
|
|
1257
|
+
for (const player of Object.keys(s.dialogs ?? {}))
|
|
1258
|
+
actions.push({ type: "effect", effect: { kind: "clear_dialog", player } });
|
|
1259
|
+
s.dialogs = {};
|
|
1260
|
+
}
|
|
1191
1261
|
/** The SDK's own terminal result: no author callback runs. */
|
|
1192
1262
|
function failRun(s, actions, endState, message, data) {
|
|
1193
1263
|
actions.push(compact({ type: "log", message, data }));
|
|
@@ -1202,6 +1272,7 @@ function createReducer(def) {
|
|
|
1202
1272
|
const achievements = {};
|
|
1203
1273
|
for (const p of Object.values(s.players))
|
|
1204
1274
|
achievements[p.name] = [...p.achievements];
|
|
1275
|
+
clearDialogs(s, actions);
|
|
1205
1276
|
actions.push({ type: "game_over", winners: [], endState, reason: "error", achievements });
|
|
1206
1277
|
}
|
|
1207
1278
|
// ------------------------------------------------------------ lifecycle
|
|
@@ -1762,6 +1833,8 @@ function createReducer(def) {
|
|
|
1762
1833
|
return;
|
|
1763
1834
|
}
|
|
1764
1835
|
p.connected = false;
|
|
1836
|
+
if (s.dialogs)
|
|
1837
|
+
delete s.dialogs[p.name];
|
|
1765
1838
|
if (playing())
|
|
1766
1839
|
fire(r, "left", { player: viewOf(r, p) });
|
|
1767
1840
|
break;
|
|
@@ -1770,6 +1843,12 @@ function createReducer(def) {
|
|
|
1770
1843
|
r.isTick = true;
|
|
1771
1844
|
s.dt = e.serverTick - s.tick;
|
|
1772
1845
|
s.tick = e.serverTick;
|
|
1846
|
+
for (const [player, d] of Object.entries(s.dialogs ?? {})) {
|
|
1847
|
+
if (s.tick < d.expires)
|
|
1848
|
+
continue;
|
|
1849
|
+
delete s.dialogs[player];
|
|
1850
|
+
r.actions.push({ type: "effect", effect: { kind: "clear_dialog", player } });
|
|
1851
|
+
}
|
|
1773
1852
|
if (e.entities)
|
|
1774
1853
|
s.world = (0, world_js_1.moveEntities)(s.world, e.entities);
|
|
1775
1854
|
if (e.time !== undefined && e.time !== s.world.time)
|
|
@@ -1813,6 +1892,11 @@ function createReducer(def) {
|
|
|
1813
1892
|
play(r);
|
|
1814
1893
|
return;
|
|
1815
1894
|
}
|
|
1895
|
+
// A command of the batch with no result yet did not run: the batch was refused before the engine got it.
|
|
1896
|
+
for (const [id, c] of Object.entries(s.commands)) {
|
|
1897
|
+
if (c.batch === e.id)
|
|
1898
|
+
commandDone(r, id, false, undefined, e.detail ?? "the command did not run");
|
|
1899
|
+
}
|
|
1816
1900
|
const batchName = s.batches[e.id];
|
|
1817
1901
|
if (batchName !== undefined) {
|
|
1818
1902
|
delete s.batches[e.id];
|
|
@@ -1835,8 +1919,18 @@ function createReducer(def) {
|
|
|
1835
1919
|
}
|
|
1836
1920
|
break;
|
|
1837
1921
|
}
|
|
1922
|
+
case "command_result":
|
|
1923
|
+
commandDone(r, e.id, e.ok, e.value, e.error);
|
|
1924
|
+
break;
|
|
1838
1925
|
case "effect_failed":
|
|
1926
|
+
if (e.effect?.kind === "dialog") {
|
|
1927
|
+
const effect = e.effect;
|
|
1928
|
+
if (s.dialogs?.[effect.player]?.requestId === effect.requestId)
|
|
1929
|
+
delete s.dialogs[effect.player];
|
|
1930
|
+
}
|
|
1839
1931
|
r.actions.push({ type: "log", message: `effect failed: ${e.kind}: ${e.detail}` });
|
|
1932
|
+
if (e.effect?.kind === "command" && e.effect.id !== undefined)
|
|
1933
|
+
commandDone(r, e.effect.id, false, undefined, e.detail);
|
|
1840
1934
|
if (playing()) {
|
|
1841
1935
|
fire(r, "effectFailed", {
|
|
1842
1936
|
kind: e.kind,
|
|
@@ -1872,6 +1966,8 @@ function createReducer(def) {
|
|
|
1872
1966
|
break;
|
|
1873
1967
|
}
|
|
1874
1968
|
case "player_died": {
|
|
1969
|
+
if (s.dialogs)
|
|
1970
|
+
delete s.dialogs[e.name];
|
|
1875
1971
|
const p = resolve(e.name);
|
|
1876
1972
|
if (!p)
|
|
1877
1973
|
return;
|
|
@@ -1980,7 +2076,11 @@ function createReducer(def) {
|
|
|
1980
2076
|
applyMobStatus(next, e);
|
|
1981
2077
|
s.world = (0, world_js_1.putEntity)(s.world, next);
|
|
1982
2078
|
if (playing())
|
|
1983
|
-
fire(r, "entityChanged",
|
|
2079
|
+
fire(r, "entityChanged", () => ({
|
|
2080
|
+
entity: (0, world_js_1.freezeObservation)(next),
|
|
2081
|
+
was: (0, world_js_1.freezeObservation)(prev),
|
|
2082
|
+
changed: Object.freeze((0, world_js_1.changedFields)(prev, next)),
|
|
2083
|
+
}));
|
|
1984
2084
|
break;
|
|
1985
2085
|
}
|
|
1986
2086
|
case "entity_removed": {
|
|
@@ -1996,6 +2096,33 @@ function createReducer(def) {
|
|
|
1996
2096
|
});
|
|
1997
2097
|
break;
|
|
1998
2098
|
}
|
|
2099
|
+
case "nbt": {
|
|
2100
|
+
const res = (0, world_js_1.applyNbt)(s.world, e);
|
|
2101
|
+
const world = res.world;
|
|
2102
|
+
s.world = world;
|
|
2103
|
+
if (!playing())
|
|
2104
|
+
break;
|
|
2105
|
+
// A counter (an item's `Age`) changes on every tick; the paths let a handler skip it. They are built only for a handler.
|
|
2106
|
+
for (const c of res.entities) {
|
|
2107
|
+
const entity = world.entities[c.id];
|
|
2108
|
+
if (!entity)
|
|
2109
|
+
continue;
|
|
2110
|
+
fire(r, "entityChanged", () => ({
|
|
2111
|
+
entity,
|
|
2112
|
+
was: (0, world_js_1.freezeObservation)(c.was),
|
|
2113
|
+
changed: Object.freeze((0, world_js_1.nbtPaths)(c.was.nbt, c.delta, "nbt")),
|
|
2114
|
+
}));
|
|
2115
|
+
}
|
|
2116
|
+
for (const c of res.blocks) {
|
|
2117
|
+
fire(r, "blockNbtChanged", () => ({
|
|
2118
|
+
at: { ...c.at },
|
|
2119
|
+
nbt: world.blockNbt[posKey(c.at)],
|
|
2120
|
+
was: c.was,
|
|
2121
|
+
changed: Object.freeze(c.delta === null ? [""] : (0, world_js_1.nbtPaths)(c.was, c.delta, "")),
|
|
2122
|
+
}));
|
|
2123
|
+
}
|
|
2124
|
+
break;
|
|
2125
|
+
}
|
|
1999
2126
|
case "chunk":
|
|
2000
2127
|
s.world = (0, world_js_1.applyChunk)(s.world, e);
|
|
2001
2128
|
break;
|
|
@@ -2095,6 +2222,28 @@ function createReducer(def) {
|
|
|
2095
2222
|
case "vote_attempt":
|
|
2096
2223
|
voteAttempt(r, e);
|
|
2097
2224
|
break;
|
|
2225
|
+
case "dialog_response": {
|
|
2226
|
+
const p = resolve(e.player);
|
|
2227
|
+
const d = s.dialogs?.[e.player];
|
|
2228
|
+
if (!playing() ||
|
|
2229
|
+
!p?.human ||
|
|
2230
|
+
!p.connected ||
|
|
2231
|
+
!d ||
|
|
2232
|
+
s.tick >= d.expires ||
|
|
2233
|
+
d.requestId !== e.requestId ||
|
|
2234
|
+
d.dialog.id !== e.dialogId ||
|
|
2235
|
+
!d.dialog.buttons.some((b) => b.id === e.buttonId) ||
|
|
2236
|
+
!(0, dialog_js_1.validDialogValues)(d.dialog, e.inputs))
|
|
2237
|
+
break;
|
|
2238
|
+
delete s.dialogs[e.player];
|
|
2239
|
+
fire(r, "dialogResponse", {
|
|
2240
|
+
player: viewOf(r, p),
|
|
2241
|
+
dialogId: e.dialogId,
|
|
2242
|
+
buttonId: e.buttonId,
|
|
2243
|
+
inputs: snapshot(e.inputs),
|
|
2244
|
+
});
|
|
2245
|
+
break;
|
|
2246
|
+
}
|
|
2098
2247
|
case "custom": {
|
|
2099
2248
|
if (!playing())
|
|
2100
2249
|
return;
|