Skip to content

[FEATURE] Bring-your-own assets: import spec for every asset kind, editor ingest, game-defined component schemas #1689

Description

@Noisemaker111

Problem: only GLB/glTF can be brought in, objects have one kind and a flat meta bag, and procedural styles are a closed union. Verified on main: packages/node/src/editorHostPlugin.ts:71 throws for non-glTF; packages/editor/src/assetImport.ts:13 MODEL_FILE = /\.(glb|gltf)$/i; packages/assets/src/catalogs/build.ts CatalogExtra is { url }; packages/core/src/scene/sceneKinds.ts ParamField has no asset-ref, object-ref, vec3, curve, or gradient; space is unset in every generated index entry; packages/core/src/world/buildings.ts BuildingStyle is a closed union.

Tasks, one PR each, in order:

  1. Import spec (assets package, pure). New packages/assets/src/importSpec.ts: AssetImportSpec { id: string; kind: "model" | "texture" | "material" | "sprite" | "spriteSheet" | "audio" | "font" | "hdri"; files: { path: string; role?: string }[]; meta?: Record<string, unknown> }, validateImportSpec(spec) -> { ok: true; entry } | { ok: false; reason }, classifyAssetFile(bytes, filename) -> kind | null (magic bytes for glb, png, jpg, ktx2, ogg, wav, mp3, ttf/otf/woff2, hdr, exr; JSON with frames as spriteSheet). Widen CatalogExtra to carry dims, space, clips, collisionMesh. Move the signature checks in packages/core/src/scene/assetDiagnostics.ts to classify instead of rejecting. Tests with byte fixtures. bun run gen. CHANGELOG Added.

  2. Editor ingest. editorHostPlugin.ts, assetImport.ts, packages/editor/src/shell/ContentBrowser.tsx accept every kind from task 1 (drop or file picker), write under the game's public/assets/<kind>/, and register a catalog entry; packages/editor/src/mcp/tools.ts gets an importAsset tool with the same spec. Shots: the content browser showing a dropped PNG, WAV, and TTF.

  3. Inspector fields. Add assetRef (with kinds filter), objectRef, vec3, curve (list of [t, v] points), gradient (list of [t, hex]) to ParamField in sceneKinds.ts and widgets in packages/editor/src/chromeFields.tsx (asset picker reuses the content browser, object picker reuses ParentPickerMenu). Tests for schema validation. Shots.

  4. Game-defined components. New packages/core/src/scene/components.ts: registerComponent({ id; targets: ("marker" | "volume" | "path")[]; schema: ParamSchema; defaults }), componentsOf(object) -> Record<id, data> reading meta.components[id], setComponent(doc, objectId, id, data) as an editor command in packages/core/src/editor/commands.ts. packages/editor/src/InspectorPanel.tsx renders every registered component for the selected object with an add/remove menu. Test: a registered component round-trips through the document. Shots.

  5. Populate space. In packages/assets/src/cli/pull.ts and indexGen.ts, derive space (canonical facing from the longest horizontal extent, unit scale from dims, anchor from minY) with a per-pack override table in packages/assets/src/packs/*.ts; regenerate the index JSON (bun --cwd=packages/assets run reindex or the documented command). Test on two entries.

  6. Style profiles. New packages/core/src/world/styleProfile.ts: StyleProfile { id; palettes: Record<string, string>; materials?: Record<string, string>; massing?: MassingRule[] }, registerStyleProfile, resolveStyleProfile(id); register the ten existing palettes from buildings.ts as profiles and make buildings.ts and packages/shell/src/scatter/scatterProxies.ts resolve through meta.styleId with the current defaults, so output is unchanged until a game registers its own. Shots: the city with a custom profile. Closes #1689.

Rules: wait for bun run agent:bootstrap --check; branch claude/<slug> off origin/main; claim comment first; one task per PR with Refs #1689; bun run gen after export changes (JSDoc on every export); CHANGELOG bullet; check-types and test on assets, core, node, editor as touched plus check-stateful-ratchet, check-doc-symbols, check-orphan-ratchet, check-asset-availability; merge origin/main before pushing; shots via bun run shoot; never add Kenney assets; squash auto-merge; fix CI on the same branch.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions