miaoda-game-devkit 0.2.6 → 0.2.7
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/dist/{gameplay-audit-XBGq_jIV.d.mts → gameplay-audit-CusQfLYQ.d.mts} +3 -1
- package/dist/{gameplay-audit-XBGq_jIV.d.ts → gameplay-audit-CusQfLYQ.d.ts} +3 -1
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +10 -1
- package/dist/index.mjs +10 -1
- package/dist/lint/gameplay-contract.contract.mjs +14 -2
- package/dist/lint/phaser-headless.contract.mjs +5 -1
- package/dist/vitest-config.d.mts +1 -1
- package/dist/vitest-config.d.ts +1 -1
- package/package.json +1 -1
|
@@ -18,7 +18,9 @@ interface HeadlessGameHost<TScene extends Phaser.Scene> {
|
|
|
18
18
|
/** 推进完整 Phaser 帧并等待异步 update 或生命周期完成。 */
|
|
19
19
|
stepFramesAsync(count?: number): Promise<void>;
|
|
20
20
|
/** 在限定帧数内推进游戏,直到条件成立。 */
|
|
21
|
-
stepUntil(condition: () => boolean, maxFrames?: number
|
|
21
|
+
stepUntil(condition: () => boolean, maxFrames?: number | {
|
|
22
|
+
maxFrames?: number;
|
|
23
|
+
}): number;
|
|
22
24
|
/** 精确推进指定次数的 Arcade Physics 单步。 */
|
|
23
25
|
stepPhysics(steps?: number): void;
|
|
24
26
|
/** 记录由测试定义的可序列化玩法检查点。 */
|
|
@@ -18,7 +18,9 @@ interface HeadlessGameHost<TScene extends Phaser.Scene> {
|
|
|
18
18
|
/** 推进完整 Phaser 帧并等待异步 update 或生命周期完成。 */
|
|
19
19
|
stepFramesAsync(count?: number): Promise<void>;
|
|
20
20
|
/** 在限定帧数内推进游戏,直到条件成立。 */
|
|
21
|
-
stepUntil(condition: () => boolean, maxFrames?: number
|
|
21
|
+
stepUntil(condition: () => boolean, maxFrames?: number | {
|
|
22
|
+
maxFrames?: number;
|
|
23
|
+
}): number;
|
|
22
24
|
/** 精确推进指定次数的 Arcade Physics 单步。 */
|
|
23
25
|
stepPhysics(steps?: number): void;
|
|
24
26
|
/** 记录由测试定义的可序列化玩法检查点。 */
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { G as GameplayContractMetadata, H as HeadlessGameHost, a as HeadlessGameplayEvidenceRequirements } from './gameplay-audit-
|
|
2
|
-
export { b as GameplayAuditContract, c as GameplayAuditOptions, d as HeadlessCanvasBounds, e as HeadlessGameOptions, f as HeadlessGameplayEvidence, g as HeadlessInputDriver, h as HeadlessInputPoint, i as HeadlessKeyboardEventOptions, j as HeadlessKeyboardInput, k as HeadlessMouseInput, l as HeadlessTouchInput, m as createHeadlessGame } from './gameplay-audit-
|
|
1
|
+
import { G as GameplayContractMetadata, H as HeadlessGameHost, a as HeadlessGameplayEvidenceRequirements } from './gameplay-audit-CusQfLYQ.mjs';
|
|
2
|
+
export { b as GameplayAuditContract, c as GameplayAuditOptions, d as HeadlessCanvasBounds, e as HeadlessGameOptions, f as HeadlessGameplayEvidence, g as HeadlessInputDriver, h as HeadlessInputPoint, i as HeadlessKeyboardEventOptions, j as HeadlessKeyboardInput, k as HeadlessMouseInput, l as HeadlessTouchInput, m as createHeadlessGame } from './gameplay-audit-CusQfLYQ.mjs';
|
|
3
3
|
import * as Phaser from 'phaser';
|
|
4
4
|
import { TestContext, TestOptions } from 'vitest';
|
|
5
5
|
|
|
@@ -23,6 +23,8 @@ interface GameplayTestOptions extends GameplayContractOptions {
|
|
|
23
23
|
interface GameplayContractHandle<TScene extends Phaser.Scene> {
|
|
24
24
|
/** 将当前 contract 绑定到实际创建的 HEADLESS host。 */
|
|
25
25
|
attachHost(host: HeadlessGameHost<TScene>): void;
|
|
26
|
+
/** 记录一个由测试先断言、再声明的玩法检查点。 */
|
|
27
|
+
checkpoint(id: string): void;
|
|
26
28
|
/** 立即验证证据;通常由 onTestFinished 自动执行。 */
|
|
27
29
|
verify(): void;
|
|
28
30
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { G as GameplayContractMetadata, H as HeadlessGameHost, a as HeadlessGameplayEvidenceRequirements } from './gameplay-audit-
|
|
2
|
-
export { b as GameplayAuditContract, c as GameplayAuditOptions, d as HeadlessCanvasBounds, e as HeadlessGameOptions, f as HeadlessGameplayEvidence, g as HeadlessInputDriver, h as HeadlessInputPoint, i as HeadlessKeyboardEventOptions, j as HeadlessKeyboardInput, k as HeadlessMouseInput, l as HeadlessTouchInput, m as createHeadlessGame } from './gameplay-audit-
|
|
1
|
+
import { G as GameplayContractMetadata, H as HeadlessGameHost, a as HeadlessGameplayEvidenceRequirements } from './gameplay-audit-CusQfLYQ.js';
|
|
2
|
+
export { b as GameplayAuditContract, c as GameplayAuditOptions, d as HeadlessCanvasBounds, e as HeadlessGameOptions, f as HeadlessGameplayEvidence, g as HeadlessInputDriver, h as HeadlessInputPoint, i as HeadlessKeyboardEventOptions, j as HeadlessKeyboardInput, k as HeadlessMouseInput, l as HeadlessTouchInput, m as createHeadlessGame } from './gameplay-audit-CusQfLYQ.js';
|
|
3
3
|
import * as Phaser from 'phaser';
|
|
4
4
|
import { TestContext, TestOptions } from 'vitest';
|
|
5
5
|
|
|
@@ -23,6 +23,8 @@ interface GameplayTestOptions extends GameplayContractOptions {
|
|
|
23
23
|
interface GameplayContractHandle<TScene extends Phaser.Scene> {
|
|
24
24
|
/** 将当前 contract 绑定到实际创建的 HEADLESS host。 */
|
|
25
25
|
attachHost(host: HeadlessGameHost<TScene>): void;
|
|
26
|
+
/** 记录一个由测试先断言、再声明的玩法检查点。 */
|
|
27
|
+
checkpoint(id: string): void;
|
|
26
28
|
/** 立即验证证据;通常由 onTestFinished 自动执行。 */
|
|
27
29
|
verify(): void;
|
|
28
30
|
}
|
package/dist/index.js
CHANGED
|
@@ -1021,7 +1021,8 @@ async function createHeadlessGame(scene, options = {}) {
|
|
|
1021
1021
|
stepFrames(count);
|
|
1022
1022
|
await settleRuntime();
|
|
1023
1023
|
},
|
|
1024
|
-
stepUntil(condition,
|
|
1024
|
+
stepUntil(condition, maxFramesOrOptions = 120) {
|
|
1025
|
+
const maxFrames = typeof maxFramesOrOptions === "number" ? maxFramesOrOptions : maxFramesOrOptions.maxFrames ?? 120;
|
|
1025
1026
|
assertStepCount(maxFrames, "stepUntil maxFrames");
|
|
1026
1027
|
throwRuntimeError();
|
|
1027
1028
|
for (let frame = 0; frame <= maxFrames; frame += 1) {
|
|
@@ -1193,6 +1194,14 @@ function registerGameplayContract(context, options) {
|
|
|
1193
1194
|
}
|
|
1194
1195
|
host = currentHost;
|
|
1195
1196
|
},
|
|
1197
|
+
checkpoint(id) {
|
|
1198
|
+
if (!host) {
|
|
1199
|
+
throw new Error(
|
|
1200
|
+
`Gameplay contract "${options.id}" must attach a HEADLESS host before recording a checkpoint.`
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
host.checkpoint(id);
|
|
1204
|
+
},
|
|
1196
1205
|
verify
|
|
1197
1206
|
};
|
|
1198
1207
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -979,7 +979,8 @@ async function createHeadlessGame(scene, options = {}) {
|
|
|
979
979
|
stepFrames(count);
|
|
980
980
|
await settleRuntime();
|
|
981
981
|
},
|
|
982
|
-
stepUntil(condition,
|
|
982
|
+
stepUntil(condition, maxFramesOrOptions = 120) {
|
|
983
|
+
const maxFrames = typeof maxFramesOrOptions === "number" ? maxFramesOrOptions : maxFramesOrOptions.maxFrames ?? 120;
|
|
983
984
|
assertStepCount(maxFrames, "stepUntil maxFrames");
|
|
984
985
|
throwRuntimeError();
|
|
985
986
|
for (let frame = 0; frame <= maxFrames; frame += 1) {
|
|
@@ -1151,6 +1152,14 @@ function registerGameplayContract(context, options) {
|
|
|
1151
1152
|
}
|
|
1152
1153
|
host = currentHost;
|
|
1153
1154
|
},
|
|
1155
|
+
checkpoint(id) {
|
|
1156
|
+
if (!host) {
|
|
1157
|
+
throw new Error(
|
|
1158
|
+
`Gameplay contract "${options.id}" must attach a HEADLESS host before recording a checkpoint.`
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
host.checkpoint(id);
|
|
1162
|
+
},
|
|
1154
1163
|
verify
|
|
1155
1164
|
};
|
|
1156
1165
|
}
|
|
@@ -983,7 +983,8 @@ async function createHeadlessGame(scene, options = {}) {
|
|
|
983
983
|
stepFrames(count);
|
|
984
984
|
await settleRuntime();
|
|
985
985
|
},
|
|
986
|
-
stepUntil(condition,
|
|
986
|
+
stepUntil(condition, maxFramesOrOptions = 120) {
|
|
987
|
+
const maxFrames = typeof maxFramesOrOptions === "number" ? maxFramesOrOptions : maxFramesOrOptions.maxFrames ?? 120;
|
|
987
988
|
assertStepCount(maxFrames, "stepUntil maxFrames");
|
|
988
989
|
throwRuntimeError();
|
|
989
990
|
for (let frame = 0; frame <= maxFrames; frame += 1) {
|
|
@@ -1155,6 +1156,14 @@ function registerGameplayContract(context, options) {
|
|
|
1155
1156
|
}
|
|
1156
1157
|
host = currentHost;
|
|
1157
1158
|
},
|
|
1159
|
+
checkpoint(id) {
|
|
1160
|
+
if (!host) {
|
|
1161
|
+
throw new Error(
|
|
1162
|
+
`Gameplay contract "${options.id}" must attach a HEADLESS host before recording a checkpoint.`
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
host.checkpoint(id);
|
|
1166
|
+
},
|
|
1158
1167
|
verify
|
|
1159
1168
|
};
|
|
1160
1169
|
}
|
|
@@ -1190,7 +1199,8 @@ describe("gameplay contract lifecycle integration", () => {
|
|
|
1190
1199
|
id: "InputScene.hit",
|
|
1191
1200
|
kind: "playthrough",
|
|
1192
1201
|
requireInput: true,
|
|
1193
|
-
requireFrameAdvance: true
|
|
1202
|
+
requireFrameAdvance: true,
|
|
1203
|
+
requireCheckpoint: "hit-recorded"
|
|
1194
1204
|
});
|
|
1195
1205
|
let host;
|
|
1196
1206
|
try {
|
|
@@ -1199,12 +1209,14 @@ describe("gameplay contract lifecycle integration", () => {
|
|
|
1199
1209
|
host.stepFrames();
|
|
1200
1210
|
await host.input.mouse.click(40, 40);
|
|
1201
1211
|
expect(host.scene.hits).toBe(1);
|
|
1212
|
+
contract.checkpoint("hit-recorded");
|
|
1202
1213
|
host.destroy();
|
|
1203
1214
|
await callbacks[0]?.();
|
|
1204
1215
|
expect(context.task.meta.gameplayContract).toMatchObject({
|
|
1205
1216
|
id: "InputScene.hit",
|
|
1206
1217
|
evidence: {
|
|
1207
1218
|
clicks: 1,
|
|
1219
|
+
checkpoints: ["hit-recorded"],
|
|
1208
1220
|
frames: 1,
|
|
1209
1221
|
mouseEvents: 3
|
|
1210
1222
|
}
|
|
@@ -983,7 +983,8 @@ async function createHeadlessGame(scene, options = {}) {
|
|
|
983
983
|
stepFrames(count);
|
|
984
984
|
await settleRuntime();
|
|
985
985
|
},
|
|
986
|
-
stepUntil(condition,
|
|
986
|
+
stepUntil(condition, maxFramesOrOptions = 120) {
|
|
987
|
+
const maxFrames = typeof maxFramesOrOptions === "number" ? maxFramesOrOptions : maxFramesOrOptions.maxFrames ?? 120;
|
|
987
988
|
assertStepCount(maxFrames, "stepUntil maxFrames");
|
|
988
989
|
throwRuntimeError();
|
|
989
990
|
for (let frame = 0; frame <= maxFrames; frame += 1) {
|
|
@@ -1149,6 +1150,9 @@ describe("Phaser HEADLESS host", () => {
|
|
|
1149
1150
|
expect(() => boundedHost.stepUntil(() => false, 1.5)).toThrow(
|
|
1150
1151
|
"stepUntil maxFrames must be a non-negative safe integer"
|
|
1151
1152
|
);
|
|
1153
|
+
expect(() => boundedHost.stepUntil(() => false, { maxFrames: 0 })).toThrow(
|
|
1154
|
+
"Condition was not met within 0 complete Phaser frames"
|
|
1155
|
+
);
|
|
1152
1156
|
expect(() => boundedHost.stepPhysics(-1)).toThrow(
|
|
1153
1157
|
"stepPhysics steps must be a non-negative safe integer"
|
|
1154
1158
|
);
|
package/dist/vitest-config.d.mts
CHANGED
package/dist/vitest-config.d.ts
CHANGED