# Procedural Demo Set and Guided Tour Runtime Milestone 4 ships a representative procedural machine set for the animation system. The demo set is intentionally data-driven: each machine module owns its geometry, part metadata, engineering facts, animation lifecycle, and guided tour content, while `proceduralDemoManifest.ts` provides a stable catalogue/runtime adapter for loading them without hard-coding viewer logic. ## Included procedural machines | Machine | Category | Motion demonstrated | Primary highlighted parts | | --- | --- | --- | --- | | Four Stroke Petrol Engine | Engines | 720° Otto cycle with valve timing, piston travel, crankshaft/camshaft relationship | Piston, crankshaft, camshaft, intake valve, exhaust valve | | Planetary Gearbox | Gearboxes & Drives | Sun/planet/ring epicyclic mesh and carrier rotation | Sun gear, planet gears, ring gear, carrier | | Differential Gear | Gearboxes & Drives | Equal torque split with wheel speed difference while cornering | Ring gear, spider gears, side gears | | Centrifugal Pump | Pumps & Fluid Systems | Impeller acceleration, volute pressure recovery, cavitation cueing | Impeller, volute, inlet, outlet, shaft | | Geneva Drive | Mechanisms | Continuous crank rotation to intermittent indexed output | Driver, pin, Geneva wheel, locking disk | | Ball Bearing | Structural / Other | Rolling contact, cage precession, load distribution | Inner race, outer race, balls, cage, load vector | | Disc Brake Caliper | Structural / Other | Hydraulic clamp/release cycle, rotor drag, friction heat cueing | Rotor, caliper body, pads, pistons, hydraulic line | | Wankel Rotary Engine | Engines | Eccentric rotor orbit, chamber volume change, port timing | Rotor, housing, eccentric shaft, intake port, exhaust port | ## Runtime loading Use the manifest adapter for catalogue or viewer integrations: ```ts import { loadProceduralDemoMachine, proceduralDemoMachineManifest, } from '../src/modules/machines/procedural/demoRuntime'; const entry = proceduralDemoMachineManifest[0]; const machine = await loadProceduralDemoMachine(entry.id); console.log(machine.title, machine.parts, machine.guidedTour); ``` For React views, use the hook: ```tsx import { useProceduralDemoMachine } from '../src/modules/machines/procedural/demoRuntime'; export function DemoMachinePanel({ machineId }: { machineId: string }) { const { status, machine, error, reload } = useProceduralDemoMachine(machineId); if (status === 'loading') return

Loading machine…

; if (status === 'error') return ; if (!machine) return null; return (

{machine.title}

{machine.description}

{machine.parts.length} modeled parts

); } ``` The normalizer accepts several common machine-module shapes (`default`, `machine`, `definition`, `Scene`, `animationModule`, `parts`, `engineeringFacts`, `guidedTour`) so the core catalogue remains resilient as future machines are added. ## Guided tours `GuidedTourPlayer` is a GSAP-ticker-backed tour controller that advances steps using requestAnimationFrame timing through `gsap.ticker`. It supports: - play, pause, resume, restart, stop - manual next/previous step navigation - looped or one-shot tours - time scale adjustment - reduced-motion mode with shortened step durations and instant camera moves - lifecycle hooks: `onEnter`, `onFrame`, `onExit` - host callbacks for camera poses, part highlighting, part isolation, annotations, explode factor, machine playback, and RPM A viewer supplies a host object: ```ts import { GuidedTourPlayer, createThreeCameraTourHost, } from '../src/animations/tourRuntime'; const host = createThreeCameraTourHost(camera, { controls: orbitControls, highlightParts: (partIds) => setHighlightedParts(partIds), selectPart: (partId) => setSelectedPart(partId), setExplodeFactor: (explodeFactor) => setExplode(explodeFactor ?? 0), setMachinePlayback: (playback) => { if (playback === 'pause') animation.pause(); else animation.play(); }, setRpm: (rpm) => animation.setRpm(rpm), }); const player = new GuidedTourPlayer(machine.guidedTour, host, { defaultStepDurationSeconds: 5, loop: false, }); ``` React integrations should prefer `useGuidedTourPlayer`, which subscribes to snapshots and cleans up the GSAP ticker on unmount. ## UI controls The new animation UI components are intentionally presentation-only: - `AnimationTransport` renders playback, restart, step-through, RPM, time-scale, and loop controls. - `GuidedTourOverlay` renders tour captions, step progress, keyboard controls, and direct step navigation. They accept plain snapshots and callback objects, so they can be connected to the existing `MachineAnimationPlayer`, Zustand stores, or a page-level adapter without coupling the controls to machine-specific animation code. ## Authoring requirements for new machines A new procedural machine should export at least: 1. A React scene component. 2. A standard animation module compatible with the milestone animation player. 3. Part metadata with stable IDs. 4. Engineering facts. 5. Guided tour steps using the `GuidedTourStepDefinition` shape. 6. A manifest entry with category, difficulty, keywords, RPM range, and featured part IDs. Stable part IDs are important because they are used by: - URL view-state sharing - part visibility and opacity controls - selected-part detail drawers - guided-tour highlights - annotations and labels - accessibility announcements ## Reduced-motion behavior Reduced-motion preference is detected with `prefers-reduced-motion: reduce` in `usePrefersReducedMotion`. When enabled: - tour auto-start is suppressed unless explicitly allowed - tour camera transitions are immediate - default step durations are capped by `reducedMotionStepDurationSeconds` - controls remain keyboard-accessible and fully functional Machine animations should still honor their own reduced-motion policy, typically by starting paused and requiring explicit user playback. ## Quality checklist Before marking a new machine production-ready: - The loop has no visible discontinuity at the cycle seam. - RPM scaling changes speed without changing kinematic relationships. - Step-through advances to meaningful mechanical phases. - Every selectable part has a human-readable name and useful description. - Guided tour step highlights reference real part IDs. - Camera poses avoid clipping through the model at desktop, tablet, and mobile aspect ratios. - The scene is legible in solid, transparent, and wireframe display modes. - Motion remains understandable at `0.1×` and does not become visually noisy at `3×`. - Reduced-motion mode does not auto-animate camera or machine movement. - All host subscriptions/tickers/tweens are disposed when leaving the viewer.