# Procedural Machine Blueprints and Asset Replacement Points

Milestone 5 adds a complete procedural blueprint layer for the 28 Phase 1 machines under `src/modules/machines/procedural/`. These blueprints are intentionally data-driven: the catalogue and learning registry can describe engineering meaning, while the blueprint layer describes how to draw a clean diagrammatic 3D assembly and where production GLB assets can replace procedural geometry later.

## What the blueprint registry contains

`CORE_MACHINE_BLUEPRINTS` is keyed by the canonical core machine IDs:

- Engines: `four-stroke-petrol-engine`, `two-stroke-engine`, `diesel-engine`, `v8-engine`, `wankel-rotary-engine`, `steam-engine`, `jet-engine-turbojet`, `turbofan-engine`
- Gearboxes & drives: `planetary-gearbox`, `differential-gear`, `manual-gearbox-5-speed`, `cvt`, `worm-gear-drive`, `bevel-gear-set`
- Pumps & fluid systems: `centrifugal-pump`, `gear-pump`, `piston-pump`, `hydraulic-cylinder`
- Mechanisms: `scotch-yoke`, `geneva-drive`, `cam-and-follower`, `rack-and-pinion`, `slider-crank`, `toggle-clamp`
- Structural / other: `ball-bearing`, `roller-bearing`, `disc-brake-caliper`, `turbocharger`

Each blueprint includes:

- Machine identity, category, layout, scale, animation profile ID, and guided-tour stage IDs.
- A hierarchical procedural node tree with part IDs used by selection, opacity, labels, and exploded views.
- Motion bindings that map procedural geometry to animation channels without requiring machine-specific viewer code.
- High-priority labels for annotation mode.
- Catalogue thumbnail strategy.
- GLB replacement points with suggested asset paths and authoring notes.
- Performance notes for instancing, shader overlays, and mobile-friendly rendering.

## Viewer integration contract

A renderer should traverse `blueprint.nodes` recursively:

1. Create a group for every `kind: "group"` node.
2. Render primitive nodes using the `kind`, `material`, `transform`, `dimensions`, and `metadata` fields.
3. Bind interactivity to `partId`, not to node IDs. This keeps opacity, visibility, exploded offsets, guided-tour highlights, and selected-part drawers aligned with the educational registry.
4. Apply `explodedOffset` when exploded view is enabled.
5. Register `labelAnchor` or the matching label position with the annotation system.
6. Bind `motionBindings` to the standard animation player. The `channel` names are stable semantic channels; the animation module decides how normalized time, RPM, time scale, and step-through mode map onto those channels.

The procedural node schema allows extension by string literal for primitive kinds and materials, so a renderer can add richer primitives later without changing the machine registry.

## GLB replacement workflow

The procedural assemblies are production fallbacks, not throwaway placeholders. When a professional model is available, add it at the `suggestedAssetPath` listed in the blueprint replacement point, for example:

```text
src/assets/machines/turbocharger/turbine-side.glb
src/assets/machines/planetary-gearbox/planet-set.glb
src/assets/machines/four-stroke-petrol-engine/crank-train.glb
```

Replacement rules:

1. Author assets in meters unless a replacement point explicitly states millimeters.
2. Preserve the documented up axis and origin. Most replacement points use `component-local-center` with Y-up.
3. Keep selectable sub-components named by `partId` whenever possible.
4. If an asset replaces an animated component, align the documented local axis with the motion binding:
   - piston/rod/cylinder stroke is usually local X or Y as noted,
   - gear and wheel rotation is usually local Z,
   - turbine/fan/compressor spool rotation is usually local X,
   - hydraulic strokes and rack travel follow the node notes.
5. Keep covers, shells, and housings separate when the note calls for cutaway or exploded-view control.
6. Do not import optional GLB files statically unless they exist. The loader should resolve replacement points dynamically and fall back to procedural nodes when an asset is absent.

This allows professional CAD/GLB replacements to be introduced machine-by-machine without touching catalogue data, animation modules, or viewer interaction code.

## Thumbnail strategy

Every blueprint includes a `thumbnail` object. The intended catalogue flow is:

1. Render procedural thumbnail using `cameraPreset`, `accentPartIds`, and the dark radial background.
2. Cache the rendered image as an application asset when a stable render pipeline is available.
3. If a hero GLB exists for the machine, switch the strategy to a hybrid or asset render while preserving the same `accentPartIds` and camera framing.

This avoids blank catalogue cards before final assets arrive and keeps the product feeling complete during incremental asset upgrades.

## Validation helper

`validateCoreMachineBlueprintCoverage()` performs structural checks that are useful in tests or development diagnostics:

- all expected machine IDs have blueprints,
- replacement points reference existing procedural node IDs,
- labels reference existing procedural node IDs,
- duplicate node IDs are detected,
- anchor parts and replacement part IDs are checked against the node tree.

A lightweight unit test can import this helper and assert that no `severity: "error"` issues are returned.

## Performance implementation notes

- Repeating balls, rollers, gear teeth, fan blades, compressor blades, turbine blades, and V8 cylinder/piston sets should be rendered with instancing where supported.
- Flow arrows, heat glow, spark pulses, pressure gauges, and load arrows should be overlay primitives driven by shader uniforms rather than repeatedly recreated meshes.
- Cutaways should be authored as procedural sectioned shells or pre-sectioned GLB meshes. Runtime boolean CSG is not required for these Phase 1 diagrams.
- Animation bindings are analytical and loop from normalized phase, which keeps step-through mode deterministic and prevents transform drift after long sessions.
