@volter/project 0.5.211 → 0.5.212
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/NOTICE +2 -2
- package/README.md +8 -15
- package/package.json +5 -26
- package/schemas/volter-project.schema.json +33 -145
- package/schemas/volter-settings.schema.json +11 -49
- package/src/adapter/adapter-module.ts +204 -465
- package/src/adapter/adapter-surface.ts +4 -32
- package/src/adapter/authoring-seam-contract.ts +7 -24
- package/src/adapter/authoring.ts +126 -265
- package/src/adapter/editor-looks.ts +96 -127
- package/src/adapter/finders/registry.ts +6 -21
- package/src/adapter/host-context.ts +17 -72
- package/src/adapter/index.ts +4 -77
- package/src/adapter/manifest-interpreter.ts +7 -50
- package/src/adapter/physics-adapter-2d.ts +4 -21
- package/src/adapter/root-adapter.ts +37 -111
- package/src/adapter/root-seam-contract.ts +3 -6
- package/src/adapter/root-stacking.ts +4 -46
- package/src/adapter/seam-evidence.ts +0 -16
- package/src/adapter/system-adapter.ts +24 -656
- package/src/adapter/system-seam-contract.ts +1 -91
- package/src/adapter/transform.ts +4 -3
- package/src/adapter/workspace-arrangement.ts +29 -49
- package/src/manifest/editor-port.ts +10 -36
- package/src/manifest/filename.ts +3 -42
- package/src/manifest/load-file.ts +9 -15
- package/src/manifest/load.ts +44 -179
- package/src/manifest/locate.ts +6 -29
- package/src/manifest/schema.ts +155 -427
- package/src/semver.ts +16 -0
- package/src/settings/keys.ts +9 -11
- package/src/settings/schema.ts +55 -44
- package/schemas/engine-api.json +0 -57
- package/schemas/engine-api.md +0 -22
- package/src/adapter/binding.ts +0 -445
- package/src/adapter/debug-registry-ref.ts +0 -19
- package/src/adapter/frame-capture.ts +0 -80
- package/src/adapter/ingest/contract-system-slots.ts +0 -28
- package/src/adapter/ingest/game-contract-seams.ts +0 -86
- package/src/adapter/ingest/game-contract.ts +0 -506
- package/src/adapter/ingest/mount-readiness.ts +0 -140
- package/src/adapter/loop-gate-report.ts +0 -53
- package/src/adapter/native-entry-surface.ts +0 -100
- package/src/adapter/render-audio.ts +0 -20
- package/src/adapter/render-memory.ts +0 -34
- package/src/adapter/renderer-config.ts +0 -84
- package/src/adapter/system-slot.ts +0 -301
- package/src/core/system-phase.ts +0 -52
- package/src/inspection.ts +0 -281
- package/src/manifest/configuration-kinds.ts +0 -241
- package/src/manifest/kind-modules.ts +0 -58
- package/src/manifest/runtime-environment.ts +0 -48
package/NOTICE
CHANGED
|
@@ -2,5 +2,5 @@ Copyright 2026 Volter AI, Inc.
|
|
|
2
2
|
|
|
3
3
|
The project contract was transferred from the Apache-2.0 packages of
|
|
4
4
|
volter-ai/volter-engine and is developed in the public volter-ai/editor
|
|
5
|
-
repository. Original source
|
|
6
|
-
|
|
5
|
+
repository. Original source revision:
|
|
6
|
+
cf9cb8e22dd7ae5709ed0dd8a46dd6f16d1e4945. LICENSE contains the Apache-2.0 text.
|
package/README.md
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Volter project contracts
|
|
2
2
|
|
|
3
3
|
Project manifests, adapter surfaces, authoring contracts and settings schemas
|
|
4
|
-
|
|
5
|
-
editor host
|
|
4
|
+
of the Volter editor. This package declares shared data and APIs independently of
|
|
5
|
+
an editor host or a rendering implementation.
|
|
6
6
|
|
|
7
|
-
Adapter editor
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
Adapter editor defaults live beside their schemas in `src/adapter/editor-looks.ts`
|
|
8
|
+
and `workspace-arrangement.ts`. The SDK exposes these same types to contribution
|
|
9
|
+
authors. Each integration owns the library-specific implementation behind its
|
|
10
|
+
host surface and authoring adapters.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
host contexts. These shared contexts do not expose the old concrete `Game`.
|
|
14
|
-
Existing native Three/Pixi surface types remain explicit; this migration does
|
|
15
|
-
not claim that the contracts are renderer-neutral.
|
|
16
|
-
|
|
17
|
-
Run `npm run typecheck -w @volter/project` through the active World.
|
|
18
|
-
There are no compiler aliases into another checkout. See the root WORK.md for
|
|
19
|
-
remaining migration and release gates. This package is private during migration.
|
|
12
|
+
Run `npm run typecheck -w @volter/project` from the repository root.
|
package/package.json
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
"name": "@volter/project",
|
|
3
3
|
"author": "Volter AI, Inc.",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"version": "0.5.
|
|
5
|
+
"version": "0.5.212",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
9
|
"description": "Project manifests and adapter contracts for Volter Editor.",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"volter",
|
|
12
|
-
"
|
|
12
|
+
"editor",
|
|
13
13
|
"manifest",
|
|
14
14
|
"adapter"
|
|
15
15
|
],
|
|
@@ -22,28 +22,7 @@
|
|
|
22
22
|
"exports": {
|
|
23
23
|
"./adapter": "./src/adapter/index.ts",
|
|
24
24
|
"./package.json": "./package.json",
|
|
25
|
-
"./*":
|
|
26
|
-
"types": [
|
|
27
|
-
"./src/*.ts",
|
|
28
|
-
"./src/*.tsx",
|
|
29
|
-
"./src/*/index.ts",
|
|
30
|
-
"./src/*/index.tsx"
|
|
31
|
-
],
|
|
32
|
-
"default": "./src/*"
|
|
33
|
-
},
|
|
34
|
-
"./manifest/locate": "./src/manifest/locate.ts",
|
|
35
|
-
"./manifest/editor-port": "./src/manifest/editor-port.ts",
|
|
36
|
-
"./manifest/filename": "./src/manifest/filename.ts",
|
|
37
|
-
"./manifest/schema": "./src/manifest/schema.ts",
|
|
38
|
-
"./manifest/load-file": "./src/manifest/load-file.ts",
|
|
39
|
-
"./manifest/kind-modules": "./src/manifest/kind-modules.ts",
|
|
40
|
-
"./manifest/configuration-kinds": "./src/manifest/configuration-kinds.ts",
|
|
41
|
-
"./manifest/runtime-environment": "./src/manifest/runtime-environment.ts",
|
|
42
|
-
"./inspection": "./src/inspection.ts",
|
|
43
|
-
"./settings/schema": "./src/settings/schema.ts",
|
|
44
|
-
"./manifest/load": "./src/manifest/load.ts",
|
|
45
|
-
"./adapter/manifest-interpreter": "./src/adapter/manifest-interpreter.ts",
|
|
46
|
-
"./adapter/adapter-module": "./src/adapter/adapter-module.ts"
|
|
25
|
+
"./*": "./src/*.ts"
|
|
47
26
|
},
|
|
48
27
|
"files": [
|
|
49
28
|
"src",
|
|
@@ -54,11 +33,11 @@
|
|
|
54
33
|
"node": ">=22.0.0"
|
|
55
34
|
},
|
|
56
35
|
"dependencies": {
|
|
57
|
-
"semver": "^7.8.5",
|
|
58
36
|
"zod": "^4.3.6"
|
|
59
37
|
},
|
|
60
38
|
"scripts": {
|
|
61
|
-
"typecheck": "tsc -p tsconfig.json"
|
|
39
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
40
|
+
"generate-schema": "node --experimental-strip-types scripts/generate-schema.mjs"
|
|
62
41
|
},
|
|
63
42
|
"peerDependencies": {
|
|
64
43
|
"react": "^19.0.0"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$comment": "
|
|
2
|
+
"$comment": "Maintained by hand beside the zod schema in src/adapter/adapter-module.ts and src/manifest/schema.ts — keep the two in step",
|
|
3
3
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
@@ -8,13 +8,12 @@
|
|
|
8
8
|
"type": "string"
|
|
9
9
|
},
|
|
10
10
|
"manifestVersion": {
|
|
11
|
-
"type": "
|
|
12
|
-
"
|
|
13
|
-
"description": "Manifest file format version (v2 clean roots)"
|
|
11
|
+
"type": "integer",
|
|
12
|
+
"description": "The manifest format version the project was written with (this editor writes 2); a manifest is read by its shape, never refused for its number"
|
|
14
13
|
},
|
|
15
14
|
"name": {
|
|
16
15
|
"type": "string",
|
|
17
|
-
"description": "
|
|
16
|
+
"description": "Project display name"
|
|
18
17
|
},
|
|
19
18
|
"appId": {
|
|
20
19
|
"description": "Stable reverse-domain application id used by packaged targets",
|
|
@@ -22,14 +21,14 @@
|
|
|
22
21
|
},
|
|
23
22
|
"version": {
|
|
24
23
|
"type": "string",
|
|
25
|
-
"description": "The
|
|
24
|
+
"description": "The project's own version"
|
|
26
25
|
},
|
|
27
26
|
"engine": {
|
|
28
27
|
"type": "object",
|
|
29
28
|
"properties": {
|
|
30
29
|
"version": {
|
|
31
30
|
"type": "string",
|
|
32
|
-
"description": "Exact @volter/project semver this
|
|
31
|
+
"description": "Exact @volter/project semver this project was scaffolded/last upgraded against — an identity pin, not a range"
|
|
33
32
|
}
|
|
34
33
|
},
|
|
35
34
|
"required": [
|
|
@@ -45,10 +44,10 @@
|
|
|
45
44
|
"properties": {
|
|
46
45
|
"id": {
|
|
47
46
|
"type": "string",
|
|
48
|
-
"description": "Unique id for this root within the manifest (enforced-unique, D-V6 —
|
|
47
|
+
"description": "Unique id for this root within the manifest (enforced-unique, D-V6 — ProjectManifestSchema.roots rejects duplicates)"
|
|
49
48
|
},
|
|
50
49
|
"description": {
|
|
51
|
-
"description": "Optional one-line description of this root's
|
|
50
|
+
"description": "Optional one-line description of this root's content",
|
|
52
51
|
"type": "string"
|
|
53
52
|
},
|
|
54
53
|
"adapter": {
|
|
@@ -57,7 +56,7 @@
|
|
|
57
56
|
{
|
|
58
57
|
"type": "string",
|
|
59
58
|
"enum": [
|
|
60
|
-
"
|
|
59
|
+
"stage",
|
|
61
60
|
"canvas",
|
|
62
61
|
"dom"
|
|
63
62
|
]
|
|
@@ -67,12 +66,12 @@
|
|
|
67
66
|
"properties": {
|
|
68
67
|
"module": {
|
|
69
68
|
"type": "string",
|
|
70
|
-
"description": "
|
|
69
|
+
"description": "Project-folder-relative path to a custom adapter module (trust boundary)"
|
|
71
70
|
},
|
|
72
71
|
"surface": {
|
|
73
72
|
"type": "string",
|
|
74
73
|
"enum": [
|
|
75
|
-
"
|
|
74
|
+
"stage",
|
|
76
75
|
"canvas",
|
|
77
76
|
"dom"
|
|
78
77
|
],
|
|
@@ -91,25 +90,21 @@
|
|
|
91
90
|
"surface": {
|
|
92
91
|
"type": "string",
|
|
93
92
|
"enum": [
|
|
94
|
-
"
|
|
93
|
+
"stage",
|
|
95
94
|
"canvas",
|
|
96
95
|
"dom"
|
|
97
96
|
],
|
|
98
|
-
"description": "Native surface captured from the unmodified
|
|
97
|
+
"description": "Native surface captured from the unmodified project"
|
|
99
98
|
},
|
|
100
99
|
"ingest": {
|
|
101
100
|
"type": "object",
|
|
102
101
|
"properties": {
|
|
103
|
-
"contractShim": {
|
|
104
|
-
"description": "Project-relative path to a HOST-ADDED ES module that declares this game's `window.volterGame` contract (adapter/ingest/game-contract.ts) WITHOUT editing a vendored byte — the pristine-copy door. The host imports it immediately BEFORE the game's own entry module, in the editor's realm. TIMING CONTRACT, which a shim author must obey: because it runs before the game`s entry, it MUST assign `window.volterGame` SYNCHRONOUSLY at top level. Anything that needs the game`s own modules must be LAZY: a dynamic `import()` INSIDE each verb/provider closure, resolved at call time. Importing a game module eagerly from the shim would evaluate it ahead of the game`s own entry and reorder its module side effects. Every such `import()` MUST take a STRING LITERAL, never a variable/table lookup. A variable specifier is not statically analyzable, so the dev server leaves it alone and it resolves at runtime against the shim`s own `/@fs/` url — while the game`s entry has had ITS relative imports rewritten to whatever url the server considers canonical for those files. Module identity is per-url, so the shim silently binds a SECOND, freshly-evaluated copy of the whole game and every provider reports a game that never started. Measured on a vendored three game: 285 world segments through the game`s own graph, 0 through the shim`s, and no error anywhere.",
|
|
105
|
-
"type": "string"
|
|
106
|
-
},
|
|
107
102
|
"dataWriter": {
|
|
108
|
-
"description": "Project-relative path to a HOST-ADDED ES module that writes this
|
|
103
|
+
"description": "Project-relative path to a HOST-ADDED ES module that writes this project's own DATA file back — the sibling of a source write for a project whose authorable truth is not source. A level-based project places its enemies, pickups and objectives in binary records inside a level file, reaching no source literal, so an authored move of one is an edit to that file and nothing else can write it. The module declares two exports and the host knows nothing else about it: `dataFile` (a project-relative string — the ONE file this writer edits) and `planDataEdit(bytes, {record, property, baseline, next})`, which returns `{changed: true, bytes}` or `{changed: false, reason}` and may be async. It is loaded in the editor realm beside the project, so it may `import()` the project's own modules to resolve what only a running project knows (a level writer asks the project`s own spatial lookup which cell a moved object landed in, and refuses \"outside the level\" rather than writing data the project would read back wrong). It NEVER fabricates: a record it cannot address, or a property it does not model, is a named refusal. An object is anchored to a record by carrying `userData.volterRecordIndex` — the project declares that identity itself (a recorded patch or a shim); the host never infers one.",
|
|
109
104
|
"type": "string"
|
|
110
105
|
},
|
|
111
106
|
"assets": {
|
|
112
|
-
"description": "Path-substring -> served-URL rewrites for this ingested
|
|
107
|
+
"description": "Path-substring -> served-URL rewrites for this ingested project",
|
|
113
108
|
"type": "object",
|
|
114
109
|
"propertyNames": {
|
|
115
110
|
"type": "string"
|
|
@@ -119,7 +114,7 @@
|
|
|
119
114
|
}
|
|
120
115
|
},
|
|
121
116
|
"moduleAliases": {
|
|
122
|
-
"description": "The
|
|
117
|
+
"description": "The project's OWN bundler path aliases, restated as a mounting fact so its source resolves unedited. A project built with its own Vite/webpack config routinely imports itself through an alias (`~/lib/config`, `@/store/x`); the editor boots Vite from the ENGINE's config and never reads a project's own, so without this every such import is an unresolvable specifier and the mount dies at transform time. Key = the specifier PREFIX exactly as the project writes it (\"~/\"); value = the repo-root-relative directory it means (\"/vendor/<id>/src/\"). SELF-SCOPING: the host honors an entry only for importers inside the vendored folder the value points into, so one project's alias can never capture another module's import. Rewriting the project's own imports instead would be a large non-seam-shaped diff against unmodified source — this declares the fact rather than editing it away.",
|
|
123
118
|
"type": "object",
|
|
124
119
|
"propertyNames": {
|
|
125
120
|
"type": "string"
|
|
@@ -129,19 +124,19 @@
|
|
|
129
124
|
}
|
|
130
125
|
},
|
|
131
126
|
"domStubs": {
|
|
132
|
-
"description": "DOM API stub ids this ingested
|
|
127
|
+
"description": "DOM API stub ids this ingested project requires to run headlessly/in-realm",
|
|
133
128
|
"type": "array",
|
|
134
129
|
"items": {
|
|
135
130
|
"type": "string"
|
|
136
131
|
}
|
|
137
132
|
},
|
|
138
133
|
"captureTimeoutMs": {
|
|
139
|
-
"description": "How long the host waits for this
|
|
134
|
+
"description": "How long the host waits for this project's first captured frame before the mount FAILS by name. A project that needs a long boot (streamed world assets, a menu the player must clear) raises it; the default is 10s.",
|
|
140
135
|
"type": "number"
|
|
141
136
|
}
|
|
142
137
|
},
|
|
143
138
|
"additionalProperties": false,
|
|
144
|
-
"description": "Ingest adapter configuration for an unmodified
|
|
139
|
+
"description": "Ingest adapter configuration for an unmodified project (a repo-vendored one or your own external folder)"
|
|
145
140
|
}
|
|
146
141
|
},
|
|
147
142
|
"required": [
|
|
@@ -153,23 +148,23 @@
|
|
|
153
148
|
]
|
|
154
149
|
},
|
|
155
150
|
"entry": {
|
|
156
|
-
"description": "Module exporting a world root — a TSX
|
|
151
|
+
"description": "Module exporting a world root — a TSX component, which the built-in stage dialect renders, or a setup()/adapter (stage), or a React component (dom). Required for every built-in adapter root.",
|
|
157
152
|
"type": "string"
|
|
158
153
|
},
|
|
159
154
|
"styles": {
|
|
160
|
-
"description": "Project-root-relative CSS files this root's mount needs — the PAGE-level stylesheet a
|
|
155
|
+
"description": "Project-root-relative CSS files this root's mount needs — the PAGE-level stylesheet a project written to own a browser tab keeps its layout in (an ingested project is the standing case: its own entry imported the sheet, the host shim that replaces that entry cannot, because `html`/`body`/`*` rules would restyle the editor). Declared here, the editor serves each file rewritten to apply ONLY inside the container it mounts the root's DOM in (`@scope`; packages/sdk/src/scoped-project-css.ts), so the HUD is styled on the UI board's story cards and on the play surface without the editor seeing a single one of those rules. The files themselves are never modified.",
|
|
161
156
|
"type": "array",
|
|
162
157
|
"items": {
|
|
163
158
|
"type": "string"
|
|
164
159
|
}
|
|
165
160
|
},
|
|
166
161
|
"world": {
|
|
167
|
-
"description": "The component this root's WORLD is, in the
|
|
162
|
+
"description": "The component this root's WORLD is, in the project's own source. Two readers, and they mount different things: the EDITOR mounts THIS component alone as the root's design-time document, while `entry` above stays what PLAY mounts (the whole project — its own composition, its own HUD, its own loop). It sits on the ROOT rather than inside any one adapter because the split it names is not about ingest: a project whose runtime entry is a SHELL over the thing an author actually edits has this shape whether the source is vendored or first-party. A project whose world is not a separate component omits this and keeps mounting through `entry` in both modes.",
|
|
168
163
|
"type": "object",
|
|
169
164
|
"properties": {
|
|
170
165
|
"entry": {
|
|
171
166
|
"type": "string",
|
|
172
|
-
"description": "Project-relative path to the
|
|
167
|
+
"description": "Project-relative path to the project's OWN module exporting that component"
|
|
173
168
|
},
|
|
174
169
|
"export": {
|
|
175
170
|
"description": "Named export to read from that module; omit when the module default-exports it",
|
|
@@ -209,7 +204,7 @@
|
|
|
209
204
|
],
|
|
210
205
|
"additionalProperties": false
|
|
211
206
|
},
|
|
212
|
-
"description": "The project's explicit adapter-root composition — ZERO OR MORE roots, and no implicit root: a project with no roots mounts nothing (a library of models, a folder of documents) and the editor derives its chrome from what IS declared. Root ids are unique, and a project declares at most ONE world root per medium — one `
|
|
207
|
+
"description": "The project's explicit adapter-root composition — ZERO OR MORE roots, and no implicit root: a project with no roots mounts nothing (a library of models, a folder of documents) and the editor derives its chrome from what IS declared. Root ids are unique, and a project declares at most ONE world root per medium — one `stage`, one `dom`, one canvas-surface root (first-party canvas, canvas ingest and canvas module are the same medium)."
|
|
213
208
|
},
|
|
214
209
|
"authoring": {
|
|
215
210
|
"description": "Editor-only authoring metadata; never runtime ownership",
|
|
@@ -266,30 +261,6 @@
|
|
|
266
261
|
},
|
|
267
262
|
"additionalProperties": false
|
|
268
263
|
},
|
|
269
|
-
"configurations": {
|
|
270
|
-
"description": "The project's run configurations — its ENTRYPOINTS beyond the host mount (`play`): each an id and a registered kind (`process`, `compound`, and whatever a capability registers) with that kind's own fields. The editor's transport and a harness start the same declaration.",
|
|
271
|
-
"type": "array",
|
|
272
|
-
"items": {
|
|
273
|
-
"type": "object",
|
|
274
|
-
"properties": {
|
|
275
|
-
"id": {
|
|
276
|
-
"type": "string",
|
|
277
|
-
"minLength": 1,
|
|
278
|
-
"description": "Configuration id, unique in the manifest"
|
|
279
|
-
},
|
|
280
|
-
"kind": {
|
|
281
|
-
"type": "string",
|
|
282
|
-
"minLength": 1,
|
|
283
|
-
"description": "A registered run kind"
|
|
284
|
-
}
|
|
285
|
-
},
|
|
286
|
-
"required": [
|
|
287
|
-
"id",
|
|
288
|
-
"kind"
|
|
289
|
-
],
|
|
290
|
-
"additionalProperties": {}
|
|
291
|
-
}
|
|
292
|
-
},
|
|
293
264
|
"resolution": {
|
|
294
265
|
"description": "Canvas resolution",
|
|
295
266
|
"type": "object",
|
|
@@ -309,91 +280,8 @@
|
|
|
309
280
|
],
|
|
310
281
|
"additionalProperties": false
|
|
311
282
|
},
|
|
312
|
-
"rendering": {
|
|
313
|
-
"description": "Construction-time renderer properties, which no world can declare after the fact. Everything a world CAN declare (tone mapping, output colour space, clear colour, shadow filter) lives on the world's own renderer config instead.",
|
|
314
|
-
"type": "object",
|
|
315
|
-
"properties": {
|
|
316
|
-
"antialias": {
|
|
317
|
-
"type": "boolean",
|
|
318
|
-
"description": "Whether every three root is built with a multisampled drawing buffer. This is the ONE render property a world cannot declare for itself (adapter/renderer-config.ts): a WebGL context fixes its sample count at CREATION from this boolean, long before a world mounts, so it belongs to the PROJECT. The runtime reader is mount-manifest.ts, which threads it into createHostRenderer for each three root. WebGL exposes no sample COUNT — the implementation picks one (4x on every desktop browser measured), so a source engine that authored 8x/16x gets multisampling but not its exact count."
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
"required": [
|
|
322
|
-
"antialias"
|
|
323
|
-
],
|
|
324
|
-
"additionalProperties": false
|
|
325
|
-
},
|
|
326
|
-
"debug": {
|
|
327
|
-
"description": "Debug-bridge production gating (D18) — governs whether ?volter-debug=1 installs window.__volter outside dev builds.",
|
|
328
|
-
"type": "object",
|
|
329
|
-
"properties": {
|
|
330
|
-
"allowInProduction": {
|
|
331
|
-
"type": "boolean",
|
|
332
|
-
"description": "Allow the ?volter-debug=1 introspection bridge and debug-command invocation in production builds. Default false: the bridge only installs in dev builds. The runtime reader is the debug-bridge installer (D18)."
|
|
333
|
-
}
|
|
334
|
-
},
|
|
335
|
-
"required": [
|
|
336
|
-
"allowInProduction"
|
|
337
|
-
],
|
|
338
|
-
"additionalProperties": false
|
|
339
|
-
},
|
|
340
|
-
"determinism": {
|
|
341
|
-
"description": "Seeded-RNG determinism contract (D15) — governs whether ctx.random is boot-seeded from a reproducible seed and whether the gameplay-rng-ban scan / dev-mode Math.random phase trap are active for this project.",
|
|
342
|
-
"type": "object",
|
|
343
|
-
"properties": {
|
|
344
|
-
"seededRandom": {
|
|
345
|
-
"type": "boolean",
|
|
346
|
-
"description": "Declares that ALL gameplay RNG in this project flows through ctx.random (the named-stream seeded PRNG) rather than raw Math.random/Date.now/performance.now. Three runtime enforcers key off this flag: the boot-time seeding reader (mount-manifest.ts seeds ctx.random from defaultSeed/?volter-seed=/explicit config, in that precedence, only when true), the gameplay-rng-ban burn-down scan (test/gameplay-rng-ban.test.ts — lints this project's src/ for raw RNG/wall-clock calls), and the dev-mode Math.random phase trap (runtime/gameplay-rng-trap.ts — warns once per call site during a gameplay frame, never throws). Default false: an undeclared project gets no determinism contract at all (that IS the opt-out — no dead field)."
|
|
347
|
-
},
|
|
348
|
-
"defaultSeed": {
|
|
349
|
-
"description": "The seed ctx.random boots from when seededRandom is true, unless overridden by ?volter-seed=<int> (the query param always wins over this manifest default) or an even higher-precedence explicit config value a host passes directly. Optional — omit to fall back to the runtime's own fixed default seed.",
|
|
350
|
-
"type": "integer",
|
|
351
|
-
"minimum": -9007199254740991,
|
|
352
|
-
"maximum": 9007199254740991
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
"required": [
|
|
356
|
-
"seededRandom"
|
|
357
|
-
],
|
|
358
|
-
"additionalProperties": false
|
|
359
|
-
},
|
|
360
|
-
"budget": {
|
|
361
|
-
"description": "Performance budget (W3d, F11 perf regression gates) asserted by `volter perf --assert-budget`: a seeded, fixed-step headless run samples the engine profiler and fails (nonzero exit) when any metric here is exceeded. Only headlessly-measurable metrics are budgetable; real GPU frame time is not (SwiftShader).",
|
|
362
|
-
"type": "object",
|
|
363
|
-
"properties": {
|
|
364
|
-
"frameCpuMsP95": {
|
|
365
|
-
"description": "Maximum allowed p95 of per-frame CPU time (ms) across the measured frames of a `volter perf` seeded headless run. CPU-side only: headless runs rasterize under SwiftShader, so this is main-thread frame cost, NOT real GPU frame time. Machine-dependent — prefer the baseline-diff tolerance band for regression gating and use this as a coarse absolute ceiling.",
|
|
366
|
-
"type": "number",
|
|
367
|
-
"exclusiveMinimum": 0
|
|
368
|
-
},
|
|
369
|
-
"physicsMsP95": {
|
|
370
|
-
"description": "Maximum allowed p95 of the profiler's `physics` phase time (ms) per fixed-step frame in a `volter perf` run. Same CPU-timing caveats as frameCpuMsP95.",
|
|
371
|
-
"type": "number",
|
|
372
|
-
"exclusiveMinimum": 0
|
|
373
|
-
},
|
|
374
|
-
"maxEntities": {
|
|
375
|
-
"description": "Maximum allowed entity-tagged scene-graph nodes (nodes carrying userData.entityId) summed across the game's three/canvas worlds at the end of a `volter perf` run. Exact and deterministic under a seed — no tolerance band.",
|
|
376
|
-
"type": "integer",
|
|
377
|
-
"minimum": 0,
|
|
378
|
-
"maximum": 9007199254740991
|
|
379
|
-
},
|
|
380
|
-
"maxDrawCalls": {
|
|
381
|
-
"description": "Maximum allowed renderer draw calls in any measured frame of a `volter perf` run (the profiler's per-frame render.drawCalls, from renderer.info). Exact and deterministic under a seed.",
|
|
382
|
-
"type": "integer",
|
|
383
|
-
"exclusiveMinimum": 0,
|
|
384
|
-
"maximum": 9007199254740991
|
|
385
|
-
},
|
|
386
|
-
"maxTriangles": {
|
|
387
|
-
"description": "Maximum allowed rendered triangles in any measured frame of a `volter perf` run (the profiler's per-frame render.triangles, from renderer.info). Exact and deterministic under a seed.",
|
|
388
|
-
"type": "integer",
|
|
389
|
-
"exclusiveMinimum": 0,
|
|
390
|
-
"maximum": 9007199254740991
|
|
391
|
-
}
|
|
392
|
-
},
|
|
393
|
-
"additionalProperties": false
|
|
394
|
-
},
|
|
395
283
|
"learn": {
|
|
396
|
-
"description": "Optional learner-facing metadata
|
|
284
|
+
"description": "Optional learner-facing metadata for example projects.",
|
|
397
285
|
"type": "object",
|
|
398
286
|
"properties": {
|
|
399
287
|
"kind": {
|
|
@@ -401,20 +289,20 @@
|
|
|
401
289
|
"enum": [
|
|
402
290
|
"starter",
|
|
403
291
|
"feature",
|
|
404
|
-
"sample-
|
|
292
|
+
"sample-project",
|
|
405
293
|
"lesson-companion"
|
|
406
294
|
],
|
|
407
|
-
"description": "Content kind
|
|
295
|
+
"description": "Content kind: starter (minimal per-genre starting point), feature (demonstrates a subsystem), sample-project (a complete project as an architectural reference), lesson-companion (exists to back a Learn-site lesson)"
|
|
408
296
|
},
|
|
409
297
|
"title": {
|
|
410
298
|
"type": "string",
|
|
411
299
|
"minLength": 1,
|
|
412
|
-
"description": "Learner-facing display title
|
|
300
|
+
"description": "Learner-facing display title"
|
|
413
301
|
},
|
|
414
302
|
"summary": {
|
|
415
303
|
"type": "string",
|
|
416
304
|
"minLength": 1,
|
|
417
|
-
"description": "One-sentence learner-facing summary
|
|
305
|
+
"description": "One-sentence learner-facing summary"
|
|
418
306
|
},
|
|
419
307
|
"difficulty": {
|
|
420
308
|
"type": "string",
|
|
@@ -431,14 +319,14 @@
|
|
|
431
319
|
"type": "string",
|
|
432
320
|
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
|
|
433
321
|
},
|
|
434
|
-
"description": "Short kebab-case
|
|
322
|
+
"description": "Short kebab-case tags describing project features"
|
|
435
323
|
},
|
|
436
324
|
"thumbnail": {
|
|
437
|
-
"description": "Optional thumbnail image reference, PROJECT-relative (canonical path: learn/thumbnail.png
|
|
325
|
+
"description": "Optional thumbnail image reference, PROJECT-relative (canonical path: learn/thumbnail.png)",
|
|
438
326
|
"type": "string"
|
|
439
327
|
},
|
|
440
328
|
"preview": {
|
|
441
|
-
"description": "Optional short preview video/loop reference, PROJECT-relative (canonical path: learn/preview.mp4
|
|
329
|
+
"description": "Optional short preview video/loop reference, PROJECT-relative (canonical path: learn/preview.mp4)",
|
|
442
330
|
"type": "string"
|
|
443
331
|
},
|
|
444
332
|
"lesson": {
|
|
@@ -464,5 +352,5 @@
|
|
|
464
352
|
"roots"
|
|
465
353
|
],
|
|
466
354
|
"additionalProperties": false,
|
|
467
|
-
"description": "
|
|
355
|
+
"description": "Project manifest (volter.project.json) — the complete v2 project configuration"
|
|
468
356
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$comment": "AUTO-GENERATED by scripts/generate-schema.
|
|
2
|
+
"$comment": "AUTO-GENERATED by packages/project/scripts/generate-schema.mjs — do not edit manually",
|
|
3
3
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
@@ -7,27 +7,19 @@
|
|
|
7
7
|
"description": "JSON Schema pointer for editor autocomplete; ignored by the editor.",
|
|
8
8
|
"type": "string"
|
|
9
9
|
},
|
|
10
|
+
"style": {
|
|
11
|
+
"description": "Editor style id (`classic`, `glass`, or one a package carries): its material, icon set and type. Choosing one also applies the colour theme it was drawn with.",
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
10
14
|
"appearance": {
|
|
11
15
|
"description": "How the editor chrome looks.",
|
|
12
16
|
"type": "object",
|
|
13
17
|
"properties": {
|
|
14
|
-
"palette": {
|
|
15
|
-
"description": "Editor palette id — a built-in or a custom theme document.",
|
|
16
|
-
"type": "string"
|
|
17
|
-
},
|
|
18
|
-
"material": {
|
|
19
|
-
"description": "Editor material id (`classic`, `glass`, or one a style bundle carries).",
|
|
20
|
-
"type": "string"
|
|
21
|
-
},
|
|
22
|
-
"icons": {
|
|
23
|
-
"description": "Editor icon set id (`default`, or one a style bundle carries).",
|
|
24
|
-
"type": "string"
|
|
25
|
-
},
|
|
26
18
|
"regions": {
|
|
27
19
|
"type": "object",
|
|
28
20
|
"properties": {
|
|
29
21
|
"workspaceTabs": {
|
|
30
|
-
"description": "The workspace tab strip in the top bar
|
|
22
|
+
"description": "The workspace tab strip in the top bar; hidden unless a style shows it.",
|
|
31
23
|
"type": "string",
|
|
32
24
|
"enum": [
|
|
33
25
|
"shown",
|
|
@@ -51,7 +43,7 @@
|
|
|
51
43
|
]
|
|
52
44
|
},
|
|
53
45
|
"inspector": {
|
|
54
|
-
"description": "Inspector presentation:
|
|
46
|
+
"description": "Inspector presentation: a narrow docked column, properties panel or card.",
|
|
55
47
|
"type": "string",
|
|
56
48
|
"enum": [
|
|
57
49
|
"column",
|
|
@@ -67,16 +59,8 @@
|
|
|
67
59
|
"hidden"
|
|
68
60
|
]
|
|
69
61
|
},
|
|
70
|
-
"telemetry": {
|
|
71
|
-
"description": "The top bar's runtime telemetry cluster: the frame-rate readout, its sparkline and the audio meter. The Profiler utility is the same information's other door.",
|
|
72
|
-
"type": "string",
|
|
73
|
-
"enum": [
|
|
74
|
-
"shown",
|
|
75
|
-
"hidden"
|
|
76
|
-
]
|
|
77
|
-
},
|
|
78
62
|
"hierarchyTypeSuffix": {
|
|
79
|
-
"description": "The `·TypeName` a component-instance row prints after its name in the hierarchy. Hidden leaves the row its name alone
|
|
63
|
+
"description": "The `·TypeName` a component-instance row prints after its name in the hierarchy. Hidden leaves the row its name alone; the type stays reachable through the row's own tooltip and the inspector.",
|
|
80
64
|
"type": "string",
|
|
81
65
|
"enum": [
|
|
82
66
|
"shown",
|
|
@@ -84,7 +68,7 @@
|
|
|
84
68
|
]
|
|
85
69
|
},
|
|
86
70
|
"hierarchyInstanceRule": {
|
|
87
|
-
"description": "The dotted rule a component-instance row draws under its name in the hierarchy. Hidden leaves the name unmarked
|
|
71
|
+
"description": "The dotted rule a component-instance row draws under its name in the hierarchy. Hidden leaves the name unmarked; the fact stays reachable through the row's own tooltip, its source actions and the inspector.",
|
|
88
72
|
"type": "string",
|
|
89
73
|
"enum": [
|
|
90
74
|
"shown",
|
|
@@ -92,7 +76,7 @@
|
|
|
92
76
|
]
|
|
93
77
|
},
|
|
94
78
|
"hierarchyRestrictions": {
|
|
95
|
-
"description": "Which restriction columns a hierarchy row carries at its right edge:
|
|
79
|
+
"description": "Which restriction columns a hierarchy row carries at its right edge: the selection lock beside the eye, or the eye in its own column with the render column reserved and blank, the viewport having one visibility flag for viewport and render alike.",
|
|
96
80
|
"type": "string",
|
|
97
81
|
"enum": [
|
|
98
82
|
"select+viewport",
|
|
@@ -107,7 +91,7 @@
|
|
|
107
91
|
"additionalProperties": false
|
|
108
92
|
},
|
|
109
93
|
"keymap": {
|
|
110
|
-
"description": "Active keymap preset id (`volter`,
|
|
94
|
+
"description": "Active keymap preset id (`volter`, or a contributed preset).",
|
|
111
95
|
"type": "string"
|
|
112
96
|
},
|
|
113
97
|
"play": {
|
|
@@ -120,28 +104,6 @@
|
|
|
120
104
|
}
|
|
121
105
|
},
|
|
122
106
|
"additionalProperties": false
|
|
123
|
-
},
|
|
124
|
-
"devicePreview": {
|
|
125
|
-
"description": "The device frame the Game document previews in.",
|
|
126
|
-
"type": "object",
|
|
127
|
-
"properties": {
|
|
128
|
-
"preset": {
|
|
129
|
-
"description": "Device preview frame preset id.",
|
|
130
|
-
"type": "string"
|
|
131
|
-
},
|
|
132
|
-
"touch": {
|
|
133
|
-
"description": "Touch emulation override; null follows the preset.",
|
|
134
|
-
"anyOf": [
|
|
135
|
-
{
|
|
136
|
-
"type": "boolean"
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
"type": "null"
|
|
140
|
-
}
|
|
141
|
-
]
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
"additionalProperties": false
|
|
145
107
|
}
|
|
146
108
|
},
|
|
147
109
|
"additionalProperties": false,
|