Skip to content

Commit 1d22d12

Browse files
author
DavidQ
committed
Move Asteroids vector maps to Object Vector Studio V2 ownership and deprecate Vector Map Editor usage - PR_26133_115-object-vector-studio-manifest-map-cleanup
1 parent 08a2404 commit 1d22d12

13 files changed

Lines changed: 294 additions & 128 deletions
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# PR_26133_115 Object Vector Studio Manifest Map Cleanup Report
2+
3+
## Summary
4+
- Read `docs/dev/PROJECT_INSTRUCTIONS.md` before implementation.
5+
- Used the current `PR_26133_114` workspace delta and `tmp/PR_26133_114-asteroids-manifest-geometry-completion_delta.zip` as the prior reference.
6+
- Moved Asteroids restored vector maps from `tools.vector-map-editor.vectorMapDocument` to `tools.object-vector-studio-v2.vectorMaps`.
7+
- Removed the separate `vector.asteroids.attract.*` map entries from the Asteroids manifest.
8+
- Updated `ASTEROIDS_VECTOR_MAP_IDS.attractAsteroid`, `attractShip`, and `attractUfo` to resolve to `object.asteroids.large-asteroid`, `object.asteroids.ship`, and `object.asteroids.large-ufo`.
9+
- Kept runtime vector-map loading manifest-only, with missing required vector maps or required Object Vector maps reported as actionable validation failures.
10+
- Marked `vector-map-editor` schema as deprecated and pointed future game-owned vector-map work to `object-vector-studio-v2.vectorMaps`.
11+
12+
## Changed Files
13+
- `games/Asteroids/game.manifest.json`
14+
- `games/Asteroids/game/AsteroidsAttractAdapter.js`
15+
- `games/Asteroids/game/AsteroidsGameScene.js`
16+
- `games/Asteroids/game/asteroidsVectorMaps.js`
17+
- `tests/games/AsteroidsAssetReferenceAdoption.test.mjs`
18+
- `tests/games/AsteroidsPlatformDemo.test.mjs`
19+
- `tests/games/AsteroidsPresentation.test.mjs`
20+
- `tests/games/AsteroidsValidation.test.mjs`
21+
- `tests/playwright/tools/WorkspaceManagerV2.spec.mjs`
22+
- `tools/schemas/game.manifest.schema.json`
23+
- `tools/schemas/tools/object-vector-studio-v2.schema.json`
24+
- `tools/schemas/tools/vector-map-editor.schema.json`
25+
- `docs/dev/reports/PR_26133_115-object-vector-studio-manifest-map-cleanup_report.md`
26+
27+
## Validation
28+
- PASS: `node --check games/Asteroids/game/asteroidsVectorMaps.js`
29+
- PASS: `node --check games/Asteroids/game/AsteroidsAttractAdapter.js`
30+
- PASS: `node --check games/Asteroids/game/AsteroidsGameScene.js`
31+
- PASS: JSON parse validation for Asteroids manifest and impacted schemas.
32+
- PASS: targeted Asteroids manifest vector-map validation confirmed:
33+
- `tools.vector-map-editor` is absent from `games/Asteroids/game.manifest.json`.
34+
- restored vector maps live under `tools.object-vector-studio-v2.vectorMaps`.
35+
- `vector.asteroids.attract.ship`, `vector.asteroids.attract.asteroid`, and `vector.asteroids.attract.ufo` are absent.
36+
- attract constants resolve to the exact Object Vector map IDs requested.
37+
- PASS: targeted Object Vector runtime loader validation accepted the migrated Asteroids payload and resolved the three attract Object Vector IDs.
38+
- PASS: targeted Object Vector Studio schema validation accepted the migrated Asteroids payload.
39+
- PASS: targeted Asteroids tests:
40+
- `AsteroidsValidation`
41+
- `AsteroidsPresentation`
42+
- `AsteroidsVectorTransforms`
43+
- `AsteroidsAssetReferenceAdoption`
44+
- `AsteroidsPlatformDemo`
45+
- `AsteroidsHardening`
46+
- `AsteroidsCollisionTimingStress`
47+
- PASS: targeted Playwright impacted tool validation:
48+
- `loads Object Vector Studio V2 runtime assets into Asteroids gameplay rendering`
49+
- `uses header lifecycle controls and launches tools from fixed Workspace Manager V2 tiles`
50+
- PASS: `git diff --check` (line-ending warnings only)
51+
52+
## Skipped
53+
- Skipped `npm run test:workspace-v2` by request; current BUILD requested targeted Asteroids and impacted tool validation only.
54+
- Skipped full samples smoke test by request.
55+
56+
## Expected Behavior
57+
- Asteroids loads restored vector maps only from `tools.object-vector-studio-v2.vectorMaps`.
58+
- Attract Ship, Asteroid, and UFO rendering use manifest-owned Object Vector objects instead of duplicate attract vector maps.
59+
- Missing `vector.asteroids.bullet` or a required attract Object Vector map fails validation with the missing ID named.
60+
- Workspace Manager V2 and Object Vector Studio V2 no longer select `vector-map-editor` for current Asteroids restored vector maps.
61+
62+
## ZIP
63+
- Output path: `tmp/PR_26133_115-object-vector-studio-manifest-map-cleanup_delta.zip`

games/Asteroids/game.manifest.json

Lines changed: 13 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,15 @@
208208
}
209209
}
210210
},
211-
"vector-map-editor": {
212-
"vectorMapDocument": {
211+
"object-vector-studio-v2": {
212+
"version": 1,
213+
"toolId": "object-vector-studio-v2",
214+
"name": "Asteroids Object Vector Assets",
215+
"vectorMaps": {
213216
"schema": "html-js-gaming.asteroids-vector-map",
214217
"version": 1,
215-
"name": "Asteroids Manifest Vector Maps",
216-
"source": "manifest",
218+
"name": "Asteroids Object Vector Manifest Maps",
219+
"source": "object-vector-studio-v2",
217220
"objectVectorRoles": {
218221
"ship": {
219222
"objectId": "object.asteroids.ship",
@@ -329,7 +332,11 @@
329332
"id": "vector.asteroids.bullet",
330333
"label": "Bullet",
331334
"kind": "polygon",
332-
"usage": ["gameplay", "collision", "projectile"],
335+
"usage": [
336+
"gameplay",
337+
"collision",
338+
"projectile"
339+
],
333340
"points": [
334341
{
335342
"x": -2,
@@ -491,92 +498,6 @@
491498
}
492499
]
493500
},
494-
{
495-
"id": "vector.asteroids.attract.ship",
496-
"label": "Attract Ship",
497-
"kind": "polygon",
498-
"usage": [
499-
"attract"
500-
],
501-
"points": [
502-
{
503-
"x": 16,
504-
"y": 0
505-
},
506-
{
507-
"x": -10,
508-
"y": 9
509-
},
510-
{
511-
"x": -5,
512-
"y": 0
513-
},
514-
{
515-
"x": -10,
516-
"y": -9
517-
}
518-
]
519-
},
520-
{
521-
"id": "vector.asteroids.attract.asteroid",
522-
"label": "Attract Asteroid",
523-
"kind": "polyline",
524-
"usage": [
525-
"attract"
526-
],
527-
"points": [
528-
{
529-
"x": -16,
530-
"y": -5
531-
},
532-
{
533-
"x": -7,
534-
"y": 14
535-
},
536-
{
537-
"x": 11,
538-
"y": 12
539-
},
540-
{
541-
"x": 15,
542-
"y": -6
543-
},
544-
{
545-
"x": 2,
546-
"y": -16
547-
},
548-
{
549-
"x": -16,
550-
"y": -5
551-
}
552-
]
553-
},
554-
{
555-
"id": "vector.asteroids.attract.ufo",
556-
"label": "Attract UFO",
557-
"kind": "polygon",
558-
"usage": [
559-
"attract"
560-
],
561-
"points": [
562-
{
563-
"x": -20,
564-
"y": 5
565-
},
566-
{
567-
"x": 20,
568-
"y": 5
569-
},
570-
{
571-
"x": 14,
572-
"y": -4
573-
},
574-
{
575-
"x": -14,
576-
"y": -4
577-
}
578-
]
579-
},
580501
{
581502
"id": "vector.asteroids.ui.title",
582503
"label": "Asteroids Title",
@@ -594,12 +515,7 @@
594515
"points": []
595516
}
596517
]
597-
}
598-
},
599-
"object-vector-studio-v2": {
600-
"version": 1,
601-
"toolId": "object-vector-studio-v2",
602-
"name": "Asteroids Object Vector Assets",
518+
},
603519
"objects": [
604520
{
605521
"id": "object.asteroids.ship",

games/Asteroids/game/AsteroidsAttractAdapter.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ David Quesenberry
55
AsteroidsAttractAdapter.js
66
*/
77
import { clamp } from '../../../src/shared/utils/mathUtils.js';
8+
import { ASTEROIDS_VECTOR_MAP_IDS } from './asteroidsVectorMaps.js';
89

910
function estimateTextWidth(text, fontPx) {
1011
return String(text ?? '').length * (fontPx * 0.62);
@@ -123,16 +124,19 @@ export default class AsteroidsAttractAdapter {
123124
...this.scene.objectVectorRoleOptions('ship'),
124125
elapsedMs: this.scene.objectVectorPlaybackMs,
125126
fps: 12,
127+
objectId: ASTEROIDS_VECTOR_MAP_IDS.attractShip,
126128
rotation: (Math.PI / 2) - 0.28,
127129
scale: 1.1,
128130
stateId: 'idle',
129131
x: 328,
130132
y: 348,
131133
});
132134
this.scene?.drawObjectVectorAsset?.(renderer, 'attractAsteroid', {
133-
...this.scene.objectVectorRoleOptions('asteroidSmall'),
135+
...this.scene.objectVectorRoleOptions('asteroidLarge'),
134136
elapsedMs: this.scene.objectVectorPlaybackMs,
135137
fps: 12,
138+
objectId: ASTEROIDS_VECTOR_MAP_IDS.attractAsteroid,
139+
scale: 0.72,
136140
stateId: 'active',
137141
x: 632,
138142
y: 352,
@@ -209,6 +213,7 @@ export default class AsteroidsAttractAdapter {
209213
...this.scene.objectVectorRoleOptions('ship'),
210214
elapsedMs: this.scene.objectVectorPlaybackMs,
211215
fps: 12,
216+
objectId: ASTEROIDS_VECTOR_MAP_IDS.attractShip,
212217
rotation: (Math.PI / 2) + Math.sin(this.demoTime * 0.9) * 1.2,
213218
stateId: 'idle',
214219
x,
@@ -218,17 +223,20 @@ export default class AsteroidsAttractAdapter {
218223
const rockX = 480 + Math.sin(this.demoTime * 0.5) * 250;
219224
const rockY = 330 + Math.cos(this.demoTime * 0.9) * 120;
220225
this.scene?.drawObjectVectorAsset?.(renderer, 'attractAsteroid', {
221-
...this.scene.objectVectorRoleOptions('asteroidSmall'),
226+
...this.scene.objectVectorRoleOptions('asteroidLarge'),
222227
elapsedMs: this.scene.objectVectorPlaybackMs,
223228
fps: 12,
229+
objectId: ASTEROIDS_VECTOR_MAP_IDS.attractAsteroid,
230+
scale: 0.72,
224231
stateId: 'active',
225232
x: rockX,
226233
y: rockY,
227234
});
228235
this.scene?.drawObjectVectorAsset?.(renderer, 'attractUfo', {
229-
...this.scene.objectVectorRoleOptions('ufoSmall'),
236+
...this.scene.objectVectorRoleOptions('ufoLarge'),
230237
elapsedMs: this.scene.objectVectorPlaybackMs,
231238
fps: 12,
239+
objectId: ASTEROIDS_VECTOR_MAP_IDS.attractUfo,
232240
stateId: 'active',
233241
x: 480 + Math.cos(this.demoTime * 0.43) * 280,
234242
y: 284,

games/Asteroids/game/AsteroidsGameScene.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,7 @@ export default class AsteroidsGameScene extends Scene {
969969
assetCount: this.objectVectorAssets?.objectsById?.size || 0,
970970
loaded: Boolean(this.objectVectorAssets),
971971
objectCount: this.objectVectorAssets?.objectsById?.size || 0,
972+
objectVectorMapIds: this.vectorMaps?.objectVectorMaps?.map((object) => object.id) || [],
972973
runtimeObjectsValid: Boolean(this.objectVectorRuntimeObjectValidation?.ok),
973974
renderCounts: { ...this.objectVectorRenderCounts },
974975
vectorMapIds: this.vectorMaps?.vectors?.map((vector) => vector.id) || [],

games/Asteroids/game/asteroidsVectorMaps.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
const ASTEROIDS_VECTOR_MAP_TOOL_KEY = 'vector-map-editor';
2-
const ASTEROIDS_VECTOR_MAP_DOCUMENT_KEY = 'vectorMapDocument';
1+
const ASTEROIDS_OBJECT_VECTOR_TOOL_KEY = 'object-vector-studio-v2';
2+
const ASTEROIDS_VECTOR_MAP_DOCUMENT_KEY = 'vectorMaps';
33

44
export const ASTEROIDS_VECTOR_MAP_IDS = Object.freeze({
5-
attractAsteroid: 'vector.asteroids.attract.asteroid',
6-
attractShip: 'vector.asteroids.attract.ship',
7-
attractUfo: 'vector.asteroids.attract.ufo',
5+
attractAsteroid: 'object.asteroids.large-asteroid',
6+
attractShip: 'object.asteroids.ship',
7+
attractUfo: 'object.asteroids.large-ufo',
88
bullet: 'vector.asteroids.bullet',
99
shipCollision: 'vector.asteroids.ship.collision',
1010
shipLife: 'vector.asteroids.ship.life',
@@ -14,9 +14,6 @@ export const ASTEROIDS_VECTOR_MAP_IDS = Object.freeze({
1414
});
1515

1616
export const ASTEROIDS_REQUIRED_VECTOR_MAP_IDS = Object.freeze([
17-
ASTEROIDS_VECTOR_MAP_IDS.attractAsteroid,
18-
ASTEROIDS_VECTOR_MAP_IDS.attractShip,
19-
ASTEROIDS_VECTOR_MAP_IDS.attractUfo,
2017
ASTEROIDS_VECTOR_MAP_IDS.bullet,
2118
ASTEROIDS_VECTOR_MAP_IDS.shipCollision,
2219
ASTEROIDS_VECTOR_MAP_IDS.shipLife,
@@ -25,6 +22,12 @@ export const ASTEROIDS_REQUIRED_VECTOR_MAP_IDS = Object.freeze([
2522
ASTEROIDS_VECTOR_MAP_IDS.uiTitle,
2623
]);
2724

25+
export const ASTEROIDS_REQUIRED_OBJECT_VECTOR_MAP_IDS = Object.freeze([
26+
ASTEROIDS_VECTOR_MAP_IDS.attractAsteroid,
27+
ASTEROIDS_VECTOR_MAP_IDS.attractShip,
28+
ASTEROIDS_VECTOR_MAP_IDS.attractUfo,
29+
]);
30+
2831
export const ASTEROIDS_REQUIRED_OBJECT_VECTOR_ROLE_IDS = Object.freeze([
2932
'ship',
3033
'asteroidLarge',
@@ -148,15 +151,22 @@ export function loadAsteroidsVectorMapsFromManifest(manifest, {
148151
logger = null,
149152
sourceLabel = 'games/Asteroids/game.manifest.json',
150153
} = {}) {
151-
const document = manifest?.tools?.[ASTEROIDS_VECTOR_MAP_TOOL_KEY]?.[ASTEROIDS_VECTOR_MAP_DOCUMENT_KEY];
154+
const objectVectorPayload = manifest?.tools?.[ASTEROIDS_OBJECT_VECTOR_TOOL_KEY];
155+
const document = objectVectorPayload?.[ASTEROIDS_VECTOR_MAP_DOCUMENT_KEY];
152156
const errors = [];
153157
if (!isRecord(document)) {
154-
errors.push(`Asteroids vector map manifest is missing root.tools.${ASTEROIDS_VECTOR_MAP_TOOL_KEY}.${ASTEROIDS_VECTOR_MAP_DOCUMENT_KEY}.`);
158+
errors.push(`Asteroids vector map manifest is missing root.tools.${ASTEROIDS_OBJECT_VECTOR_TOOL_KEY}.${ASTEROIDS_VECTOR_MAP_DOCUMENT_KEY}.`);
155159
}
156160
const vectors = Array.isArray(document?.vectors)
157161
? document.vectors.map(normalizeVectorEntry).filter(Boolean)
158162
: [];
159163
const vectorsById = new Map(vectors.map((vector) => [vector.id, vector]));
164+
const objectVectorMaps = Array.isArray(objectVectorPayload?.objects)
165+
? objectVectorPayload.objects
166+
.filter((object) => isRecord(object) && normalizeString(object.id))
167+
.map((object) => clone(object))
168+
: [];
169+
const objectVectorMapsById = new Map(objectVectorMaps.map((object) => [object.id, object]));
160170
ASTEROIDS_REQUIRED_VECTOR_MAP_IDS.forEach((id) => {
161171
const vector = vectorsById.get(id);
162172
if (!vector) {
@@ -168,6 +178,16 @@ export function loadAsteroidsVectorMapsFromManifest(manifest, {
168178
errors.push(`Asteroids vector map ${id} must contain at least ${minimumPoints} points.`);
169179
}
170180
});
181+
ASTEROIDS_REQUIRED_OBJECT_VECTOR_MAP_IDS.forEach((id) => {
182+
const object = objectVectorMapsById.get(id);
183+
if (!object) {
184+
errors.push(`Asteroids Object Vector manifest map ${id} is missing from root.tools.${ASTEROIDS_OBJECT_VECTOR_TOOL_KEY}.objects.`);
185+
return;
186+
}
187+
if (!Array.isArray(object.shapes) || !object.shapes.length) {
188+
errors.push(`Asteroids Object Vector manifest map ${id} must contain at least one shape.`);
189+
}
190+
});
171191
const objectVectorRoles = normalizeObjectVectorRoleBindings(document, errors);
172192
if (errors.length) {
173193
errors.forEach((message) => logValidation(logger, 'FAIL', message, { sourceLabel }));
@@ -179,6 +199,8 @@ export function loadAsteroidsVectorMapsFromManifest(manifest, {
179199
}
180200
const vectorMaps = {
181201
document: clone(document),
202+
objectVectorMaps,
203+
objectVectorMapsById,
182204
objectVectorRoles,
183205
sourceLabel,
184206
usageCounts: usageCounts(vectors),

tests/games/AsteroidsAssetReferenceAdoption.test.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ export async function run() {
5353
const profiles = createAsteroidsTestGeometryProfiles();
5454
const manifestText = JSON.stringify(manifest);
5555

56-
assert.equal(Array.isArray(manifest.tools["vector-map-editor"].vectorMapDocument.vectors), true);
56+
assert.equal(manifest.tools["vector-map-editor"], undefined);
57+
assert.equal(Array.isArray(manifest.tools["object-vector-studio-v2"].vectorMaps.vectors), true);
5758
assert.equal(vectorMaps.vectorsById.has("vector.asteroids.ship.collision"), true);
5859
assert.equal(vectorMaps.vectorsById.has("vector.asteroids.ui.title"), true);
5960
assert.equal(manifest.game["workspace"], undefined);

tests/games/AsteroidsPlatformDemo.test.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ export async function run() {
7272
const vectorMaps = loadAsteroidsVectorMaps();
7373
const manifestText = JSON.stringify(manifest);
7474

75-
assert.equal(Array.isArray(manifest.tools['vector-map-editor'].vectorMapDocument.vectors), true);
75+
assert.equal(manifest.tools['vector-map-editor'], undefined);
76+
assert.equal(Array.isArray(manifest.tools['object-vector-studio-v2'].vectorMaps.vectors), true);
7677
assert.equal(vectorMaps.vectorsById.has('vector.asteroids.ship.collision'), true);
7778
assert.equal(vectorMaps.vectorsById.has('vector.asteroids.ui.title'), true);
7879
assert.equal(manifest.game["workspace"], undefined);

tests/games/AsteroidsPresentation.test.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ function testAsteroidsAttractObjectsLoadFromManifestRoles() {
211211

212212
const objectIds = renderCalls.map((call) => call.objectId);
213213
assert.equal(objectIds.includes('object.asteroids.ship'), true);
214-
assert.equal(objectIds.includes('object.asteroids.small-asteroid'), true);
215-
assert.equal(objectIds.includes('object.asteroids.small-ufo'), true);
214+
assert.equal(objectIds.includes('object.asteroids.large-asteroid'), true);
215+
assert.equal(objectIds.includes('object.asteroids.large-ufo'), true);
216216
}
217217

218218
function testAsteroidsGameplayBulletsUseManifestVectorMap() {

0 commit comments

Comments
 (0)