-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCanvas2DGameCompilerTarget.ts
More file actions
125 lines (117 loc) · 4.66 KB
/
Copy pathCanvas2DGameCompilerTarget.ts
File metadata and controls
125 lines (117 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* @holoscript/core/compiler — Canvas2DGameCompiler (registered target)
*
* The first-class, RBAC-aware compiler class for the native 2D-canvas-game
* target (ANS: /compile/gamedev/canvas2d-game). It is a thin CompilerBase
* wrapper over the dependency-free codegen in ./Canvas2DGameCompiler so that:
* - the pure codegen stays importable from lightweight build scripts (no RBAC
* graph pulled in), AND
* - this target plugs into the standard compiler dispatch + UCAN/RBAC
* enforcement like every other CompilerName.
*
* Gate 2 of the native-2D-compiler build. Access validation is a no-op when no
* token is supplied (dev/test), matching the rest of the compiler family.
*/
import { CompilerBase, type BaseCompilerOptions, type CompilerToken } from './CompilerBase';
import type { HoloComposition } from '../parser/HoloCompositionTypes';
import {
compileCanvas2DGame,
type CG2DComposition,
type Canvas2DGameOptions,
} from './Canvas2DGameCompiler';
// ── Minimal view of the parser AST this target reads (loose by design) ───────
interface RawProp {
key: string;
value: unknown;
}
interface RawTrait {
name: string;
config?: Record<string, unknown>;
}
interface RawObject {
name: string;
template?: string;
state?: Record<string, unknown>;
traits?: RawTrait[];
properties?: RawProp[];
}
interface RawGroup {
name: string;
properties?: RawProp[];
objects?: RawObject[];
}
interface RawComposition {
name?: string;
templates?: Array<{ name: string; traits?: RawTrait[] }>;
spatialGroups?: RawGroup[];
environment?: { properties?: RawProp[] };
}
function propOf(node: { properties?: RawProp[] } | undefined, key: string, dflt: unknown): unknown {
return (node?.properties || []).find((p) => p.key === key)?.value ?? dflt;
}
/**
* Flatten the parser AST (positions/colors in `properties`, traits on templates)
* into the flat CG2DComposition the codegen consumes. Shared logic with
* examples/gold-game/gold-canvas2d-build.mjs.
*/
export function normalizeHoloComposition(raw: RawComposition): CG2DComposition {
return {
name: raw.name,
templates: (raw.templates || []).map((t) => ({
name: t.name,
traits: (t.traits || []).map((tr) => ({ name: tr.name, config: tr.config || {} })),
})),
spatialGroups: (raw.spatialGroups || []).map((g) => ({
name: g.name,
origin: propOf(g, 'origin', [0, 0, 0]) as number[],
objects: (g.objects || []).map((o) => ({
name: o.name,
template: o.template,
position: propOf(o, 'position', [0, 0, 0]) as number[],
color: propOf(o, 'color', '#cccccc') as string,
state: o.state || {},
traits: (o.traits || []).map((tr) => ({ name: tr.name, config: tr.config || {} })),
})),
})),
environment: {
gravity: propOf(raw.environment, 'gravity', [0, -9.81, 0]) as number[],
timeLimit: propOf(raw.environment, 'timeLimit', undefined),
startingHearts: propOf(raw.environment, 'startingHearts', undefined),
muteDefault: propOf(raw.environment, 'muteDefault', undefined),
musicVolume: propOf(raw.environment, 'musicVolume', undefined),
sfxVolume: propOf(raw.environment, 'sfxVolume', undefined),
musicTempo: propOf(raw.environment, 'musicTempo', undefined),
},
};
}
export type Canvas2DGameCompilerOptions = Canvas2DGameOptions & BaseCompilerOptions;
export class Canvas2DGameCompiler extends CompilerBase {
protected readonly compilerName = 'Canvas2DGameCompiler';
private readonly ctorOptions: Canvas2DGameCompilerOptions & { sceneJson?: string };
/**
* Options passed at construction (how ExportManager/CompilerFactory supplies
* them — `exportDirect` calls `compile(composition)` with no per-call options).
*/
constructor(options: Canvas2DGameCompilerOptions & { sceneJson?: string } = {}) {
super();
this.ctorOptions = options;
}
/**
* Compile a composition to a self-contained, offline, playable HTML game.
* `options.sceneJson` (when present) is embedded verbatim for the modality
* digest contract; otherwise the derived spec is embedded. Per-call options
* override constructor options.
*/
// @ts-expect-error widened options param during migration (matches Native2DCompiler)
compile(
composition: HoloComposition,
agentToken?: CompilerToken,
outputPath?: string,
options?: Canvas2DGameCompilerOptions & { sceneJson?: string }
): string {
this.validateCompilerAccess(agentToken, outputPath);
const merged = { ...this.ctorOptions, ...(options || {}) };
const normalized = normalizeHoloComposition(composition as unknown as RawComposition);
return compileCanvas2DGame(normalized, merged, merged.sceneJson);
}
}