Editor
Full-featured scene editor with 3D viewport, entity inspector, particle editor, audio studio, and world management. Built entirely in vanilla JS with no frameworks.
Architecture
editor/
├── index.html ← Entry point
├── js/
│ ├── EditorApp.js ← Main app class — orchestrates everything
│ ├── ProjectManager.js ← Scene save/load, localStorage persistence
│ ├── main.js ← Bootstrap and initialization
│ ├── panels/
│ │ ├── Viewport.js ← 3D canvas, camera, render loop (~6.7K lines)
│ │ ├── Inspector.js ← Entity component editor
│ │ ├── WorldPanel.js ← Scene settings, lighting, shader modes
│ │ └── HierarchyPanel.js ← Entity tree view
│ ├── modules/
│ │ ├── EditorParticles.js ← Particle system integration (per-frame)
│ │ ├── EditorSettings.js ← User preferences (rendering, physics, audio, controls)
│ │ ├── EditorAudio.js ← Audio preview and editing
│ │ └── EditorPhysics.js ← Physics sandbox controls
│ ├── components/
│ │ ├── AudioEditorPanel.js ← Node-graph audio patch editor
│ │ └── ...UI components
│ └── gizmos/
│ ├── TranslateGizmo.js ← 3-axis translation handles
│ ├── RotateGizmo.js ← Rotation rings
│ └── ScaleGizmo.js ← Scale handles
└── css/ ← Editor styles (dark theme)
EditorApp
EditorApp.js is the central orchestrator. It owns the ECS world, render loop, and all panel references. Key responsibilities:
- Init — Creates vGPU, ECS world, LightManager, all panels
- Render loop — Calls stepParticles → stepECS → renderFrame every frame
- Entity management — Spawn, delete, select, clone entities
- State delegation — Exposes getters for panels to query (e.g.,
getParticleDecals())
Viewport
The Viewport panel (~6.7K lines) manages the 3D canvas, orbit camera, and the multi-pass render pipeline. Each frame it:
- Updates camera from mouse/keyboard input
- Uploads frame uniforms (camera matrices, lighting, time)
- Runs debug pre-passes if a view mode is active (particle depth, debug textures)
- Renders: entities → grid → SDF colliders → cloth/rope → particles → volume smoke → gizmos
- Post-pass: depth copy → scene debug viz → shadows → distortion → SPH → bloom → tonemap → TSR
Debug View Modes
The toolbar dropdown (#view-mode-selector) provides 10 render view modes:
| Mode | Type | Description |
|---|---|---|
| Final Render | Default | Full lit scene with all post-processing |
| Depth Buffer | Scene-wide | Linearized depth (near=white, far=black) from hardware depth + particle depth |
| Normal Maps | Scene-wide | World-space normals reconstructed from depth (RGB = XYZ) |
| Albedo/Color | Particle | Raw particle color without lighting |
| Lighting Only | Particle | Diffuse lighting on synthesized sphere normals |
| Velocity | Particle | Speed heatmap (blue→red) |
| Age/Lifetime | Particle | Normalized age gradient |
| Emissive | Particle | Luminance-based emission intensity |
| Size | Particle | Normalized particle size gradient |
| Thermal | Particle | Blackbody color from temperature (Kelvin) |
Scene-wide modes run as a post-pass on the actual depth buffer (see Rendering → Debug Visualization). Particle modes render to a separate texture before the main pass.
Inspector
The Inspector panel shows editable component cards for the selected entity. Each component type has a custom card with appropriate controls (sliders, color pickers, dropdowns). Changes are written back to ECS components in real time.
World Panel
Controls global scene settings:
- Shader mode — Standard / Unlit / Normals / Depth
- Lighting — Sun direction, color, intensity, ambient
- Physics — Gravity, friction, restitution
- Debug — Wireframe, bounds, collision shapes
Editor Settings
EditorSettings.js provides user-configurable preferences persisted to localStorage. Settings are organized by category:
| Category | Key Settings |
|---|---|
| rendering | reconstructionMode (tsr/fsr/svgf), tsrQuality, fsrSharpness, reconstructionEnabled |
| physics | grabMode (toggle/hold), showFairyCursor (bool) |
| environment | windSpeed, windDirection, turbulence |
| audio | spatialAudio, quality, maxVoices |
| lighting | mode (dynamic/unlit), sunIntensity, ambientIntensity, solidFloor |
| controls | Separate play-mode and edit-mode hotkey bindings |
Audio Editor
The AudioEditorPanel provides a visual node-graph editor for creating audio patches. Nodes can be connected, parameters tweaked with sliders, and patches previewed in real time using the Web Audio API. See the Audio guide for details on the synthesis system.
Scene Persistence
ProjectManager.js handles save/load via localStorage:
- Scene save — Serializes ECS world, entity list, render state, particle configs
- Scene load — Restores world, re-creates entities with GPU resources, heals components
- Auto-save — Periodic snapshots to prevent data loss
Key Files
| File | Lines | Purpose |
|---|---|---|
editor/js/EditorApp.js | ~2K | Central orchestrator |
editor/js/panels/Viewport.js | ~6.7K | 3D viewport, camera, multi-pass render loop, debug viz |
editor/js/modules/EditorParticles.js | ~2K | Particle system per-frame integration, debug renderers |
editor/js/modules/EditorSettings.js | ~400 | User preferences (rendering, physics, audio, controls) |
editor/js/components/AudioEditorPanel.js | ~1.5K | Node-graph audio patch editor |
editor/js/ProjectManager.js | ~1K | Save/load/auto-save |