Skip to content

Commit 830a4b6

Browse files
author
DavidQ
committed
Clean up Asteroids vector map SSoT and restore older manifest geometry - PR_26133_116-asteroids-vector-map-ssoT-cleanup
1 parent 1d22d12 commit 830a4b6

13 files changed

Lines changed: 199 additions & 105 deletions
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# PR_26133_116 Asteroids Vector Map SSoT Cleanup Report
2+
3+
## Summary
4+
- Read `docs/dev/PROJECT_INSTRUCTIONS.md` before implementation.
5+
- Used PR_26133_115 as the prior reference from committed `HEAD` (`1d22d12c7`) and `docs/dev/reports/PR_26133_115-object-vector-studio-manifest-map-cleanup_report.md`; the local PR115 delta ZIP was not present under `tmp/`.
6+
- Replaced collision-suffixed Asteroids vector map IDs with unsuffixed manifest-owned IDs:
7+
- `vector.asteroids.ship`
8+
- `vector.asteroids.ufo.large`
9+
- `vector.asteroids.ufo.small`
10+
- Removed `ASTEROIDS_REQUIRED_OBJECT_VECTOR_MAP_IDS`; `ASTEROIDS_REQUIRED_VECTOR_MAP_IDS` is now the single required-ID validation list for manifest vector entries and required Object Vector object IDs.
11+
- Restored older Asteroids vector geometry from git history:
12+
- ship path/points from pre-Object-Vector manifest vector data (`3fc7bbce7`)
13+
- UFO polylines and Bullet square geometry from the original Asteroids runtime (`31ca1521e`)
14+
- Removed the active workspace manifest schema `$ref` to `vector-map-editor.schema.json`; the deprecated schema remains only as historical metadata.
15+
16+
## Changed Files
17+
- `games/Asteroids/game.manifest.json`
18+
- `games/Asteroids/game/AsteroidsGameScene.js`
19+
- `games/Asteroids/game/AsteroidsWorld.js`
20+
- `games/Asteroids/game/asteroidsVectorMaps.js`
21+
- `tests/games/AsteroidsAssetReferenceAdoption.test.mjs`
22+
- `tests/games/AsteroidsPlatformDemo.test.mjs`
23+
- `tests/games/AsteroidsValidation.test.mjs`
24+
- `tests/games/AsteroidsVectorTransforms.test.mjs`
25+
- `tests/playwright/tools/WorkspaceManagerV2.spec.mjs`
26+
- `tests/tools/ToolWorkspaceSchemaManifestBoundaries.test.mjs`
27+
- `tools/schemas/tools/README.md`
28+
- `tools/schemas/workspace.manifest.schema.json`
29+
- `docs/dev/reports/PR_26133_116-asteroids-vector-map-ssoT-cleanup_report.md`
30+
31+
## Validation
32+
- PASS: `node --check games/Asteroids/game/asteroidsVectorMaps.js`
33+
- PASS: `node --check games/Asteroids/game/AsteroidsWorld.js`
34+
- PASS: `node --check games/Asteroids/game/AsteroidsGameScene.js`
35+
- PASS: syntax checks for changed targeted test files.
36+
- PASS: JSON parse validation for Asteroids manifest and impacted schemas.
37+
- PASS: targeted Asteroids required vector map SSoT validation confirmed all `ASTEROIDS_REQUIRED_VECTOR_MAP_IDS` resolve and collision-suffixed IDs are absent.
38+
- PASS: targeted Asteroids tests:
39+
- `AsteroidsValidation`
40+
- `AsteroidsVectorTransforms`
41+
- `AsteroidsAssetReferenceAdoption`
42+
- `AsteroidsPlatformDemo`
43+
- `AsteroidsPresentation`
44+
- `AsteroidsHardening`
45+
- `AsteroidsCollisionTimingStress`
46+
- PASS: targeted Object Vector runtime loader validation accepted the migrated Asteroids payload.
47+
- PASS: targeted Object Vector Studio schema validation accepted the migrated Asteroids payload.
48+
- PASS: targeted workspace schema audit confirmed `tools/schemas/workspace.manifest.schema.json` no longer allows `vector-map-editor`.
49+
- PASS: targeted Playwright impacted tool validation:
50+
- `loads Object Vector Studio V2 runtime assets into Asteroids gameplay rendering`
51+
- `uses header lifecycle controls and launches tools from fixed Workspace Manager V2 tiles`
52+
- PASS: `git diff --check` (line-ending warnings only)
53+
- WARN: attempted non-targeted `ToolWorkspaceSchemaManifestBoundaries` execution fails on an unrelated stale Palette Manager assertion; the schema file itself still passes syntax/JSON and targeted vector-map-editor reference checks.
54+
55+
## Skipped
56+
- Skipped `npm run test:workspace-v2` by request; this PR requested targeted Asteroids and impacted tool validation only.
57+
- Skipped full samples smoke test by request.
58+
59+
## Expected Behavior
60+
- Asteroids vector map runtime loading uses manifest data only.
61+
- Required manifest IDs resolve from `ASTEROIDS_REQUIRED_VECTOR_MAP_IDS`.
62+
- `vector.asteroids.ship.collision`, `vector.asteroids.ship.life`, `vector.asteroids.ufo.large.collision`, and `vector.asteroids.ufo.small.collision` are no longer active Asteroids vector map IDs.
63+
- Missing required manifest vector entries or required Object Vector objects fail validation with the missing ID named.
64+
- Current workspace schemas do not actively depend on `vector-map-editor.schema.json`.
65+
66+
## ZIP
67+
- Output path: `tmp/PR_26133_116-asteroids-vector-map-ssoT-cleanup_delta.zip`

games/Asteroids/game.manifest.json

Lines changed: 20 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -263,68 +263,35 @@
263263
},
264264
"vectors": [
265265
{
266-
"id": "vector.asteroids.ship.collision",
267-
"label": "Ship Collision",
268-
"kind": "polygon",
269-
"usage": [
270-
"gameplay",
271-
"collision"
272-
],
273-
"points": [
274-
{
275-
"x": 14,
276-
"y": 0
277-
},
278-
{
279-
"x": -10,
280-
"y": -8
281-
},
282-
{
283-
"x": -6,
284-
"y": -3
285-
},
286-
{
287-
"x": -6,
288-
"y": 3
289-
},
290-
{
291-
"x": -10,
292-
"y": 8
293-
},
294-
{
295-
"x": 14,
296-
"y": 0
297-
}
298-
]
299-
},
300-
{
301-
"id": "vector.asteroids.ship.life",
302-
"label": "Ship Life Icon",
266+
"id": "vector.asteroids.ship",
267+
"label": "Ship",
303268
"kind": "polygon",
304269
"usage": [
305270
"gameplay",
271+
"collision",
306272
"ui"
307273
],
274+
"viewBox": "-24 -24 48 48",
275+
"paths": [
276+
"M 0 -18 L 14 16 L 0 8 L -14 16 Z",
277+
"M -6 14 L 0 6 L 6 14"
278+
],
308279
"points": [
309280
{
310-
"x": 14,
311-
"y": 0
312-
},
313-
{
314-
"x": -10,
315-
"y": -8
281+
"x": 0,
282+
"y": -18
316283
},
317284
{
318-
"x": -6,
319-
"y": -3
285+
"x": 14,
286+
"y": 16
320287
},
321288
{
322-
"x": -6,
323-
"y": 3
289+
"x": 0,
290+
"y": 8
324291
},
325292
{
326-
"x": -10,
327-
"y": 8
293+
"x": -14,
294+
"y": 16
328295
}
329296
]
330297
},
@@ -357,8 +324,8 @@
357324
]
358325
},
359326
{
360-
"id": "vector.asteroids.ufo.small.collision",
361-
"label": "Small UFO Collision",
327+
"id": "vector.asteroids.ufo.small",
328+
"label": "Small UFO",
362329
"kind": "polyline",
363330
"usage": [
364331
"gameplay",
@@ -428,8 +395,8 @@
428395
]
429396
},
430397
{
431-
"id": "vector.asteroids.ufo.large.collision",
432-
"label": "Large UFO Collision",
398+
"id": "vector.asteroids.ufo.large",
399+
"label": "Large UFO",
433400
"kind": "polyline",
434401
"usage": [
435402
"gameplay",

games/Asteroids/game/AsteroidsGameScene.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ export default class AsteroidsGameScene extends Scene {
876876

877877
const startX = centerX - ((lives - 1) * LIFE_SPACING) / 2;
878878
Array.from({ length: lives }).forEach((_, index) => {
879-
this.drawManifestVectorMap(renderer, ASTEROIDS_VECTOR_MAP_IDS.shipLife, {
879+
this.drawManifestVectorMap(renderer, ASTEROIDS_VECTOR_MAP_IDS.ship, {
880880
color: '#ffffff',
881881
lineWidth: 1,
882882
rotation: -Math.PI / 2,

games/Asteroids/game/AsteroidsWorld.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,10 @@ export default class AsteroidsWorld {
151151
throw new Error('AsteroidsWorld requires manifest-loaded vector maps for ship, UFO, and bullet gameplay geometry.');
152152
}
153153
this.bulletCollisionPoints = requireAsteroidsVectorPoints(this.vectorMaps, ASTEROIDS_VECTOR_MAP_IDS.bullet, 'bullet geometry');
154-
this.shipCollisionPoints = requireAsteroidsVectorPoints(this.vectorMaps, ASTEROIDS_VECTOR_MAP_IDS.shipCollision, 'ship collision geometry');
154+
this.shipCollisionPoints = requireAsteroidsVectorPoints(this.vectorMaps, ASTEROIDS_VECTOR_MAP_IDS.ship, 'ship collision geometry');
155155
this.ufoCollisionPoints = {
156-
large: requireAsteroidsVectorPoints(this.vectorMaps, ASTEROIDS_VECTOR_MAP_IDS.ufoLargeCollision, 'large UFO collision geometry'),
157-
small: requireAsteroidsVectorPoints(this.vectorMaps, ASTEROIDS_VECTOR_MAP_IDS.ufoSmallCollision, 'small UFO collision geometry'),
156+
large: requireAsteroidsVectorPoints(this.vectorMaps, ASTEROIDS_VECTOR_MAP_IDS.ufoLarge, 'large UFO collision geometry'),
157+
small: requireAsteroidsVectorPoints(this.vectorMaps, ASTEROIDS_VECTOR_MAP_IDS.ufoSmall, 'small UFO collision geometry'),
158158
};
159159
this.rng = typeof rng === 'function' ? rng : Math.random;
160160
this.bounds = sanitizeBounds(bounds);

games/Asteroids/game/asteroidsVectorMaps.js

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,21 @@ export const ASTEROIDS_VECTOR_MAP_IDS = Object.freeze({
66
attractShip: 'object.asteroids.ship',
77
attractUfo: 'object.asteroids.large-ufo',
88
bullet: 'vector.asteroids.bullet',
9-
shipCollision: 'vector.asteroids.ship.collision',
10-
shipLife: 'vector.asteroids.ship.life',
11-
ufoLargeCollision: 'vector.asteroids.ufo.large.collision',
12-
ufoSmallCollision: 'vector.asteroids.ufo.small.collision',
9+
ship: 'vector.asteroids.ship',
10+
ufoLarge: 'vector.asteroids.ufo.large',
11+
ufoSmall: 'vector.asteroids.ufo.small',
1312
uiTitle: 'vector.asteroids.ui.title',
1413
});
1514

1615
export const ASTEROIDS_REQUIRED_VECTOR_MAP_IDS = Object.freeze([
17-
ASTEROIDS_VECTOR_MAP_IDS.bullet,
18-
ASTEROIDS_VECTOR_MAP_IDS.shipCollision,
19-
ASTEROIDS_VECTOR_MAP_IDS.shipLife,
20-
ASTEROIDS_VECTOR_MAP_IDS.ufoLargeCollision,
21-
ASTEROIDS_VECTOR_MAP_IDS.ufoSmallCollision,
22-
ASTEROIDS_VECTOR_MAP_IDS.uiTitle,
23-
]);
24-
25-
export const ASTEROIDS_REQUIRED_OBJECT_VECTOR_MAP_IDS = Object.freeze([
2616
ASTEROIDS_VECTOR_MAP_IDS.attractAsteroid,
2717
ASTEROIDS_VECTOR_MAP_IDS.attractShip,
2818
ASTEROIDS_VECTOR_MAP_IDS.attractUfo,
19+
ASTEROIDS_VECTOR_MAP_IDS.bullet,
20+
ASTEROIDS_VECTOR_MAP_IDS.ship,
21+
ASTEROIDS_VECTOR_MAP_IDS.ufoLarge,
22+
ASTEROIDS_VECTOR_MAP_IDS.ufoSmall,
23+
ASTEROIDS_VECTOR_MAP_IDS.uiTitle,
2924
]);
3025

3126
export const ASTEROIDS_REQUIRED_OBJECT_VECTOR_ROLE_IDS = Object.freeze([
@@ -49,6 +44,10 @@ function normalizeString(value) {
4944
return String(value || '').trim();
5045
}
5146

47+
function isObjectVectorId(id) {
48+
return normalizeString(id).startsWith('object.');
49+
}
50+
5251
function normalizeTags(value) {
5352
return Array.isArray(value)
5453
? value.map((tag) => normalizeString(tag).toLowerCase()).filter(Boolean)
@@ -168,6 +167,17 @@ export function loadAsteroidsVectorMapsFromManifest(manifest, {
168167
: [];
169168
const objectVectorMapsById = new Map(objectVectorMaps.map((object) => [object.id, object]));
170169
ASTEROIDS_REQUIRED_VECTOR_MAP_IDS.forEach((id) => {
170+
if (isObjectVectorId(id)) {
171+
const object = objectVectorMapsById.get(id);
172+
if (!object) {
173+
errors.push(`Asteroids Object Vector manifest map ${id} is missing from root.tools.${ASTEROIDS_OBJECT_VECTOR_TOOL_KEY}.objects.`);
174+
return;
175+
}
176+
if (!Array.isArray(object.shapes) || !object.shapes.length) {
177+
errors.push(`Asteroids Object Vector manifest map ${id} must contain at least one shape.`);
178+
}
179+
return;
180+
}
171181
const vector = vectorsById.get(id);
172182
if (!vector) {
173183
errors.push(`Asteroids vector map manifest is missing ${id}.`);
@@ -178,16 +188,6 @@ export function loadAsteroidsVectorMapsFromManifest(manifest, {
178188
errors.push(`Asteroids vector map ${id} must contain at least ${minimumPoints} points.`);
179189
}
180190
});
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-
});
191191
const objectVectorRoles = normalizeObjectVectorRoleBindings(document, errors);
192192
if (errors.length) {
193193
errors.forEach((message) => logValidation(logger, 'FAIL', message, { sourceLabel }));

tests/games/AsteroidsAssetReferenceAdoption.test.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export async function run() {
5555

5656
assert.equal(manifest.tools["vector-map-editor"], undefined);
5757
assert.equal(Array.isArray(manifest.tools["object-vector-studio-v2"].vectorMaps.vectors), true);
58-
assert.equal(vectorMaps.vectorsById.has("vector.asteroids.ship.collision"), true);
58+
assert.equal(vectorMaps.vectorsById.has("vector.asteroids.ship"), true);
59+
assert.equal(vectorMaps.vectorsById.has("vector.asteroids.ship.collision"), false);
5960
assert.equal(vectorMaps.vectorsById.has("vector.asteroids.ui.title"), true);
6061
assert.equal(manifest.game["workspace"], undefined);
6162
assert.equal(manifest.game.gameData, undefined);

tests/games/AsteroidsPlatformDemo.test.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ export async function run() {
7474

7575
assert.equal(manifest.tools['vector-map-editor'], undefined);
7676
assert.equal(Array.isArray(manifest.tools['object-vector-studio-v2'].vectorMaps.vectors), true);
77-
assert.equal(vectorMaps.vectorsById.has('vector.asteroids.ship.collision'), true);
77+
assert.equal(vectorMaps.vectorsById.has('vector.asteroids.ship'), true);
78+
assert.equal(vectorMaps.vectorsById.has('vector.asteroids.ship.collision'), false);
7879
assert.equal(vectorMaps.vectorsById.has('vector.asteroids.ui.title'), true);
7980
assert.equal(manifest.game["workspace"], undefined);
8081
assert.equal(manifest.game.gameData, undefined);

tests/games/AsteroidsValidation.test.mjs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
loadAsteroidsVectorMaps
1919
} from './asteroidsManifestObjectVectors.mjs';
2020
import {
21+
ASTEROIDS_REQUIRED_VECTOR_MAP_IDS,
2122
ASTEROIDS_VECTOR_MAP_IDS,
2223
loadAsteroidsVectorMapsFromManifest
2324
} from '../../games/Asteroids/game/asteroidsVectorMaps.js';
@@ -157,6 +158,13 @@ export async function run() {
157158
const objectVectorPayload = manifestPayload.tools['object-vector-studio-v2'];
158159
const manifestVectorIds = objectVectorPayload.vectorMaps.vectors.map((vector) => vector.id);
159160
assert.equal(manifestVectorIds.includes(ASTEROIDS_VECTOR_MAP_IDS.bullet), true);
161+
assert.equal(manifestVectorIds.includes(ASTEROIDS_VECTOR_MAP_IDS.ship), true);
162+
assert.equal(manifestVectorIds.includes(ASTEROIDS_VECTOR_MAP_IDS.ufoLarge), true);
163+
assert.equal(manifestVectorIds.includes(ASTEROIDS_VECTOR_MAP_IDS.ufoSmall), true);
164+
assert.equal(manifestVectorIds.includes('vector.asteroids.ship.collision'), false);
165+
assert.equal(manifestVectorIds.includes('vector.asteroids.ship.life'), false);
166+
assert.equal(manifestVectorIds.includes('vector.asteroids.ufo.large.collision'), false);
167+
assert.equal(manifestVectorIds.includes('vector.asteroids.ufo.small.collision'), false);
160168
assert.equal(manifestVectorIds.includes('vector.asteroids.attract.ship'), false);
161169
assert.equal(manifestVectorIds.includes('vector.asteroids.attract.asteroid'), false);
162170
assert.equal(manifestVectorIds.includes('vector.asteroids.attract.ufo'), false);
@@ -166,6 +174,15 @@ export async function run() {
166174
assert.equal(vectorMaps.objectVectorMapsById.get(ASTEROIDS_VECTOR_MAP_IDS.attractAsteroid).id, 'object.asteroids.large-asteroid');
167175
assert.equal(vectorMaps.objectVectorMapsById.get(ASTEROIDS_VECTOR_MAP_IDS.attractShip).id, 'object.asteroids.ship');
168176
assert.equal(vectorMaps.objectVectorMapsById.get(ASTEROIDS_VECTOR_MAP_IDS.attractUfo).id, 'object.asteroids.large-ufo');
177+
ASTEROIDS_REQUIRED_VECTOR_MAP_IDS.forEach((id) => {
178+
assert.equal(
179+
id.startsWith('object.')
180+
? vectorMaps.objectVectorMapsById.has(id)
181+
: vectorMaps.vectorsById.has(id),
182+
true,
183+
`required Asteroids manifest vector id ${id} should resolve`,
184+
);
185+
});
169186
assert.deepEqual(
170187
vectorMaps.vectorsById.get(ASTEROIDS_VECTOR_MAP_IDS.bullet).points,
171188
[
@@ -175,6 +192,32 @@ export async function run() {
175192
{ x: -2, y: 2 },
176193
],
177194
);
195+
assert.deepEqual(
196+
vectorMaps.vectorsById.get(ASTEROIDS_VECTOR_MAP_IDS.ship).points,
197+
[
198+
{ x: 0, y: -18 },
199+
{ x: 14, y: 16 },
200+
{ x: 0, y: 8 },
201+
{ x: -14, y: 16 },
202+
],
203+
);
204+
assert.deepEqual(
205+
vectorMaps.vectorsById.get(ASTEROIDS_VECTOR_MAP_IDS.ship).paths,
206+
[
207+
'M 0 -18 L 14 16 L 0 8 L -14 16 Z',
208+
'M -6 14 L 0 6 L 6 14',
209+
],
210+
);
211+
assert.deepEqual(
212+
vectorMaps.vectorsById.get(ASTEROIDS_VECTOR_MAP_IDS.ufoSmall).points.slice(0, 5),
213+
[
214+
{ x: -14, y: 3 },
215+
{ x: 14, y: 3 },
216+
{ x: 9, y: 9 },
217+
{ x: -9, y: 9 },
218+
{ x: -14, y: 3 },
219+
],
220+
);
178221
const shipObject = loadAsteroidsObjectVectorPayload().objects.find((object) => object.id === 'object.asteroids.ship');
179222
const shipHull = shipObject.shapes.find((shape) => shape.tool === 'polygon');
180223
assert.deepEqual(shipHull.geometry.points, [
@@ -199,6 +242,12 @@ export async function run() {
199242
const missingBulletValidation = loadAsteroidsVectorMapsFromManifest(missingBulletManifest);
200243
assert.equal(missingBulletValidation.ok, false);
201244
assert.equal(missingBulletValidation.errors.some((message) => message.includes(ASTEROIDS_VECTOR_MAP_IDS.bullet)), true);
245+
const missingShipObjectManifest = structuredClone(manifestPayload);
246+
missingShipObjectManifest.tools['object-vector-studio-v2'].objects = missingShipObjectManifest.tools['object-vector-studio-v2'].objects
247+
.filter((object) => object.id !== ASTEROIDS_VECTOR_MAP_IDS.attractShip);
248+
const missingShipObjectValidation = loadAsteroidsVectorMapsFromManifest(missingShipObjectManifest);
249+
assert.equal(missingShipObjectValidation.ok, false);
250+
assert.equal(missingShipObjectValidation.errors.some((message) => message.includes(ASTEROIDS_VECTOR_MAP_IDS.attractShip)), true);
202251
const createdDocumentShim = typeof globalThis.document === 'undefined';
203252
const createdWindowShim = typeof globalThis.window === 'undefined';
204253
const shimCanvas = createCanvas();

0 commit comments

Comments
 (0)