@forgeax/engine-devkit 0.1.4 → 0.1.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/README.md +162 -5
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/cli-output.unit.test.d.ts +2 -0
- package/dist/__tests__/cli-output.unit.test.d.ts.map +1 -0
- package/dist/__tests__/engine-binding.unit.test.d.ts +2 -0
- package/dist/__tests__/engine-binding.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gltf-source-key-diagnostics.integration.test.d.ts +2 -0
- package/dist/__tests__/gltf-source-key-diagnostics.integration.test.d.ts.map +1 -0
- package/dist/__tests__/preview-port.integration.test.d.ts +2 -0
- package/dist/__tests__/preview-port.integration.test.d.ts.map +1 -0
- package/dist/__tests__/rhi-debug-build-graph.integration.test.d.ts +2 -0
- package/dist/__tests__/rhi-debug-build-graph.integration.test.d.ts.map +1 -0
- package/dist/__tests__/sdk-update.unit.test.d.ts +2 -0
- package/dist/__tests__/sdk-update.unit.test.d.ts.map +1 -0
- package/dist/__tests__/software-browser-session.unit.test.d.ts +2 -0
- package/dist/__tests__/software-browser-session.unit.test.d.ts.map +1 -0
- package/dist/__tests__/software-capture-pixels.unit.test.d.ts +2 -0
- package/dist/__tests__/software-capture-pixels.unit.test.d.ts.map +1 -0
- package/dist/__tests__/software-capture.unit.test.d.ts +2 -0
- package/dist/__tests__/software-capture.unit.test.d.ts.map +1 -0
- package/dist/assets.d.ts.map +1 -1
- package/dist/bootstrap-commands.d.ts.map +1 -1
- package/dist/cli-output.d.ts +4 -0
- package/dist/cli-output.d.ts.map +1 -0
- package/dist/cli.mjs +1863 -819
- package/dist/cli.mjs.map +1 -1
- package/dist/commands.d.ts +2 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/engine-binding.d.ts +58 -0
- package/dist/engine-binding.d.ts.map +1 -0
- package/dist/host/__tests__/bootstrap-root-owner.test-d.d.ts +2 -0
- package/dist/host/__tests__/bootstrap-root-owner.test-d.d.ts.map +1 -0
- package/dist/host/project-bootstrap.d.ts +4 -2
- package/dist/host/project-bootstrap.d.ts.map +1 -1
- package/dist/host/resource-bootstrap.d.ts +5 -3
- package/dist/host/resource-bootstrap.d.ts.map +1 -1
- package/dist/host.d.ts +2 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +1714 -862
- package/dist/index.mjs.map +1 -1
- package/dist/project.d.ts +0 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/rhi-debug/cli-context.d.ts.map +1 -1
- package/dist/rhi-debug/operations.d.ts +3 -3
- package/dist/rhi-debug/operations.d.ts.map +1 -1
- package/dist/sdk-bootstrap.d.ts +9 -0
- package/dist/sdk-bootstrap.d.ts.map +1 -1
- package/dist/sdk-cli.mjs +193 -25
- package/dist/sdk-cli.mjs.map +1 -1
- package/dist/sdk-install.d.ts.map +1 -1
- package/dist/sdk-update.d.ts +23 -0
- package/dist/sdk-update.d.ts.map +1 -0
- package/dist/software-capture.d.ts +123 -0
- package/dist/software-capture.d.ts.map +1 -0
- package/dist/tools/benchmark/__tests__/benchmark-vocabulary-owner.test-d.d.ts +2 -0
- package/dist/tools/benchmark/__tests__/benchmark-vocabulary-owner.test-d.d.ts.map +1 -0
- package/dist/tools/benchmark/harness.d.ts.map +1 -1
- package/dist/tools/browser-host.d.ts.map +1 -1
- package/dist/tools/commands.d.ts +5 -0
- package/dist/tools/commands.d.ts.map +1 -1
- package/dist/tools/native-preview.d.ts.map +1 -1
- package/dist/types.d.ts +28 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +32 -31
- package/dist/__tests__/tool-migration.test.d.ts +0 -2
- package/dist/__tests__/tool-migration.test.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -12,6 +12,9 @@ owns rendering, RHI events, replay backends, and preview execution.
|
|
|
12
12
|
## Navigation
|
|
13
13
|
|
|
14
14
|
- [CLI and catalog](#cli-and-catalog)
|
|
15
|
+
- [Browser compositor capture](#browser-compositor-capture)
|
|
16
|
+
- [Engine source binding](#engine-source-binding)
|
|
17
|
+
- [Startup diagnostics](#startup-diagnostics)
|
|
15
18
|
- [RHI-debug operations](#rhi-debug-operations)
|
|
16
19
|
- [Authoring preview](#authoring-preview)
|
|
17
20
|
- [Project authority](#project-authority)
|
|
@@ -22,7 +25,7 @@ owns rendering, RHI events, replay backends, and preview execution.
|
|
|
22
25
|
The normal project commands remain available through the `forgeax` CLI:
|
|
23
26
|
|
|
24
27
|
```text
|
|
25
|
-
forgeax new [directory] [--template empty|game-
|
|
28
|
+
forgeax new [directory] [--template empty|game-3d]
|
|
26
29
|
forgeax init
|
|
27
30
|
forgeax doctor
|
|
28
31
|
forgeax skill install
|
|
@@ -30,17 +33,23 @@ forgeax skill verify
|
|
|
30
33
|
forgeax test
|
|
31
34
|
forgeax dev
|
|
32
35
|
forgeax build
|
|
36
|
+
forgeax capture --backend auto --require-ui --output artifacts/capture/game-ui.png --json
|
|
33
37
|
forgeax preview
|
|
34
38
|
forgeax package [--output release/game-web.zip]
|
|
35
39
|
forgeax list --json
|
|
36
40
|
forgeax describe project.build --json
|
|
37
41
|
forgeax run project.build --input request.json --json
|
|
38
42
|
forgeax exec program.mjs --json
|
|
39
|
-
forgeax run rhi.
|
|
40
|
-
forgeax run rhi.
|
|
41
|
-
forgeax run rhi.inspect --artifact {ArtifactRef} --work-index {workIndex}
|
|
43
|
+
forgeax run rhi.summary --artifact .forgeax-debug/{runId}/frame.rhitape --digest {sha256}
|
|
44
|
+
forgeax run rhi.inspect --artifact .forgeax-debug/{runId}/frame.rhitape --digest {sha256} --work-index {workIndex}
|
|
42
45
|
```
|
|
43
46
|
|
|
47
|
+
> [!IMPORTANT]
|
|
48
|
+
> `forgeax dev` is a source-development server and `forgeax preview` is a
|
|
49
|
+
> verified static `dist/` server. Their `--json` startup envelopes expose
|
|
50
|
+
> `mode`, `serves`, and the current `rhi.capture` capability. Neither command
|
|
51
|
+
> silently invents a live capture attachment.
|
|
52
|
+
|
|
44
53
|
Static deployment is an Engine-owned build product. A publishing host supplies
|
|
45
54
|
the project root, public URL base, and dedicated output directory; DevKit owns
|
|
46
55
|
the generated host, asset cooking, shader compilation, Pack index, and
|
|
@@ -78,20 +87,168 @@ for local HTTP acceptance. Opening the archived `index.html` through `file://` i
|
|
|
78
87
|
schema output. The operation manifest is the single discovery and recovery
|
|
79
88
|
surface for RHI-debug.
|
|
80
89
|
|
|
90
|
+
## Browser compositor capture
|
|
91
|
+
|
|
92
|
+
> [!IMPORTANT]
|
|
93
|
+
> forgeax capture is a development visual-evidence path. It uses the host browser adapter when
|
|
94
|
+
> available and can explicitly use a software lane on machines with no physical GPU or display. It
|
|
95
|
+
> is not a player or release-acceptance gate.
|
|
96
|
+
|
|
97
|
+
The command starts the source-development host on an ephemeral loopback port, creates an Xvfb display
|
|
98
|
+
when `$DISPLAY` is absent on Linux, launches a real Chromium browser, waits for an engine frame signal
|
|
99
|
+
and non-flat **canvas** pixels, then takes a Playwright **page screenshot**. A page screenshot
|
|
100
|
+
composites the WebGPU canvas with normal DOM and open ShadowRoot UI;
|
|
101
|
+
`canvas.toDataURL()` cannot provide that proof. `--wait-ms` is an additional settle interval after the
|
|
102
|
+
first non-flat canvas frame, not a guess for CPU startup time.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
forgeax capture --backend software --require-ui \
|
|
106
|
+
--output artifacts/capture/game-ui.png \
|
|
107
|
+
--width 1280 --height 720 --wait-ms 4000 --json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The adjacent `game-ui.json` is the schema-v2 run manifest. Its run-level fields record the browser,
|
|
111
|
+
viewport, X display, lavapipe ICD discovery, and browser errors; its ordered `captures[]` rows record
|
|
112
|
+
each PNG digest, checkpoint, actual `GPUAdapterInfo`, canvas/UI witnesses, and canvas-only sampled luma
|
|
113
|
+
backend auto (the default) tries the normal browser adapter and falls back to the software lane only
|
|
114
|
+
when WebGPU is unavailable. backend hardware requires a non-software adapter; backend software pins
|
|
115
|
+
SwiftShader/lavapipe-compatible browser flags. The old --software spelling remains a compatibility
|
|
116
|
+
alias for backend software.
|
|
117
|
+
|
|
118
|
+
range. The witness screenshot temporarily hides every non-canvas element, so a visible HUD cannot
|
|
119
|
+
disguise a black 3D frame; the written PNG remains the complete page compositor output.
|
|
120
|
+
`--require-ui` requires at least one mounted child under the generated host's `#game-ui` root; unrelated
|
|
121
|
+
Engine or browser ShadowRoots are only diagnostics and cannot satisfy the gate. A uniform black frame
|
|
122
|
+
also fails even when canvas and adapter structure exist. Use `--browser` only when Chrome Beta is not at
|
|
123
|
+
`/opt/google/chrome-beta/chrome`.
|
|
124
|
+
|
|
125
|
+
The browser context fixes the viewport and screen size, DPR 1, sRGB colour profile, light colour
|
|
126
|
+
scheme, `en-US` locale, UTC timezone, and waits for `document.fonts.ready`. Projects must ship the same
|
|
127
|
+
Web font files on every machine; a system-font fallback is not a colour or layout parity contract.
|
|
128
|
+
|
|
129
|
+
For local/remote pixel or colour comparison, add `--deterministic`. The command navigates with
|
|
130
|
+
`?forgeaxCapture=1`. The Engine App publishes
|
|
131
|
+
`document.documentElement.dataset.forgeaxFrameSubmitted` (the monotonic frame id) after the Renderer
|
|
132
|
+
crosses its real queue-submit boundary and dispatches `forgeax:frame-submitted` on the canvas. DevKit
|
|
133
|
+
waits for that engine signal and a non-flat canvas crop before consuming the game's
|
|
134
|
+
`document.documentElement.dataset.forgeaxCaptureReady` checkpoint; it never guesses startup time. The
|
|
135
|
+
game remains the time authority: in capture mode it must pin its random seed, viewport-independent
|
|
136
|
+
state, local web fonts, and logical time/frame, render that state, then publish the ready marker. A
|
|
137
|
+
wall-clock delay is useful only as extra settle and is not parity evidence.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
forgeax capture --backend software --require-ui --deterministic \
|
|
141
|
+
--width 1280 --height 720 --output artifacts/capture/parity.png --json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Persistent playthrough capture
|
|
145
|
+
|
|
146
|
+
`capture` is the one-shot adapter over the same browser owner. For one game boot followed by input,
|
|
147
|
+
assertions, and multiple compositor captures, compose the persistent session through `forgeax exec`:
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
export default async function playthrough({ browser }) {
|
|
151
|
+
const session = await browser.open({
|
|
152
|
+
backend: 'auto',
|
|
153
|
+
deterministic: true,
|
|
154
|
+
requireUi: true,
|
|
155
|
+
outputDir: 'artifacts/playthrough/boss-flow',
|
|
156
|
+
});
|
|
157
|
+
try {
|
|
158
|
+
const { page } = session;
|
|
159
|
+
await page.getByRole('button', { name: 'Start' }).click();
|
|
160
|
+
const spawn = await session.capture('spawn');
|
|
161
|
+
await page.keyboard.press('KeyW');
|
|
162
|
+
const arena = await session.capture('arena');
|
|
163
|
+
await page.getByRole('button', { name: 'Cast' }).click();
|
|
164
|
+
const bossHit = await session.capture('boss-hit');
|
|
165
|
+
return { report: session.reportPath, captures: [spawn, arena, bossHit] };
|
|
166
|
+
} finally {
|
|
167
|
+
await session.close();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
forgeax exec tests/boss-playthrough.mjs --json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The Engine App frame signal and the game checkpoint are separate composable authorities:
|
|
177
|
+
`session.capture('boss-hit')` waits for the engine frame signal, then the exact
|
|
178
|
+
`document.documentElement.dataset.forgeaxCaptureReady` value and non-flat pixels. Playwright remains
|
|
179
|
+
the input/assertion owner through the unwrapped `session.page`.
|
|
180
|
+
DevKit owns Xvfb/Chrome/Vite lifecycle, compositor stabilization, PNG validation, numbering, digests,
|
|
181
|
+
and one `run.json`. A live `Page` or session may not be returned from the program; `exec` accepts only
|
|
182
|
+
JSON-safe results and closes leaked sessions on exit.
|
|
183
|
+
|
|
184
|
+
| Browser backend | Owner | What it proves |
|
|
185
|
+
|:--|:--|:--|
|
|
186
|
+
| Mesa lavapipe | Dawn/Node smoke and explicit GPUTexture readback | Offscreen render pixels without a display; no HTML UI |
|
|
187
|
+
| Chrome hardware adapter | forgeax capture --backend hardware | Browser compositor pixels on the selected adapter plus HTML/Shadow DOM |
|
|
188
|
+
| Chrome SwiftShader under Xvfb | forgeax capture --backend software or forgeax exec browser session | Browser WebGPU canvas plus HTML/Shadow DOM in ordered viewport PNGs |
|
|
189
|
+
|
|
190
|
+
> [!CAUTION]
|
|
191
|
+
> Software pixels are iteration evidence. They do not prove physical-GPU performance, vendor-driver
|
|
192
|
+
> behavior, HDR-display output, or release visual acceptance.
|
|
193
|
+
|
|
194
|
+
## Engine source binding
|
|
195
|
+
|
|
196
|
+
Built-package games normally resolve @forgeax/engine from the registry. A source-development game
|
|
197
|
+
can bind the same dependency name to a checked-out Engine workspace without editing its manifest:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
forgeax engine status --json
|
|
201
|
+
forgeax engine use-local ../forgeax-engine --json
|
|
202
|
+
forgeax engine doctor --json
|
|
203
|
+
forgeax engine unlink --json
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The binding is stored only in .forgeax/engine-binding.json; file absence is the single normal
|
|
207
|
+
registry/SDK state. The project manifest remains the dependency authority. engine doctor fails
|
|
208
|
+
closed for a pnpm workspace dependency that npm cannot consume, for an unbuilt local workspace, or
|
|
209
|
+
for a missing SDK package. Status derives its workspace digest from the actual built entry bytes and
|
|
210
|
+
reports their newest modification time. engine unlink removes the sole override and returns to the
|
|
211
|
+
normal registry/SDK resolution path.
|
|
212
|
+
|
|
81
213
|
Physical realm consumers use `createRealmDispatch`. Each descriptor is routed to
|
|
82
214
|
one owner for its declared `build`, `host`, or `engine` realm. A missing owner
|
|
83
215
|
returns `tool-capability-unavailable` with the realm in `detail`; it never falls
|
|
84
216
|
through to another realm.
|
|
85
217
|
|
|
218
|
+
## Startup diagnostics
|
|
219
|
+
|
|
220
|
+
The generated game host renders structured startup failures recursively instead
|
|
221
|
+
of coercing thrown objects to `[object Object]`. It preserves `name`, `message`,
|
|
222
|
+
`code`, `expected`, `hint`, `reason`, and bounded nested
|
|
223
|
+
`cause/detail/webgpuError/wgpuError/error` fields. Generic objects use bounded
|
|
224
|
+
JSON serialization and circular objects receive an explicit diagnostic.
|
|
225
|
+
|
|
226
|
+
When the resulting evidence mentions WebGPU, adapter absence, or no usable
|
|
227
|
+
backend, the host also states that ForgeaX supports browser WebGPU and a
|
|
228
|
+
wgpu/WebGL2 fallback. This note is intentionally not a fallback decision: the
|
|
229
|
+
structured cause remains the authority. A publishing Agent must not infer
|
|
230
|
+
unsupported hardware, swallow the entry error, or inject a replacement Canvas
|
|
231
|
+
game merely to remove an uncaught exception.
|
|
232
|
+
|
|
86
233
|
## RHI-debug operations
|
|
87
234
|
|
|
235
|
+
The operation manifest describes the complete host contract, but a standalone
|
|
236
|
+
CLI process does not own a running browser App. Consequently,
|
|
237
|
+
`forgeax run rhi.capture --json` is a structured capability probe and returns
|
|
238
|
+
`capture-unavailable` until a recorder-enabled live host supplies the
|
|
239
|
+
`rhiCapture` eval root. Use the browser live bridge described by the
|
|
240
|
+
`forgeax-engine-cli` skill to invoke that root; preserve the resulting tape's
|
|
241
|
+
`digest` and `path` for the offline commands below. `rhi.summary` and
|
|
242
|
+
`rhi.inspect` remain directly executable because they consume the persisted
|
|
243
|
+
artifact rather than live App state.
|
|
244
|
+
|
|
88
245
|
```mermaid
|
|
89
246
|
sequenceDiagram
|
|
90
247
|
participant AI as "AI or CLI"
|
|
91
248
|
participant H as "Host"
|
|
92
249
|
participant D as "DevKit"
|
|
93
250
|
participant R as "Fresh replay backend"
|
|
94
|
-
AI->>H: "
|
|
251
|
+
AI->>H: "rhiCapture.captureFrame through the live host"
|
|
95
252
|
H-->>AI: "one ArtifactRef"
|
|
96
253
|
AI->>D: "rhi.summary + ArtifactRef"
|
|
97
254
|
D-->>AI: "FrameModel and workIndex"
|