Skip to content

Commit 1732b95

Browse files
author
DavidQ
committed
Finish Object Vector Studio V2 manifest cleanup and remove stale vector-map role usage - PR_26133_122-object-vector-final-manifest-cleanup
1 parent 19b6496 commit 1732b95

24 files changed

Lines changed: 286 additions & 328 deletions
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# PR_26133_122 Object Vector Final Manifest Cleanup Report
2+
3+
## Summary
4+
- Removed the unused `object-vector-studio-v2.vectorMaps` manifest payload so Asteroids Object Vector Studio V2 data is owned by `objects[].tags` and `objects[].shapes[]`.
5+
- Renamed Asteroids runtime helpers from vector-map/role wording to object-geometry/tag wording.
6+
- Updated Asteroids launch/runtime wiring to pass `objectGeometry` and resolve gameplay/attract objects from manifest object IDs plus tags.
7+
- Updated Object Vector Studio V2 and game manifest schemas to reject the removed shared vector-map payload.
8+
- Confirmed Workspace Manager V2 still discovers Asteroids from the game manifest path.
9+
10+
## Files Changed
11+
- `games/Asteroids/game.manifest.json`
12+
- `games/Asteroids/game/asteroidsObjectGeometryManifest.js`
13+
- `games/Asteroids/game/asteroidsObjectTags.js`
14+
- `games/Asteroids/game/AsteroidsGameScene.js`
15+
- `games/Asteroids/game/AsteroidsWorld.js`
16+
- `games/Asteroids/game/AsteroidsAttractAdapter.js`
17+
- `games/Asteroids/game/asteroidObjectGeometry.js`
18+
- `games/Asteroids/index.js`
19+
- `games/Asteroids/entities/Bullet.js`
20+
- `tools/schemas/game.manifest.schema.json`
21+
- `tools/schemas/tools/object-vector-studio-v2.schema.json`
22+
- `tools/schemas/tools/vector-map-editor.schema.json`
23+
- `tools/workspace-manager-v2/js/services/WorkspaceManagerV2ContextService.js`
24+
- Targeted Asteroids/Object Vector/Workspace Manager tests under `tests/`
25+
26+
## Validation
27+
- PASS: `node --check` for changed JavaScript and test files.
28+
- PASS: JSON parse for changed manifests/schemas.
29+
- PASS: Object Vector Studio V2 Asteroids manifest-load validation.
30+
- PASS: `tests/tools/ObjectVectorStudioV2DeleteCleanup.test.mjs`
31+
- PASS: `tests/games/AsteroidsValidation.test.mjs`
32+
- PASS: `tests/games/AsteroidsVectorTransforms.test.mjs`
33+
- PASS: `tests/games/AsteroidsAssetReferenceAdoption.test.mjs`
34+
- PASS: `tests/games/AsteroidsPlatformDemo.test.mjs`
35+
- PASS: `tests/games/AsteroidsPresentation.test.mjs`
36+
- PASS: `tests/games/AsteroidsHardening.test.mjs`
37+
- PASS: `tests/games/AsteroidsCollisionTimingStress.test.mjs`
38+
- PASS: `npx playwright test tests/playwright/tools/WorkspaceManagerV2.spec.mjs --project=playwright --workers=1 --reporter=list -g "discovers Active Game options|loads Object Vector Studio V2 runtime assets"`
39+
- PASS: `git diff --check`
40+
41+
## Skipped
42+
- `npm run test:workspace-v2` was not run; PR requested targeted Workspace Manager V2 validation only.
43+
- Full regression and full samples smoke test were not run; this change is limited to Asteroids/Object Vector manifest cleanup and Workspace Manager discovery verification.
44+
45+
## Manual Validation
46+
1. Open `tools/workspace-manager-v2/index.html`, pick the repo folder, and confirm the Active Game dropdown includes `Asteroids`.
47+
2. Select `Asteroids` and confirm the generated workspace context includes `tools["object-vector-studio-v2"].objects` and does not include `tools["object-vector-studio-v2"].vectorMaps`.
48+
3. Open `games/Asteroids/index.html` and confirm the game launches with ship, asteroid, UFO, and bullet Object Vector geometry rendering.

games/Asteroids/entities/Bullet.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default class Bullet {
2525
this.life = life;
2626
this.collisionPoints = normalizePoints(collisionPoints);
2727
if (this.collisionPoints.length < 3) {
28-
throw new Error('Asteroids Bullet requires manifest-loaded bullet vector map geometry.');
28+
throw new Error('Asteroids Bullet requires manifest-loaded bullet object geometry.');
2929
}
3030
}
3131

games/Asteroids/game.manifest.json

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,6 @@
212212
"version": 1,
213213
"toolId": "object-vector-studio-v2",
214214
"name": "Asteroids Object Vector Assets",
215-
"vectorMaps": {
216-
"schema": "html-js-gaming.asteroids-object-vector-shapes",
217-
"version": 1,
218-
"name": "Asteroids Object Vector Shape Roles",
219-
"source": "object-vector-studio-v2",
220-
"shapes": []
221-
},
222215
"objects": [
223216
{
224217
"id": "object.asteroids.bullet",

games/Asteroids/game/AsteroidsAttractAdapter.js

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

1010
function estimateTextWidth(text, fontPx) {
1111
return String(text ?? '').length * (fontPx * 0.62);
@@ -121,21 +121,21 @@ export default class AsteroidsAttractAdapter {
121121
}
122122

123123
this.scene?.drawObjectVectorAsset?.(renderer, 'attractShip', {
124-
...this.scene.objectVectorRoleOptions('ship'),
124+
...this.scene.objectVectorTagOptions('ship'),
125125
elapsedMs: this.scene.objectVectorPlaybackMs,
126126
fps: 12,
127-
objectId: ASTEROIDS_OBJECT_VECTOR_IDS.attractShip,
127+
objectId: ASTEROIDS_OBJECT_GEOMETRY_IDS.attractShip,
128128
rotation: -0.28,
129129
scale: 1.1,
130130
stateId: 'idle',
131131
x: 328,
132132
y: 348,
133133
});
134134
this.scene?.drawObjectVectorAsset?.(renderer, 'attractAsteroid', {
135-
...this.scene.objectVectorRoleOptions('asteroidLarge'),
135+
...this.scene.objectVectorTagOptions('asteroidLarge'),
136136
elapsedMs: this.scene.objectVectorPlaybackMs,
137137
fps: 12,
138-
objectId: ASTEROIDS_OBJECT_VECTOR_IDS.attractAsteroid,
138+
objectId: ASTEROIDS_OBJECT_GEOMETRY_IDS.attractAsteroid,
139139
scale: 0.72,
140140
stateId: 'active',
141141
x: 632,
@@ -210,10 +210,10 @@ export default class AsteroidsAttractAdapter {
210210
const x = 480 + Math.cos(this.demoTime * 0.7) * 220;
211211
const y = 340 + Math.sin(this.demoTime * 1.1) * 130;
212212
this.scene?.drawObjectVectorAsset?.(renderer, 'attractShip', {
213-
...this.scene.objectVectorRoleOptions('ship'),
213+
...this.scene.objectVectorTagOptions('ship'),
214214
elapsedMs: this.scene.objectVectorPlaybackMs,
215215
fps: 12,
216-
objectId: ASTEROIDS_OBJECT_VECTOR_IDS.attractShip,
216+
objectId: ASTEROIDS_OBJECT_GEOMETRY_IDS.attractShip,
217217
rotation: Math.sin(this.demoTime * 0.9) * 1.2,
218218
stateId: 'idle',
219219
x,
@@ -223,20 +223,20 @@ export default class AsteroidsAttractAdapter {
223223
const rockX = 480 + Math.sin(this.demoTime * 0.5) * 250;
224224
const rockY = 330 + Math.cos(this.demoTime * 0.9) * 120;
225225
this.scene?.drawObjectVectorAsset?.(renderer, 'attractAsteroid', {
226-
...this.scene.objectVectorRoleOptions('asteroidLarge'),
226+
...this.scene.objectVectorTagOptions('asteroidLarge'),
227227
elapsedMs: this.scene.objectVectorPlaybackMs,
228228
fps: 12,
229-
objectId: ASTEROIDS_OBJECT_VECTOR_IDS.attractAsteroid,
229+
objectId: ASTEROIDS_OBJECT_GEOMETRY_IDS.attractAsteroid,
230230
scale: 0.72,
231231
stateId: 'active',
232232
x: rockX,
233233
y: rockY,
234234
});
235235
this.scene?.drawObjectVectorAsset?.(renderer, 'attractUfo', {
236-
...this.scene.objectVectorRoleOptions('ufoLarge'),
236+
...this.scene.objectVectorTagOptions('ufoLarge'),
237237
elapsedMs: this.scene.objectVectorPlaybackMs,
238238
fps: 12,
239-
objectId: ASTEROIDS_OBJECT_VECTOR_IDS.attractUfo,
239+
objectId: ASTEROIDS_OBJECT_GEOMETRY_IDS.attractUfo,
240240
stateId: 'active',
241241
x: 480 + Math.cos(this.demoTime * 0.43) * 280,
242242
y: 284,

games/Asteroids/game/AsteroidsGameScene.js

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ import AsteroidsHighScoreService from '../systems/AsteroidsHighScoreService.js';
1515
import AsteroidsInitialsEntry from '../systems/AsteroidsInitialsEntry.js';
1616
import { createAsteroidGeometryProfilesFromObjectVectorAssets } from './asteroidObjectGeometry.js';
1717
import {
18-
ASTEROID_SIZE_RUNTIME_ROLES,
19-
runtimeObjectRoleOptions,
20-
validateAsteroidsRuntimeObjectRoles
21-
} from './asteroidsObjectVectorRoles.js';
18+
ASTEROID_SIZE_RUNTIME_OBJECT_KEYS,
19+
runtimeObjectTagOptions,
20+
validateAsteroidsRuntimeObjectTags
21+
} from './asteroidsObjectTags.js';
2222
import {
2323
ASTEROIDS_GAME_OVER_AUTO_EXIT_SECONDS, ASTEROIDS_GAME_OVER_RETURN_MODE
2424
} from "../rules/flowRules.js";
@@ -88,17 +88,17 @@ export default class AsteroidsGameScene extends Scene {
8888
this.devConsoleIntegration = options.devConsoleIntegration || null;
8989
this.objectVectorAssets = options.objectVectorAssets || null;
9090
this.objectVectorRuntime = options.objectVectorRuntime || null;
91-
this.vectorMaps = options.vectorMaps || null;
92-
if (!this.vectorMaps?.objectVectorMapsById || !this.vectorMaps?.objectsByRole) {
91+
this.objectGeometry = options.objectGeometry || null;
92+
if (!this.objectGeometry?.objectsById || !this.objectGeometry?.objectsByKey) {
9393
const message = 'Asteroids Object Vector manifest validation failed: object geometry was not loaded from game.manifest.json.';
9494
console.error(message);
9595
throw new Error(message);
9696
}
9797
this.objectVectorRuntimeObjectValidation = this.objectVectorAssets
98-
? validateAsteroidsRuntimeObjectRoles([...this.objectVectorAssets.objectsById.values()], {
98+
? validateAsteroidsRuntimeObjectTags([...this.objectVectorAssets.objectsById.values()], {
9999
logger: this.objectVectorRuntime,
100100
})
101-
: { errors: [], objectsByRole: {}, ok: false, warnings: [] };
101+
: { errors: [], objectsByKey: {}, ok: false, warnings: [] };
102102
if (this.objectVectorAssets && !this.objectVectorRuntimeObjectValidation.ok) {
103103
const message = validationFailureMessage(this.objectVectorRuntimeObjectValidation);
104104
this.objectVectorRuntime?.log?.('FAIL', message, {
@@ -125,7 +125,7 @@ export default class AsteroidsGameScene extends Scene {
125125
};
126126
this.world = new AsteroidsWorld({ width: 960, height: 720 }, {
127127
asteroidGeometryProfiles: this.asteroidGeometryProfiles,
128-
vectorMaps: this.vectorMaps,
128+
objectGeometry: this.objectGeometry,
129129
});
130130
this.highScoreService = new AsteroidsHighScoreService();
131131
this.highScoreRows = this.highScoreService.loadTable();
@@ -734,9 +734,9 @@ export default class AsteroidsGameScene extends Scene {
734734
}
735735

736736
this.world.asteroids.forEach((asteroid) => {
737-
const roleId = ASTEROID_SIZE_RUNTIME_ROLES[asteroid.size];
737+
const objectKey = ASTEROID_SIZE_RUNTIME_OBJECT_KEYS[asteroid.size];
738738
this.drawObjectVectorAsset(renderer, "asteroids", {
739-
...this.objectVectorRoleOptions(roleId),
739+
...this.objectVectorTagOptions(objectKey),
740740
elapsedMs: this.objectVectorPlaybackMs,
741741
fps: 12,
742742
rotation: asteroid.angle,
@@ -747,9 +747,9 @@ export default class AsteroidsGameScene extends Scene {
747747
});
748748

749749
if (this.world.ufo) {
750-
const roleId = this.world.ufo.type === "small" ? "ufoSmall" : "ufoLarge";
750+
const objectKey = this.world.ufo.type === "small" ? "ufoSmall" : "ufoLarge";
751751
this.drawObjectVectorAsset(renderer, "ufo", {
752-
...this.objectVectorRoleOptions(roleId),
752+
...this.objectVectorTagOptions(objectKey),
753753
elapsedMs: this.objectVectorPlaybackMs,
754754
fps: 12,
755755
stateId: "active",
@@ -760,7 +760,7 @@ export default class AsteroidsGameScene extends Scene {
760760

761761
this.world.bullets.forEach((bullet) => {
762762
this.drawObjectVectorAsset(renderer, "bullet", {
763-
...this.objectVectorRoleOptions("bullet"),
763+
...this.objectVectorTagOptions("bullet"),
764764
stateId: "active",
765765
x: bullet.x,
766766
y: bullet.y,
@@ -769,7 +769,7 @@ export default class AsteroidsGameScene extends Scene {
769769

770770
this.world.ufoBullets.forEach((bullet) => {
771771
this.drawObjectVectorAsset(renderer, "bullet", {
772-
...this.objectVectorRoleOptions("bullet"),
772+
...this.objectVectorTagOptions("bullet"),
773773
stateId: "active",
774774
x: bullet.x,
775775
y: bullet.y,
@@ -780,7 +780,7 @@ export default class AsteroidsGameScene extends Scene {
780780

781781
if (this.world.shipActive && !this.session.isTurnIntroActive() && this.session.mode !== 'menu') {
782782
this.drawObjectVectorAsset(renderer, "ship", {
783-
...this.objectVectorRoleOptions("ship"),
783+
...this.objectVectorTagOptions("ship"),
784784
elapsedMs: this.objectVectorPlaybackMs,
785785
fps: 12,
786786
rotation: this.world.ship.angle,
@@ -857,8 +857,8 @@ export default class AsteroidsGameScene extends Scene {
857857
this.publishObjectVectorRuntimeDiagnostics();
858858
}
859859

860-
objectVectorRoleOptions(roleId) {
861-
return runtimeObjectRoleOptions(roleId);
860+
objectVectorTagOptions(objectKey) {
861+
return runtimeObjectTagOptions(objectKey);
862862
}
863863

864864
drawLives(renderer, centerX, y, lives) {
@@ -869,7 +869,7 @@ export default class AsteroidsGameScene extends Scene {
869869
const startX = centerX - ((lives - 1) * LIFE_SPACING) / 2;
870870
Array.from({ length: lives }).forEach((_, index) => {
871871
this.drawObjectVectorAsset(renderer, "shipLife", {
872-
...this.objectVectorRoleOptions("ship"),
872+
...this.objectVectorTagOptions("ship"),
873873
elapsedMs: this.objectVectorPlaybackMs,
874874
fps: 12,
875875
rotation: -Math.PI / 2,
@@ -916,10 +916,9 @@ export default class AsteroidsGameScene extends Scene {
916916
assetCount: this.objectVectorAssets?.objectsById?.size || 0,
917917
loaded: Boolean(this.objectVectorAssets),
918918
objectCount: this.objectVectorAssets?.objectsById?.size || 0,
919-
objectVectorObjectIds: this.vectorMaps?.objectVectorMaps?.map((object) => object.id) || [],
919+
objectVectorObjectIds: this.objectGeometry?.objects?.map((object) => object.id) || [],
920920
runtimeObjectsValid: Boolean(this.objectVectorRuntimeObjectValidation?.ok),
921921
renderCounts: { ...this.objectVectorRenderCounts },
922-
sharedShapeCount: this.vectorMaps?.shapes?.length || 0,
923922
};
924923
} catch {
925924
// Ignore diagnostics assignment in restricted runtimes.

games/Asteroids/game/AsteroidsWorld.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import { distance } from '../../../src/shared/utils/mathUtils.js';
1313
import { randomRange } from '../utils/math.js';
1414
import { sanitizeFiniteNumber, sanitizePositiveNumber } from '../../../src/shared/math/numberNormalization.js';
1515
import {
16-
requireAsteroidsObjectVectorPoints,
17-
} from './asteroidsVectorMaps.js';
16+
requireAsteroidsObjectGeometryPoints,
17+
} from './asteroidsObjectGeometryManifest.js';
1818

1919
const WAVE_ASTEROID_COUNTS = [4, 6, 8];
2020
const RESPAWN_SAFE_DISTANCE = 100;
@@ -139,21 +139,21 @@ function getRectOverlapDepth(x, y, radius, rect) {
139139
}
140140

141141
export default class AsteroidsWorld {
142-
constructor(bounds, { rng = Math.random, asteroidGeometryProfiles = null, vectorMaps = null } = {}) {
142+
constructor(bounds, { rng = Math.random, asteroidGeometryProfiles = null, objectGeometry = null } = {}) {
143143
if (!hasLoggedWorldConstruction) {
144144
hasLoggedWorldConstruction = true;
145145
logWorldBootStage('constructed', bounds);
146146
}
147147
this.asteroidGeometryProfiles = asteroidGeometryProfiles;
148-
this.vectorMaps = vectorMaps;
149-
if (!this.vectorMaps?.objectVectorMapsById) {
148+
this.objectGeometry = objectGeometry;
149+
if (!this.objectGeometry?.objectsById) {
150150
throw new Error('AsteroidsWorld requires manifest-loaded Object Vector geometry for ship, UFO, asteroid, and bullet gameplay geometry.');
151151
}
152-
this.bulletCollisionPoints = requireAsteroidsObjectVectorPoints(this.vectorMaps, 'bullet', 'bullet object geometry');
153-
this.shipCollisionPoints = requireAsteroidsObjectVectorPoints(this.vectorMaps, 'ship', 'ship object geometry');
152+
this.bulletCollisionPoints = requireAsteroidsObjectGeometryPoints(this.objectGeometry, 'bullet', 'bullet object geometry');
153+
this.shipCollisionPoints = requireAsteroidsObjectGeometryPoints(this.objectGeometry, 'ship', 'ship object geometry');
154154
this.ufoCollisionPoints = {
155-
large: requireAsteroidsObjectVectorPoints(this.vectorMaps, 'ufoLarge', 'large UFO object geometry'),
156-
small: requireAsteroidsObjectVectorPoints(this.vectorMaps, 'ufoSmall', 'small UFO object geometry'),
155+
large: requireAsteroidsObjectGeometryPoints(this.objectGeometry, 'ufoLarge', 'large UFO object geometry'),
156+
small: requireAsteroidsObjectGeometryPoints(this.objectGeometry, 'ufoSmall', 'small UFO object geometry'),
157157
};
158158
this.rng = typeof rng === 'function' ? rng : Math.random;
159159
this.bounds = sanitizeBounds(bounds);

games/Asteroids/game/asteroidObjectGeometry.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
2-
ASTEROID_SIZE_RUNTIME_ROLES,
3-
resolveAsteroidsObjectVectorRole,
4-
} from './asteroidsObjectVectorRoles.js';
2+
ASTEROID_SIZE_RUNTIME_OBJECT_KEYS,
3+
resolveAsteroidsTaggedObject,
4+
} from './asteroidsObjectTags.js';
55

66
const ASTEROID_SIZE_LABELS = Object.freeze({
77
1: 'SML',
@@ -64,8 +64,8 @@ function extractPrimaryPolygonPoints(object) {
6464
function createProfilesFromObjects(objects, options = {}) {
6565
const profiles = {};
6666

67-
Object.entries(ASTEROID_SIZE_RUNTIME_ROLES).forEach(([size, roleId]) => {
68-
const object = resolveAsteroidsObjectVectorRole(objects, roleId, options);
67+
Object.entries(ASTEROID_SIZE_RUNTIME_OBJECT_KEYS).forEach(([size, objectKey]) => {
68+
const object = resolveAsteroidsTaggedObject(objects, objectKey, options);
6969
const points = centerPoints(extractPrimaryPolygonPoints(object));
7070
if (points.length < 3) {
7171
return;

0 commit comments

Comments
 (0)