miaoda-game-devkit 0.1.0 → 0.2.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 +44 -14
- package/bin/miaoda-game-lint.js +1 -1
- package/dist/cli/lint.js +1 -1
- package/dist/gameplay-audit-CYqLL8gY.d.mts +193 -0
- package/dist/gameplay-audit-CYqLL8gY.d.ts +193 -0
- package/dist/index.d.mts +47 -83
- package/dist/index.d.ts +47 -83
- package/dist/index.js +481 -93
- package/dist/index.mjs +480 -93
- package/dist/lint/contracts.config.mjs +36 -0
- package/dist/lint/gameplay-audit.contract.mjs +426 -0
- package/dist/lint/gameplay-contract.contract.mjs +1227 -0
- package/dist/lint/phaser-headless.contract.mjs +1575 -0
- package/dist/lint/phaser-text-assertions.contract.mjs +32 -0
- package/dist/lint/resource-import-plugin.contract.mjs +97 -0
- package/dist/lint/setup.mjs +31 -34
- package/dist/lint/vitest-config.contract.mjs +471 -0
- package/dist/vitest-config.d.mts +6 -2
- package/dist/vitest-config.d.ts +6 -2
- package/dist/vitest-config.js +344 -5
- package/dist/vitest-config.mjs +342 -5
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,111 +1,75 @@
|
|
|
1
|
+
import { G as GameplayContractMetadata, H as HeadlessGameHost, a as HeadlessGameplayEvidenceRequirements } from './gameplay-audit-CYqLL8gY.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-CYqLL8gY.js';
|
|
1
3
|
import * as Phaser from 'phaser';
|
|
4
|
+
import { TestContext, TestOptions } from 'vitest';
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
game: Phaser.Game;
|
|
5
|
-
scene: TScene;
|
|
6
|
-
input: HeadlessInputDriver;
|
|
7
|
-
/** 当前隔离 host 实际执行过的客观操作证据。 */
|
|
8
|
-
readonly evidence: Readonly<HeadlessGameplayEvidence>;
|
|
9
|
-
/** 当缺少所要求的输入、时间、物理或转场证据时失败。 */
|
|
10
|
-
assertGameplayEvidence(requirements?: HeadlessGameplayEvidenceRequirements): void;
|
|
11
|
-
settle(): Promise<void>;
|
|
12
|
-
stepFrames(count?: number): void;
|
|
13
|
-
stepFramesAsync(count?: number): Promise<void>;
|
|
14
|
-
stepUntil(condition: () => boolean, maxFrames?: number): number;
|
|
15
|
-
stepPhysics(steps?: number): void;
|
|
16
|
-
assertTextHealth(): void;
|
|
17
|
-
destroy(): void;
|
|
18
|
-
}
|
|
19
|
-
interface HeadlessGameplayEvidence {
|
|
20
|
-
/** 通过 host 公共 API 推进的完整 Phaser 帧数。 */
|
|
21
|
-
frames: number;
|
|
22
|
-
/** 显式执行的 Arcade Physics 单步数。 */
|
|
23
|
-
physicsSteps: number;
|
|
24
|
-
/** 投递到 Phaser canvas 的 DOM 鼠标事件数。 */
|
|
25
|
-
mouseEvents: number;
|
|
26
|
-
/** 通过输入辅助方法投递的复合 click 次数。 */
|
|
27
|
-
clicks: number;
|
|
28
|
-
/** 通过 Scene Plugin 公共 API 观察到的 Scene 操作。 */
|
|
29
|
-
transitions: ReadonlyArray<{
|
|
30
|
-
from: string;
|
|
31
|
-
to: string;
|
|
32
|
-
method: "start" | "launch" | "switch" | "sleep" | "wake";
|
|
33
|
-
}>;
|
|
34
|
-
}
|
|
35
|
-
interface HeadlessGameplayEvidenceRequirements {
|
|
36
|
-
/** 至少要求一次真实 DOM 鼠标事件。 */
|
|
37
|
-
requireInput?: boolean;
|
|
38
|
-
/** 至少要求推进一个完整 Phaser 帧。 */
|
|
39
|
-
requireFrameAdvance?: boolean;
|
|
40
|
-
/** 至少要求执行一次显式 Arcade Physics 单步。 */
|
|
41
|
-
requirePhysicsStep?: boolean;
|
|
42
|
-
/** 要求发生一个或多个目标 key 匹配的 Scene 转场。 */
|
|
43
|
-
requireTransition?: string | string[];
|
|
44
|
-
}
|
|
45
|
-
interface HeadlessCanvasBounds {
|
|
46
|
-
left: number;
|
|
47
|
-
top: number;
|
|
48
|
-
width: number;
|
|
49
|
-
height: number;
|
|
50
|
-
}
|
|
51
|
-
interface HeadlessInputPoint {
|
|
52
|
-
clientX: number;
|
|
53
|
-
clientY: number;
|
|
54
|
-
}
|
|
55
|
-
interface HeadlessMouseInput {
|
|
56
|
-
move(x: number, y: number, buttons?: number): Promise<void>;
|
|
57
|
-
down(x: number, y: number): Promise<void>;
|
|
58
|
-
up(x: number, y: number): Promise<void>;
|
|
59
|
-
click(x: number, y: number): Promise<void>;
|
|
60
|
-
}
|
|
61
|
-
interface HeadlessInputDriver {
|
|
62
|
-
readonly canvas: HTMLCanvasElement;
|
|
63
|
-
readonly mouse: HeadlessMouseInput;
|
|
64
|
-
setCanvasBounds(bounds: HeadlessCanvasBounds): void;
|
|
65
|
-
gameToClient(x: number, y: number): HeadlessInputPoint;
|
|
66
|
-
settle(): Promise<void>;
|
|
67
|
-
}
|
|
68
|
-
type HeadlessGameOptions = Omit<Phaser.Types.Core.GameConfig, "type" | "scene" | "callbacks"> & {
|
|
69
|
-
/** Maximum time to wait for Scene creation to complete. */
|
|
70
|
-
bootTimeoutMs?: number;
|
|
71
|
-
/** Scene types that must be registered before the initial Scene starts. */
|
|
72
|
-
additionalScenes?: Phaser.Types.Scenes.SceneType[];
|
|
73
|
-
};
|
|
74
|
-
/** Creates one isolated Phaser game and resolves after the scene has run create(). */
|
|
75
|
-
declare function createHeadlessGame<TScene extends Phaser.Scene>(scene: TScene, options?: HeadlessGameOptions): Promise<HeadlessGameHost<TScene>>;
|
|
76
|
-
|
|
6
|
+
/** 将单个 Vitest 测试绑定到玩法 Ledger 的契约选项。 */
|
|
77
7
|
interface GameplayContractOptions extends HeadlessGameplayEvidenceRequirements {
|
|
78
|
-
/**
|
|
8
|
+
/** 生产玩法清单中稳定且唯一的 contract 标识。 */
|
|
79
9
|
id: string;
|
|
10
|
+
/** 当前契约负责证明的生产 Scene key。 */
|
|
11
|
+
scenes?: string[];
|
|
12
|
+
}
|
|
13
|
+
/** 在收集阶段声明静态 metadata 的 gameplayTest 选项。 */
|
|
14
|
+
interface GameplayTestOptions extends GameplayContractOptions {
|
|
15
|
+
/** 当前契约必须负责至少一个生产 Scene。 */
|
|
16
|
+
scenes: string[];
|
|
17
|
+
/** 透传给 Vitest 的非 metadata 测试选项。 */
|
|
18
|
+
testOptions?: Omit<TestOptions, "meta">;
|
|
80
19
|
}
|
|
20
|
+
/** 单个玩法测试用于绑定 host 和主动校验证据的句柄。 */
|
|
81
21
|
interface GameplayContractHandle<TScene extends Phaser.Scene> {
|
|
82
22
|
/** 将当前 contract 绑定到实际创建的 HEADLESS host。 */
|
|
83
23
|
attachHost(host: HeadlessGameHost<TScene>): void;
|
|
84
|
-
/**
|
|
24
|
+
/** 立即验证证据;通常由 onTestFinished 自动执行。 */
|
|
85
25
|
verify(): void;
|
|
86
26
|
}
|
|
27
|
+
/** registerGameplayContract 所需的最小 Vitest 测试上下文。 */
|
|
87
28
|
interface GameplayTestContext {
|
|
29
|
+
/** 当前 Vitest task 及其可序列化 metadata。 */
|
|
88
30
|
task: {
|
|
89
|
-
meta:
|
|
31
|
+
meta: {
|
|
32
|
+
gameplayContract?: GameplayContractMetadata;
|
|
33
|
+
};
|
|
90
34
|
};
|
|
35
|
+
/** 注册在测试及 afterEach 结束后执行的回调。 */
|
|
91
36
|
onTestFinished(callback: () => void | Promise<void>): void;
|
|
37
|
+
/** 注册仅在当前测试失败时执行的回调。 */
|
|
92
38
|
onTestFailed?: (callback: () => void) => void;
|
|
93
39
|
}
|
|
40
|
+
/** gameplayTest 测试函数接收的契约参数。 */
|
|
41
|
+
interface GameplayTestArguments<TScene extends Phaser.Scene> {
|
|
42
|
+
/** Vitest 原生测试上下文。 */
|
|
43
|
+
context: TestContext;
|
|
44
|
+
/** 已自动注册到当前 task 的玩法契约句柄。 */
|
|
45
|
+
contract: GameplayContractHandle<TScene>;
|
|
46
|
+
}
|
|
94
47
|
/**
|
|
95
48
|
* 将一个 gameplay contract 绑定到当前 Vitest 测试。
|
|
96
49
|
*
|
|
97
|
-
* 证据校验在 `onTestFinished` 中执行,晚于 `afterEach
|
|
98
|
-
*
|
|
99
|
-
* contract 元数据只包含可序列化值,供 reporter 在 worker 之外汇总。
|
|
50
|
+
* 证据校验在 `onTestFinished` 中执行,晚于 `afterEach`,因此通用 cleanup
|
|
51
|
+
* 可以先销毁 host。写入 metadata 的内容全部可序列化,供主线程 reporter 汇总。
|
|
100
52
|
*/
|
|
101
53
|
declare function registerGameplayContract<TScene extends Phaser.Scene>(context: GameplayTestContext, options: GameplayContractOptions): GameplayContractHandle<TScene>;
|
|
54
|
+
/**
|
|
55
|
+
* 定义一个可被全局 reporter 在执行前发现的玩法测试。
|
|
56
|
+
*
|
|
57
|
+
* 该方法在测试收集阶段写入静态 metadata,并在执行阶段自动注册同一个 contract。
|
|
58
|
+
*/
|
|
59
|
+
declare function gameplayTest<TScene extends Phaser.Scene>(name: string, options: GameplayTestOptions, run: (arguments_: GameplayTestArguments<TScene>) => void | Promise<void>): void;
|
|
60
|
+
declare module "vitest" {
|
|
61
|
+
interface TaskMeta {
|
|
62
|
+
/** 供玩法审计 reporter 读取的可序列化契约数据。 */
|
|
63
|
+
gameplayContract?: GameplayContractMetadata;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
102
66
|
|
|
103
67
|
declare function assertSceneRuntimeHealth(scene: Phaser.Scene): void;
|
|
104
68
|
declare function assertSceneInteractiveHealth(scene: Phaser.Scene): void;
|
|
105
69
|
|
|
106
|
-
/**
|
|
70
|
+
/** 返回 Bitmap Font 中缺失的非空白 UTF-16 code unit。 */
|
|
107
71
|
declare function collectMissingBitmapGlyphs(text: string, chars: Record<number, unknown>): string[];
|
|
108
|
-
/**
|
|
72
|
+
/** 在文字状态损坏时抛出适合 CI 和编码智能体处理的错误。 */
|
|
109
73
|
declare function assertSceneTextHealth(scene: Phaser.Scene): void;
|
|
110
74
|
|
|
111
|
-
export { type GameplayContractHandle,
|
|
75
|
+
export { type GameplayContractHandle, GameplayContractMetadata, type GameplayContractOptions, type GameplayTestArguments, type GameplayTestContext, type GameplayTestOptions, HeadlessGameHost, HeadlessGameplayEvidenceRequirements, assertSceneInteractiveHealth, assertSceneRuntimeHealth, assertSceneTextHealth, collectMissingBitmapGlyphs, gameplayTest, registerGameplayContract };
|