# Blacksite Editor Roadmap: Jackdaw-Inspired Feature Tickets

Date: 2026-06-06

Target repository: `Falling-Metal-Interactive/Blacksite` on `main`.

Purpose: turn Blacksite from a game-specific editor scaffold into a more functional Bevy editor sandbox for a future game, while preserving Blacksite's existing strengths: authoring components, hydration, schema validation, in-process PIE, and a high-fidelity unified viewport.

This document is inspired by Jackdaw's public README and book, especially its brush geometry, material browser, terrain tools, physics placement workflow, project launcher, extension model, and open challenges. It is not a recommendation to clone Jackdaw wholesale.

## Executive summary

Blacksite already has the hard foundation pieces: an editor crate, ordered plugin group, project settings, scene schema validation, authoring/hydration split, docked egui UI, asset browser, material/prefab/static-mesh systems, command palette, BRP, and PIE. The biggest functional gaps for an editor sandbox are native geometry authoring, better material workflow, terrain, physics placement, and a more general extension/project story.

Recommended sequence:
- **M0 - Foundation and polish seams:** Make the sandbox easy to start, easy to extend internally, and safe to mutate. This is the prerequisite for bigger tools.
- **M1 - Brush-based blockout:** Add the Jackdaw-inspired level-blockout workflow: brush schema, draw/edit modes, CSG, per-face materials.
- **M2 - Materials and asset pipeline:** Make assets feel live and production-like: material browser, PBR grouping, drag/drop assignment, reference repair, headless processing.
- **M3 - Terrain and physics placement:** Add larger-world authoring and practical prop placement: terrain sculpting plus physics drop/settle.
- **M4 - Extensibility and runtime integration:** Turn Blacksite from a single editor crate into a future-game editor platform through static extensions and narrow remote prototypes.
- **M5 - Regression, docs, and first-hour UX:** Lock in quality: samples, tests, profiling, docs, and first-run guidance.

## Guiding principles

- Keep Blacksite game-ready: preserve the authoring/hydration model instead of serializing runtime ECS directly.
- Adopt Jackdaw ideas as patterns, not a wholesale format or architecture migration.
- Use one operator path for every user mutation: preview, commit, cancel, undo, redo, dirty flag, status message.
- Prefer statically linked extension APIs first. Dynamic dylib loading should be an experiment, not a foundation.
- Every modal tool needs visual preview, clear status text, Escape cancel, and grouped undo.
- Every new authoring component needs schema migration, save allowlist, validation, hydration stripping, and docs.
- Every visible workflow change updates root README controls and docs/editor indexes in the same task.

## Feature gap map

| Jackdaw-inspired area | Current Blacksite state | Roadmap decision | Tickets |
|---|---|---|---|
| Project launcher and scaffolds | Blacksite has ProjectWorkspace, user prefs, project open/new, and window titles. | Add launcher and templates as optional front door. | BS-JD-001, BS-JD-402 |
| JSN / future BSN scene-document model | Blacksite uses Bevy DynamicScene RON with schema stamping, migration, and authoring-only validation. | Keep RON now; add SceneDocument abstraction to make future format changes mechanical. | BS-JD-002 |
| Component metadata and reflected inspector categories | Blacksite has component registry and typed actor inspector. | Formalize metadata and use it across inspector, palette, docs, and dependency validation. | BS-JD-003 |
| Operator framework | Blacksite has EditorHistory and EditorCommandRegistry. | Unify all mutating actions behind preview/commit/cancel/undo operators. | BS-JD-004 |
| Brushes and CSG | Blacksite has primitives/static meshes, no native brush geometry yet. | Add authoring brush data, draw/edit modes, CSG, per-face material/UV. | BS-JD-101 to BS-JD-106 |
| Material browser and PBR auto-detection | Blacksite has MaterialAsset, material overrides, asset browser, thumbnails. | Add dedicated Material Browser, texture-set detection, drag/drop material assignment. | BS-JD-201 to BS-JD-203 |
| Terrain sculpting | No native terrain authoring found in inspected Blacksite editor modules. | Add heightmap/chunk terrain MVP and brush tools. | BS-JD-301 to BS-JD-303 |
| Physics placement tool | Blacksite has Avian, ColliderDesc/RigidBodyDesc, visualizers, PIE sim. | Add selected-body drop/settle/commit tool and collider diagnostics. | BS-JD-304 to BS-JD-305 |
| Dylib extensions | Blacksite has EditorPlugin, command palette, ActorInspectorSection, optional game hot reload. | Stabilize static extension API first; treat dylib as later experimental. | BS-JD-401 to BS-JD-403 |
| Remote PIE/inspector | Blacksite has in-process PIE and BRP plugin. | Prototype narrow BRP write path before out-of-process game preview. | BS-JD-404 to BS-JD-405 |

## Milestone plan

### M0: Foundation and polish seams

Make the sandbox easy to start, easy to extend internally, and safe to mutate. This is the prerequisite for bigger tools.

- **BS-JD-000 [P0] Adoption policy, license notes, and source attribution** - Document which Jackdaw ideas are being adapted, which code may be referenced, and the license/attribution rules for any direct copying.
- **BS-JD-001 [P0] Project launcher and sandbox profiles** - Add an optional launcher/start screen for recent projects, new sandbox project, open project, and last scene resume.
- **BS-JD-002 [P0] Scene document abstraction above DynamicScene RON** - Keep Blacksite's Bevy DynamicScene RON for now, but introduce a SceneDocument layer that tools edit instead of touching Bevy serialization directly.
- **BS-JD-003 [P0] Editor metadata for components** - Add explicit component metadata for category, description, hidden state, icon, dependencies, and authoring/runtime behavior.
- **BS-JD-004 [P0] Unified operator/action framework** - Unify command palette actions, history commands, asset drag/drop, and modal tools behind one operator interface with preview, commit, cancel, and undo.
- **BS-JD-005 [P1] Command palette polish and fuzzy matching** - Upgrade Ctrl+P into a fast launcher for commands, tools, panels, assets, and help.
- **BS-JD-006 [P1] Selection and editing shortcut polish** - Add box select, component copy/paste, visibility shortcut, reset transforms, and clearer selection state.
- **BS-JD-007 [P1] Viewport productivity controls** - Expand camera bookmarks, grid controls, speed controls, nudge keys, and transform constraints.

### M1: Brush-based blockout

Add the Jackdaw-inspired level-blockout workflow: brush schema, draw/edit modes, CSG, per-face materials.

- **BS-JD-101 [P0] Brush authoring schema and hydration MVP** - Add a convex brush authoring component that serializes as planes/faces and hydrates into generated mesh/collider children.
- **BS-JD-102 [P0] Quick add and draw-brush tool** - Add brush creation via menu/context actions and a modal draw tool that places vertices on a face or floor, then extrudes to a convex brush.
- **BS-JD-103 [P0] Brush element edit modes** - Add vertex, edge, face, and clip edit modes for selected brushes.
- **BS-JD-104 [P1] Brush CSG operations** - Implement subtract, intersect, and convex merge for selected brushes.
- **BS-JD-105 [P1] Per-face material and UV controls** - Allow brush faces to reference textures/materials and edit UV offset, scale, and rotation.
- **BS-JD-106 [P2] Brush validation, repair, and diagnostics** - Add robust error handling for degenerate brushes, inverted normals, zero-area faces, and non-manifold results.

### M2: Materials and asset pipeline

Make assets feel live and production-like: material browser, PBR grouping, drag/drop assignment, reference repair, headless processing.

- **BS-JD-201 [P0] Material Browser and shared material catalog** - Create a dedicated Material Browser panel for named PBR materials, scene-local materials, and project-wide material assets.
- **BS-JD-202 [P1] PBR texture-set auto-detection** - Detect texture sets from filenames and generate draft materials automatically.
- **BS-JD-203 [P0] Drag/drop material and texture application** - Make texture/material drag/drop work consistently for static mesh actors, primitive actors, and brush faces.
- **BS-JD-204 [P1] Live asset watcher and refresh** - Watch assets/ and refresh asset catalog, thumbnails, and material registry without manual refresh.
- **BS-JD-205 [P1] Asset rename/move reference repair** - Track asset moves/renames and repair scene/material/prefab references.
- **BS-JD-206 [P2] Headless asset processing command** - Add xtask/cargo-style command to process assets without opening the editor UI.

### M3: Terrain and physics placement

Add larger-world authoring and practical prop placement: terrain sculpting plus physics drop/settle.

- **BS-JD-301 [P1] Terrain authoring schema and chunked mesh hydration** - Add a heightmap-backed TerrainDesc authoring component with chunked generated meshes.
- **BS-JD-302 [P1] Terrain sculpt tools with stroke undo** - Implement raise/lower, flatten, smooth, and noise sculpt brushes with one undo entry per stroke.
- **BS-JD-303 [P2] Terrain material layers and texture painting MVP** - Add terrain material layers with simple weight painting.
- **BS-JD-304 [P1] Physics placement tool** - Let users select props, release them into simulated gravity, then commit or cancel settled transforms.
- **BS-JD-305 [P1] Collider authoring diagnostics and overlays** - Improve collider visualization, shape switching, and error reporting.

### M4: Extensibility and runtime integration

Turn Blacksite from a single editor crate into a future-game editor platform through static extensions and narrow remote prototypes.

- **BS-JD-401 [P1] Static extension API v0** - Formalize a stable, statically linked extension API before attempting dynamic loading.
- **BS-JD-402 [P2] Extension and game prototype scaffolds** - Add editor actions to create new game prototype or editor extension crates from templates.
- **BS-JD-403 [P3] Optional dylib extension exploration** - Explore dynamic extension loading only after static extension API is stable.
- **BS-JD-404 [P2] BRP remote inspector write prototype** - Prototype editing one Transform over BRP against a running game/editor world.
- **BS-JD-405 [P3] Out-of-process game preview spike** - Investigate spawning the game as a separate process and syncing selected state back to the editor.

### M5: Regression, docs, and first-hour UX

Lock in quality: samples, tests, profiling, docs, and first-run guidance.

- **BS-JD-501 [P0] Editor sample scenes and regression pack** - Create curated sample scenes for brushes, materials, terrain, physics placement, and rendering.
- **BS-JD-502 [P0] Tool regression tests and undo invariants** - Add reusable tests for every modal tool and every editor operator.
- **BS-JD-503 [P2] Performance budgets and editor profiler panel** - Add performance budgets for expensive editor systems and a panel that surfaces hot operations.
- **BS-JD-504 [P0] Documentation and issue board structure** - Create docs pages and issue labels/milestones that match this roadmap.
- **BS-JD-505 [P1] First-hour usability polish pass** - Make the first hour in the editor feel guided: starter scene, tooltips, shortcut help, empty-state actions, and recovery messages.

## Cross-cutting polish checklist

| Checklist item | Required behavior |
|---|---|
| Tool preview | Ghost geometry, highlighted drop targets, brush rings, CSG previews, collider overlays, or material swatches before commit. |
| Commit/cancel | Space/Enter commits when appropriate; Esc/right-click cancels; cancel leaves no dirty state. |
| Undo grouping | Continuous drags, sculpt strokes, physics settle sessions, and asset drops create one meaningful undo entry. |
| Status and errors | Status bar names the active tool and next action. Failures explain cause and recovery. |
| Selection clarity | Generated/editor-only proxies resolve to source entities; active mode badge prevents confusion. |
| Performance | Large rebuilds are dirty-region based; thumbnails/assets are debounced; slow operations report diagnostics. |
| Save discipline | Generated meshes, colliders, handles, and helper entities never leak into saved scenes. |
| Docs and samples | Each feature ships with README controls, docs/editor page, and a sample scene or fixture. |

## Issue tickets

### BS-JD-000 - Adoption policy, license notes, and source attribution

**Milestone:** M0  
**Priority:** P0  
**Area:** Governance

**Summary:** Document which Jackdaw ideas are being adapted, which code may be referenced, and the license/attribution rules for any direct copying.

**Why this matters:** Blacksite should borrow design lessons without accidentally becoming an untracked fork. Jackdaw is MIT/Apache-2.0, but copied code still needs correct attribution and review.

**Implementation notes:**
- Create docs/adr/NNNN-jackdaw-inspired-editor-roadmap.md or docs/editor/jackdaw-roadmap.md.
- Add a short 'Inspired by' source note in docs/editor/README.md.
- If direct code is copied, preserve file-level license notes and commit with a source URL plus upstream commit hash.
- Prefer clean-room reimplementation for geometry, terrain, and operator APIs because Blacksite's authoring/hydration model differs from Jackdaw's JSN model.

**Acceptance criteria:**
- Repo has one canonical document explaining the adoption policy.
- Each future ticket references whether it is design-inspired, API-inspired, or code-derived.
- No copied code lands without license header and source commit note.

**Polish details:**
- Keep the document terse enough to be read before a PR.
- Add a PR checklist checkbox: 'If inspired by Jackdaw, source and license notes are included.'

**Tests:**
- N/A - documentation and review policy.

**Docs to update:**
- docs/editor/README.md
- root README if a visible workflow changes.

### BS-JD-001 - Project launcher and sandbox profiles

**Milestone:** M0  
**Priority:** P0  
**Area:** Project UX

**Summary:** Add an optional launcher/start screen for recent projects, new sandbox project, open project, and last scene resume.

**Why this matters:** Jackdaw starts with a project select screen. Blacksite currently behaves like an editor for one workspace; because this repo is an editor sandbox for a future game, project switching and sandbox creation should become first-class.

**Implementation notes:**
- Add an EditorStartupState or LauncherState before full editor mode. Keep the current direct-open behavior behind a CLI flag or saved preference.
- Extend ProjectWorkspace with project_id, last_opened_scene, and project_kind: Sandbox, GamePrototype, Imported.
- Add assets/project.ron fields for display_name, default_scene, project_template_version, and editor_capabilities.
- Implement UI under crates/editor/src/project/launcher.rs and register it before EditorUiPlugin shows the dock layout.
- Add File > Switch Project and File > Reveal Project Folder.

**Acceptance criteria:**
- First launch can create a new sandbox project with assets/, assets/levels/, assets/materials/, assets/models/, assets/textures/.
- Recent projects list filters missing folders and shows last opened scene.
- Existing Blacksite behavior still works when opening the default repo project.
- Window title and SceneIo active path update after switching.

**Polish details:**
- Use large cards: New Sandbox, Open Project, Recent Projects.
- Show validation badges for missing Cargo.toml, missing assets/project.ron, or missing default scene.
- Do not load the game/editor world until a project is selected, or clearly show a loading overlay if startup still preloads systems.

**Tests:**
- Unit test project manifest read/write defaults.
- Integration smoke: create temp project, open it, create scene, save, restart preference load.

**Docs to update:**
- README Running
- docs/editor/architecture.md project workspace section.

### BS-JD-002 - Scene document abstraction above DynamicScene RON

**Milestone:** M0  
**Priority:** P0  
**Area:** Scene I/O

**Summary:** Keep Blacksite's Bevy DynamicScene RON for now, but introduce a SceneDocument layer that tools edit instead of touching Bevy serialization directly.

**Why this matters:** Jackdaw's JSN docs emphasize line-diffable scene data and future BSN migration. Blacksite already has schema stamping and authoring-only validation; a document layer lets future tools, diffs, prefab overrides, and possible BSN migration avoid rewriting every tool.

**Implementation notes:**
- Create crates/scene/src/document.rs with SceneDocument, SceneEntity, SceneComponentBlob, and ScenePatch.
- SceneDocument initially round-trips to/from current DynamicScene RON, including schema header.
- Update SceneIo save/load path to: World -> SceneDocument -> DynamicScene RON text, and RON text -> SceneDocument -> World.
- Add patch operations: set_component, remove_component, add_entity, delete_entity, reparent, set_name, set_transform.
- Keep raw Bevy Entity IDs out of SceneDocument; use ActorId and ComponentInstanceId.

**Acceptance criteria:**
- Existing levels save byte-equivalent enough for current validator, or a documented one-time formatting migration occurs.
- All save validation still rejects hydrated runtime components.
- At least transform edit, rename, and component add/remove can be expressed as ScenePatch.

**Polish details:**
- Add a small debug panel showing the selected entity's document identity and dirty patches.
- Make scene diff output readable in logs for failed migrations.
- Do not expose SceneDocument to normal users yet; this is an internal seam.

**Tests:**
- Round-trip current assets/levels/editor_scene.scn.ron through SceneDocument.
- Golden tests for schema v1->v2 migration still pass.
- Patch tests verify stable ActorId and child order.

**Docs to update:**
- docs/editor/architecture.md scene authoring flow
- docs/adr if BSN direction is adopted.

### BS-JD-003 - Editor metadata for components

**Milestone:** M0  
**Priority:** P0  
**Area:** Inspector

**Summary:** Add explicit component metadata for category, description, hidden state, icon, dependencies, and authoring/runtime behavior.

**Why this matters:** Jackdaw uses editor metadata and registry filtering for custom components and picker UX. Blacksite already has a registry-driven Add Component footer, but metadata should become the single source for inspector/palette/hierarchy presentation.

**Implementation notes:**
- Extend ui/component_registry.rs or add shared::EditorComponentMeta.
- Fields: type_path, display_name, category, description, icon, default_factory, hidden, requires, conflicts_with, hydration_effect.
- Register metadata from shared authoring components at startup; allow game/editor extensions to register more.
- Use metadata in Inspector Add Component, component card header, command palette, and docs generation.
- Add 'why disabled' messages when required dependencies are missing or conflicts exist.

**Acceptance criteria:**
- Add Component palette groups components by Authoring, Rendering, Physics, Gameplay, Volumes, Experimental.
- Hidden/runtime-only components never appear in the add list.
- Selecting a component shows one-line docs and dependency/conflict hints.
- Adding ColliderDesc can optionally add RigidBodyDesc based on metadata requirements.

**Polish details:**
- Use icons and short descriptions; avoid raw Rust type paths in normal UI.
- Add search aliases like 'sun' -> LightDesc, 'spawn' -> PlayerSpawn.
- Show component active/inactive state consistently with existing InspectorOrder behavior.

**Tests:**
- Registry snapshot test ensures all shared authoring components have metadata.
- UI-independent tests for dependency/conflict logic.

**Docs to update:**
- docs/editor/README.md subsystem table
- README Inspector controls.

### BS-JD-004 - Unified operator/action framework

**Milestone:** M0  
**Priority:** P0  
**Area:** Undo/Redo

**Summary:** Unify command palette actions, history commands, asset drag/drop, and modal tools behind one operator interface with preview, commit, cancel, and undo.

**Why this matters:** Jackdaw routes editor actions such as ApplyTextureOp through an operator stack. Blacksite currently has EditorCommandRegistry and EditorHistory, but tools can be cleaner if every user action follows a standard lifecycle.

**Implementation notes:**
- Add crates/editor/src/action or crates/editor/src/tools/operator.rs.
- Define trait EditorOperator { id, label, can_start, begin, update, preview, commit, cancel, undo_label }.
- Bridge existing EditorHistory commands into operators: Spawn, Despawn, SetTransform, SetMaterial, AddComponent.
- Command palette invokes operators by ID, not ad hoc closures.
- Modal tools store active operator state in an ActiveOperator resource and show status bar help.

**Acceptance criteria:**
- Asset drag/drop, component add/remove, transform gizmo commit, and material apply all create consistent undo entries.
- Active operator can be canceled with Esc without dirtying the scene.
- Status bar shows the active tool, shortcut hints, and commit/cancel actions.

**Polish details:**
- Every operator has a user-facing label; undo menu says 'Undo Move Selection' not 'Undo command'.
- Operators can produce non-blocking warnings rendered in the viewport or status bar.
- Use grouping: drag strokes and gizmo drags produce one undo entry, not per-frame spam.

**Tests:**
- Operator lifecycle unit tests: begin -> preview -> cancel leaves world unchanged.
- Commit -> undo -> redo snapshot test for transform and material.

**Docs to update:**
- docs/editor/architecture.md Undo/history section.

### BS-JD-005 - Command palette polish and fuzzy matching

**Milestone:** M0  
**Priority:** P1  
**Area:** UI

**Summary:** Upgrade Ctrl+P into a fast launcher for commands, tools, panels, assets, and help.

**Why this matters:** Blacksite already has a command palette; Jackdaw has fuzzy picker infrastructure and many editor actions exposed through shortcuts and menus.

**Implementation notes:**
- Add fuzzy scoring module or small dependency-free scorer similar to jackdaw_fuzzy concept.
- Command entries include category, keywords, shortcut, disabled reason, and optional icon.
- Palette sources: EditorCommandRegistry, EditorOperator registry, panels, recent assets, recent scenes.
- Support prefix filters: > commands, @ assets, # panels, ? help.

**Acceptance criteria:**
- Ctrl+P opens focused input; Enter runs top match.
- Disabled commands show why they are disabled.
- Recently used commands float slightly higher.
- Help entries can open docs or the shortcuts window.

**Polish details:**
- Keyboard-only navigation with up/down/enter/escape.
- Highlight matched characters.
- Keep palette width stable and avoid reflow flicker as results update.

**Tests:**
- Fuzzy scorer deterministic tests.
- Command registry tests for duplicate IDs.

**Docs to update:**
- README controls
- docs/editor/README.md command palette.

### BS-JD-006 - Selection and editing shortcut polish

**Milestone:** M0  
**Priority:** P1  
**Area:** Viewport

**Summary:** Add box select, component copy/paste, visibility shortcut, reset transforms, and clearer selection state.

**Why this matters:** Jackdaw documents Shift+drag box select, Ctrl+C/Ctrl+V component copy/paste, H visibility toggle, and Alt+G/R/S transform resets. Blacksite has multi-select and selection cycling; this rounds out editor muscle memory.

**Implementation notes:**
- Add ViewportMarquee resource and draw overlay rectangle in viewport_chrome.rs.
- Use scene_view_ray to form a selection frustum for authored LevelObject bounds.
- Add InspectorClipboard support for selected component copies, building on existing inspector clipboard.
- Add shortcut handlers in ui/selection_ops.rs or new tools/selection_shortcuts.rs.
- Visibility shortcut writes EditorVisibility through history.

**Acceptance criteria:**
- Shift+LMB drag selects authored objects inside marquee.
- Ctrl+C copies selected component values; Ctrl+V pastes compatible components to selected entity/entities.
- H toggles editor visibility through undoable command.
- Alt+G/Alt+R/Alt+S reset position/rotation/scale with undo.

**Polish details:**
- Marquee draws even over dark scenes and shows selection count before release.
- Clipboard paste shows '3 components pasted to 4 actors' status.
- Conflicting component paste warns instead of silently doing nothing.

**Tests:**
- Selection frustum math tests using sample bounds.
- Clipboard round-trip for MaterialDesc, LightDesc, ColliderDesc.

**Docs to update:**
- README Editor Controls.

### BS-JD-007 - Viewport productivity controls

**Milestone:** M0  
**Priority:** P1  
**Area:** Viewport

**Summary:** Expand camera bookmarks, grid controls, speed controls, nudge keys, and transform constraints.

**Why this matters:** Blacksite has focus, grid, clean view, and two camera bookmark shortcuts. Jackdaw exposes 1-9 bookmarks, RMB+scroll speed, grid step changes, arrow nudge, and axis constraints.

**Implementation notes:**
- Extend CameraBookmarks to map scene_key + slot 1..9 -> Transform.
- Ctrl+1..9 saves, 1..9 restores when viewport focused and no text input is active.
- RMB+scroll adjusts EditorCamera.fly_speed and persists to user prefs as optional override.
- Add grid size up/down controls with [ and ], tied to ViewportSettings.snap_increment.
- Add nudge operators for selected transforms: Arrow keys, PageUp/PageDown, Alt+Arrows rotate 90 degrees.
- During transform gizmo drag, Ctrl toggles snap and X/Y/Z constrains axis if supported by transform-gizmo-bevy; otherwise add manual nudge constraints first.

**Acceptance criteria:**
- Nine camera bookmarks work per scene.
- Grid size visible in viewport status HUD.
- Nudge movement uses current snap increment and creates one undo entry per keypress.
- RMB+scroll speed changes are visible in status bar.

**Polish details:**
- Small bottom-right HUD: Grid 1.0m | Snap On | Speed 14.
- Do not steal number keys when renaming or typing in inspector fields.
- Add reset speed button in shortcuts/help overlay.

**Tests:**
- Bookmark save/restore tests.
- Nudge transform history test.

**Docs to update:**
- README Editor Controls
- docs/editor/README.md viewport.

### BS-JD-101 - Brush authoring schema and hydration MVP

**Milestone:** M1  
**Priority:** P0  
**Area:** Brushes

**Summary:** Add a convex brush authoring component that serializes as planes/faces and hydrates into generated mesh/collider children.

**Why this matters:** Jackdaw's strongest worldbuilding feature is brush-based geometry similar to TrenchBroom/Hammer. For a sandbox with no game yet, this gives fast blockout without external DCC tools.

**Implementation notes:**
- Add shared::BrushDesc with faces: Vec<BrushFaceDesc>; each face stores plane, material_ref, uv_offset, uv_scale, uv_rotation, smoothing_group.
- Add shared::BrushKind: Additive, SubtractiveMarker (subtractive can be inactive until CSG ticket).
- Create new crate crates/geometry or module shared::brush_math for convex validation, face polygon reconstruction, triangulation, normal generation.
- Hydration spawns EditorOnly generated mesh children or uses hydrated components on the brush entity, but save strips all generated mesh/collider runtime data.
- Add ActorKind::Brush or treat as StaticMesh with BrushDesc; prefer ActorKind::Brush for validation clarity.
- Register BrushDesc reflection and scene allowlist in SceneIo.

**Acceptance criteria:**
- Add cube brush creates an authored LevelObject with BrushDesc and visible mesh.
- Save/load round-trips brush data without serializing generated Mesh3d/MeshMaterial3d.
- Invalid brush data displays a warning marker and does not panic.
- Brush can generate a static collider when ColliderDesc is enabled.

**Polish details:**
- Generated face children must be hidden from hierarchy and scene save.
- Selection should resolve generated face clicks back to the brush until face-edit mode exists.
- Show brush wireframe and face normals when selected.

**Tests:**
- Geometry tests: cube face reconstruction, triangulation, normals.
- Scene save test: no hydrated brush mesh markers in .scn.ron.
- Load invalid face data should log warning not panic.

**Docs to update:**
- docs/editor/brushes.md new page
- docs/editor/README.md index.

### BS-JD-102 - Quick add and draw-brush tool

**Milestone:** M1  
**Priority:** P0  
**Area:** Brushes

**Summary:** Add brush creation via menu/context actions and a modal draw tool that places vertices on a face or floor, then extrudes to a convex brush.

**Why this matters:** Jackdaw's B/C draw workflow is a fast path for blockout. Blacksite already supports asset placement by viewport rays; reuse that for brush drawing.

**Implementation notes:**
- Add BrushToolState: Idle, DrawingPolygon, Extruding, Preview.
- LMB places vertices on plane selected by raycast: closest brush/static mesh face under cursor or y=0 floor.
- Enter closes polygon and creates extrusion preview; drag or default height sets depth.
- Esc/right-click cancels; Backspace removes last vertex; Tab toggles additive/subtractive mode if subtractive is implemented later.
- Create brush snapshot through EditorHistory/operator framework.
- Add toolbar button and B shortcut; C can create subtractive brush marker after CSG support.

**Acceptance criteria:**
- B enters draw-brush mode and status bar shows next action.
- Click-click-click-Enter creates a visible brush from a floor polygon.
- Cancel leaves no entity and no dirty scene state.
- Undo removes the created brush.

**Polish details:**
- Draw preview uses ghost lines and filled translucent polygon.
- Invalid polygon self-intersection is detected before commit.
- Plane snap and grid snap are visible and consistent with ViewportSettings.

**Tests:**
- Polygon validation unit tests.
- Operator cancel/commit history tests.

**Docs to update:**
- README shortcuts
- docs/editor/brushes.md.

### BS-JD-103 - Brush element edit modes

**Milestone:** M1  
**Priority:** P0  
**Area:** Brushes

**Summary:** Add vertex, edge, face, and clip edit modes for selected brushes.

**Why this matters:** Jackdaw exposes 1-4 brush edit modes. This turns brushes from primitives into real level geometry tools.

**Implementation notes:**
- Add BrushEditMode resource: Object, Vertex, Edge, Face, Clip.
- Create selectable handles/proxies for vertices, edges, and faces; resolve picks to brush + element ID.
- Dragging a vertex/edge/face edits BrushDesc, validates convexity, rebuilds mesh preview, and commits one undo entry when drag ends.
- Clip mode stores a preview plane; Enter applies split into one or two BrushDesc entities.
- Disable normal object transform gizmo or scope it to selected elements while in brush mode.

**Acceptance criteria:**
- 1/2/3/4 enter vertex/edge/face/clip modes when a brush is selected.
- Element highlighting and selection work with Shift+Click multi-select.
- Element edits preserve valid convex brush geometry or reject with visible reason.
- Esc returns to object mode.

**Polish details:**
- Viewport badge: Brush: Face Mode.
- Selected elements use high-contrast colors distinct from entity selection.
- Inspector shows selected face material/UV controls in face mode.

**Tests:**
- Convexity validation tests for vertex moves.
- Undo/redo tests for vertex and face drag.
- Selection proxy save filter tests.

**Docs to update:**
- docs/editor/brushes.md edit mode section.

### BS-JD-104 - Brush CSG operations

**Milestone:** M1  
**Priority:** P1  
**Area:** Brushes

**Summary:** Implement subtract, intersect, and convex merge for selected brushes.

**Why this matters:** Jackdaw has CSG Subtract, CSG Intersect, and Join/Convex Merge. For Blacksite, this is the difference between block placement and useful greybox geometry.

**Implementation notes:**
- Use a geometry crate boundary from BS-JD-101 so CSG can be tested independently.
- Inputs: selected BrushDesc entities ordered by selection time; first entity is minuend for subtract.
- Outputs: replace inputs with new BrushDesc snapshots, preserving names where possible and pushing one history command.
- Reject degenerate zero-volume results with a status warning and no scene mutation.
- Add menu entries under Edit > Brush and command palette IDs brush.subtract, brush.intersect, brush.merge_convex.

**Acceptance criteria:**
- Subtract cuts one brush volume from another.
- Intersect keeps overlapping volume.
- Convex merge succeeds only when result is convex and rejects otherwise.
- Undo restores original brushes and selection.

**Polish details:**
- Before commit, show preview of output faces.
- CSG failure messages are specific: no overlap, non-convex merge, degenerate face.
- Retain material assignment on surviving faces where face plane/material can be matched.

**Tests:**
- Golden geometry cases: cube subtract cube, cube intersect cube, non-overlap, non-convex merge.
- Scene save after CSG authoring-only check.

**Docs to update:**
- docs/editor/brushes.md boolean operations.

### BS-JD-105 - Per-face material and UV controls

**Milestone:** M1  
**Priority:** P1  
**Area:** Materials

**Summary:** Allow brush faces to reference textures/materials and edit UV offset, scale, and rotation.

**Why this matters:** Jackdaw stores material and UV data per brush face. Blacksite already has material assets and material overrides; brush faces need a parallel authoring path.

**Implementation notes:**
- Extend BrushFaceDesc with material: Option<EditorAssetRef>, texture: Option<EditorAssetRef>, uv_offset: Vec2, uv_scale: Vec2, uv_rotation: f32.
- Face inspector appears when BrushEditMode::Face has one or more selected faces.
- Drag texture/material from asset browser onto face proxy to set face material via an operator.
- Hydration builds per-face mesh sections or material slots; keep static mesh renderer path separate from brush renderer path initially.

**Acceptance criteria:**
- Selecting a face shows material and UV controls.
- Dragging a texture or material onto a face applies it with undo.
- Save/load preserves per-face material and UV data.
- Missing material displays fallback checker and warning.

**Polish details:**
- Add Align, Fit, Rotate 90, Flip U, Flip V buttons.
- Show material swatch and asset path with Locate/Clear actions.
- Face material drop target highlights only the face under cursor.

**Tests:**
- UV transform math tests.
- Material ref round-trip tests.
- Undo/redo material apply to multiple faces.

**Docs to update:**
- docs/editor/materials.md
- docs/editor/brushes.md face materials.

### BS-JD-106 - Brush validation, repair, and diagnostics

**Milestone:** M1  
**Priority:** P2  
**Area:** Brushes

**Summary:** Add robust error handling for degenerate brushes, inverted normals, zero-area faces, and non-manifold results.

**Why this matters:** CSG and direct vertex editing create edge cases. Good diagnostics prevent the editor sandbox from feeling brittle.

**Implementation notes:**
- Add BrushValidationReport with warnings/errors and suggested repair actions.
- Run validation after edits, after load, and before save.
- Repair actions: flip normals, remove zero-area faces, weld close vertices, recenter origin.
- Expose Window > Brush Diagnostics and per-actor warning icon.

**Acceptance criteria:**
- Invalid brush cannot crash hydration or save.
- Diagnostics panel lists brush entity, issue, severity, and fix action.
- Repair actions are undoable.

**Polish details:**
- Viewport warning icon at brush origin.
- Error messages use level-designer language, not geometry jargon.
- Add 'copy diagnostics' for bug reports.

**Tests:**
- Invalid brush fixtures.
- Repair action snapshot tests.

**Docs to update:**
- docs/editor/brushes.md common gotchas.

### BS-JD-201 - Material Browser and shared material catalog

**Milestone:** M2  
**Priority:** P0  
**Area:** Materials

**Summary:** Create a dedicated Material Browser panel for named PBR materials, scene-local materials, and project-wide material assets.

**Why this matters:** Jackdaw separates the Asset Browser from a Material Browser with named material definitions. Blacksite already scans assets/materials/*.ron and has shader-aware MaterialAsset, but a focused material workflow will make the sandbox much more useful.

**Implementation notes:**
- Add crates/editor/src/ui/material_browser/ with grid/list/detail views.
- Read/write MaterialAsset RON under assets/materials/.
- Define material refs: scene-local (#Name) and project-wide (@Name) or use existing EditorAssetRef consistently.
- Add Create Material, Duplicate, Rename, Delete, Locate Usages.
- Preview material on sphere using existing thumbnail/offscreen infrastructure or new material preview target.

**Acceptance criteria:**
- Window > Material Browser opens a panel with all project materials.
- User can create a material, assign base color/metallic/roughness/texture, save to RON, and drag it onto a selected actor or brush face.
- Material usage list shows actors/faces using a material.
- Missing material refs show warnings but scenes still load.

**Polish details:**
- Live preview sphere updates as sliders move.
- Dirty indicator on unsaved material edits.
- Clear distinction between shared material asset edits and per-actor overrides.

**Tests:**
- MaterialAsset read/write round-trip.
- Preview cache invalidation on material edit.
- Assign material with undo to actor and brush face.

**Docs to update:**
- docs/editor/materials.md new page
- README Scene Workflow.

### BS-JD-202 - PBR texture-set auto-detection

**Milestone:** M2  
**Priority:** P1  
**Area:** Materials

**Summary:** Detect texture sets from filenames and generate draft materials automatically.

**Why this matters:** Jackdaw groups albedo/normal/roughness/metallic/AO/height textures by common suffixes. This makes material authoring fast when importing texture packs.

**Implementation notes:**
- Add pbr_filename_regex-like matcher in assets/materials.rs or material_browser/import.rs.
- Recognize suffixes: albedo, basecolor, diffuse, normal, n, roughness, r, metallic, m, ao, orm, height, displacement.
- Group files by stem base and propose MaterialAsset drafts.
- ORM auto-detection: if texture name contains orm or occlusion_roughness_metallic, map channels R=AO, G=roughness, B=metallic.
- Add 'Create materials from folder' action in Asset Browser and Material Browser.

**Acceptance criteria:**
- Dropping a PBR texture folder under assets/textures lets user generate one or more MaterialAsset files.
- Generated material has correct texture bindings and editable values.
- User can split/merge mistakenly grouped textures before saving.

**Polish details:**
- Preview detected groups before commit.
- Show confidence labels and unresolved files.
- Never overwrite existing material without confirmation.

**Tests:**
- Filename grouping fixtures.
- ORM channel mapping metadata tests.

**Docs to update:**
- docs/editor/materials.md auto-detection section.

### BS-JD-203 - Drag/drop material and texture application

**Milestone:** M2  
**Priority:** P0  
**Area:** Assets

**Summary:** Make texture/material drag/drop work consistently for static mesh actors, primitive actors, and brush faces.

**Why this matters:** Jackdaw's asset browser can drag an image onto a brush face and route through undo. Blacksite has asset drag placement and texture assignment; unify this under operator semantics.

**Implementation notes:**
- Detect drop target: selected actor, actor under viewport cursor, brush face proxy, static mesh slot.
- If image dropped onto material slot, create or update MaterialOverride base color texture.
- If material dropped, assign material ref to appropriate slot/face.
- If no valid target, show ghost invalid drop cursor and status message.
- All changes use EditorOperator and EditorHistory.

**Acceptance criteria:**
- Drag texture from Asset Browser onto selected primitive changes its visible material.
- Drag material onto static mesh slot sets override or ref.
- Drag material onto brush face sets face material.
- Undo restores previous material state.

**Polish details:**
- Target under cursor highlights before release.
- Drop popup if target has multiple slots: choose slot or apply to all.
- Status message includes material name and target actor.

**Tests:**
- Drop target resolution tests.
- Undo tests for primitive, static mesh, brush face.

**Docs to update:**
- README Asset Browser controls.

### BS-JD-204 - Live asset watcher and refresh

**Milestone:** M2  
**Priority:** P1  
**Area:** Assets

**Summary:** Watch assets/ and refresh asset catalog, thumbnails, and material registry without manual refresh.

**Why this matters:** Jackdaw templates rely on Bevy's file watcher so dropped files appear automatically. Blacksite scans assets and refreshes on settings changes or import; live watching improves iteration.

**Implementation notes:**
- Add notify watcher to EditorAssetsPlugin or rely on Bevy AssetServer watcher if configured; notify is already optional for hot reload, but this should be editor feature-gated or always available.
- Debounce file events and refresh only affected folders where possible.
- Invalidate thumbnail cache for changed paths.
- Refresh material browser groups on texture/material changes.
- Status bar shows 'Assets refreshed: N changed'.

**Acceptance criteria:**
- Copying a PNG into assets/textures appears in Asset Browser without restart.
- Editing a MaterialAsset RON refreshes Material Browser and assigned material preview.
- Deleting an asset marks stale references with warnings.

**Polish details:**
- Avoid UI stalls on large folder changes with debounce and incremental refresh.
- Show spinner or small activity icon during refresh.
- Recover gracefully from partial files being copied.

**Tests:**
- Unit tests for debouncer.
- Manual smoke script with temp asset dir.

**Docs to update:**
- docs/editor/assets.md.

### BS-JD-205 - Asset rename/move reference repair

**Milestone:** M2  
**Priority:** P1  
**Area:** Assets

**Summary:** Track asset moves/renames and repair scene/material/prefab references.

**Why this matters:** General editors need robust asset references. Jackdaw has project-wide catalog concepts; Blacksite already has stable UUIDs in AssetRegistry, so this is a natural improvement.

**Implementation notes:**
- Treat AssetId as source of truth and path as mutable metadata.
- On file watcher rename or Asset Browser rename, update AssetRecord.path and all EditorAssetRef paths where asset_id matches.
- Add a missing-reference resolver dialog for files changed outside the editor.
- Add Asset Browser actions: Rename, Move, Duplicate, Delete with reference impact preview.

**Acceptance criteria:**
- Renaming a material or model inside editor updates scene refs and registry.
- Opening a scene with missing path but matching AssetId repairs path if registry knows it.
- Deleting an asset warns about usages before commit.

**Polish details:**
- Reference impact dialog lists affected scenes/entities/material slots.
- Offer 'Keep broken reference' for deliberate missing assets.
- Add undo for in-editor rename/move where practical.

**Tests:**
- Registry path update tests.
- Scene ref repair tests with missing asset path.

**Docs to update:**
- docs/editor/assets.md reference model.

### BS-JD-206 - Headless asset processing command

**Milestone:** M2  
**Priority:** P2  
**Area:** Pipeline

**Summary:** Add xtask/cargo-style command to process assets without opening the editor UI.

**Why this matters:** Jackdaw calls out asset processing as an open challenge. Blacksite already has xtask and generated static mesh artifacts; processing outside the UI will help CI and future builds.

**Implementation notes:**
- Add xtask process-assets with options: --check, --write, --changed-only, --project assets/project.ron.
- Move static mesh artifact refresh logic into a reusable library function not tied to UI resources.
- Process material auto-detection, static mesh manifests, thumbnail metadata, and registry consistency checks.
- CI can run xtask process-assets --check to fail stale generated artifacts.

**Acceptance criteria:**
- Running cargo run -p xtask -- process-assets --check reports stale/missing generated mesh manifests.
- Running --write updates assets/.index/registry.ron and generated manifests.
- No Bevy window or egui initialization is required.

**Polish details:**
- Output concise summaries and actionable errors.
- Use stable ordering for deterministic generated files.
- Add --json for future automation.

**Tests:**
- Temp project fixture process-assets test.
- Golden generated manifest comparison.

**Docs to update:**
- README Target/Asset tasks
- docs/editor/assets.md.

### BS-JD-301 - Terrain authoring schema and chunked mesh hydration

**Milestone:** M3  
**Priority:** P1  
**Area:** Terrain

**Summary:** Add a heightmap-backed TerrainDesc authoring component with chunked generated meshes.

**Why this matters:** Jackdaw terrain supports heightmap sculpting with chunks. Blacksite currently has strong static mesh/primitive workflows but no native terrain authoring.

**Implementation notes:**
- Add shared::TerrainDesc: resolution, size, height_scale, heights storage reference, material/layer refs.
- Store height data either inline for small terrains or as assets/terrain/*.terrain.ron/bin for larger maps.
- Add crates/terrain or shared::terrain_math with chunk mesh generation and normal computation.
- Hydration spawns EditorOnly mesh chunk children and optional collider chunks.
- Chunk size starts at 32 cells, configurable later.

**Acceptance criteria:**
- Add > Terrain creates flat terrain visible in viewport.
- Terrain saves/loads without generated chunk meshes in scene.
- Changing size/resolution rebuilds chunks and preserves existing heights where possible.
- Terrain can generate static collision.

**Polish details:**
- Inspector warns before destructive resolution changes.
- Viewport shows chunk boundaries when selected.
- Initial terrain appears centered under camera/selection, not at an unexpected origin.

**Tests:**
- Heightmap mesh generation tests.
- Chunk dirty-region tests.
- Save filter tests for generated chunks.

**Docs to update:**
- docs/editor/terrain.md new page.

### BS-JD-302 - Terrain sculpt tools with stroke undo

**Milestone:** M3  
**Priority:** P1  
**Area:** Terrain

**Summary:** Implement raise/lower, flatten, smooth, and noise sculpt brushes with one undo entry per stroke.

**Why this matters:** Jackdaw's terrain tools emphasize brush radius, strength, preview ring, and stroke-based undo. This is the minimum useful terrain workflow.

**Implementation notes:**
- Add TerrainToolState with active terrain, brush mode, radius, strength, falloff.
- Viewport ray picks terrain surface and shows brush ring projected onto terrain.
- During drag, apply brush to height samples, mark affected chunks dirty, and rebuild only overlapping chunks.
- Store pre-stroke height patch and post-stroke patch for undo/redo.
- Add toolbar controls and shortcuts.

**Acceptance criteria:**
- Raise/lower, flatten, smooth, and noise tools work on selected terrain.
- Each drag stroke is one undo entry.
- Affected chunks update without rebuilding the whole terrain.
- Brush preview ring tracks cursor and radius.

**Polish details:**
- Tablet-like controls are not required, but sliders should feel responsive.
- Status HUD shows tool, radius, strength, falloff.
- Show a warning for very high resolution terrains if stroke cost is high.

**Tests:**
- Brush application math tests.
- Undo patch tests.
- Dirty chunk overlap tests.

**Docs to update:**
- docs/editor/terrain.md sculpt section.

### BS-JD-303 - Terrain material layers and texture painting MVP

**Milestone:** M3  
**Priority:** P2  
**Area:** Terrain

**Summary:** Add terrain material layers with simple weight painting.

**Why this matters:** Jackdaw docs note texture painting as roadmap/not built. Blacksite can start with a pragmatic MVP after terrain sculpting lands.

**Implementation notes:**
- TerrainDesc stores layers: material ref + weightmap channel/index.
- Weight data can be stored as small RON for MVP, binary later.
- Painting tool adjusts selected layer weight with radius/strength and normalizes weights.
- Shader path: simple splat map material or generate mesh vertex colors as interim visualization.
- Provide fallback single material for runtime if layer shader is not ready.

**Acceptance criteria:**
- User can add at least four terrain material layers.
- Paint tool visibly blends layer preview in editor.
- Save/load preserves layer weights.
- Runtime fallback is documented.

**Polish details:**
- Layer list supports reorder, rename, clear layer, fill layer.
- Brush preview uses selected material swatch.
- Warn if renderer fallback cannot show all layers.

**Tests:**
- Weight normalization tests.
- Layer serialization tests.

**Docs to update:**
- docs/editor/terrain.md material layers.

### BS-JD-304 - Physics placement tool

**Milestone:** M3  
**Priority:** P1  
**Area:** Physics

**Summary:** Let users select props, release them into simulated gravity, then commit or cancel settled transforms.

**Why this matters:** Jackdaw's Physics Tool is a practical level-design feature: drop dynamic props into place instead of hand-positioning them.

**Implementation notes:**
- Add PhysicsPlacementState: Idle, Holding, Simulating, Settled.
- Shortcut Shift+P enters tool if selected entities have RigidBodyDesc/ColliderDesc.
- Temporarily enable sim for selected entities only; freeze or disable non-selected dynamic bodies while retaining static colliders.
- On Space commit, capture final transforms and write SetTransformGroup history command.
- On Esc cancel, restore pre-tool transforms and simulation state.
- Use Avian components through hydration; do not persist runtime physics state.

**Acceptance criteria:**
- Selected dynamic props can be dropped onto static colliders and settle.
- Space commits final transforms; Esc restores original transforms.
- Undo after commit restores original transforms.
- Non-selected dynamic props are not disturbed.

**Polish details:**
- Status bar: Physics Tool | drag selected to release | Space commit | Esc cancel.
- Selected bodies show orange collider overlay; static obstacles green.
- If selection lacks colliders, offer Add Collider action.

**Tests:**
- State machine unit tests.
- Transform commit/cancel history tests.
- Manual scene fixture for physics placement.

**Docs to update:**
- docs/editor/physics.md new page
- README controls.

### BS-JD-305 - Collider authoring diagnostics and overlays

**Milestone:** M3  
**Priority:** P1  
**Area:** Physics

**Summary:** Improve collider visualization, shape switching, and error reporting.

**Why this matters:** Blacksite already has collider descriptors and visualizers. Jackdaw's physics docs emphasize green/orange/cyan overlays, collider shape selection, and common gotchas.

**Implementation notes:**
- Extend visualizers.rs to color colliders by body/sensor/selection state.
- Inspector card for ColliderDesc shows shape dropdown, dimensions, mesh source, cooking options, and warnings.
- Add validation: dynamic trimesh warning, missing mesh source, invalid scale, zero extents.
- Add 'Fit Collider To Mesh Bounds' and 'Copy Collider From Renderer' actions.

**Acceptance criteria:**
- Collider overlays communicate selected/static/dynamic/sensor states.
- Invalid collider choices display warnings before hydration fails.
- Fit-to-bounds creates undoable collider changes.

**Polish details:**
- Overlay opacity controlled from viewport options.
- Warnings use actionable language.
- Collider card shows estimated complexity for mesh collider.

**Tests:**
- Collider validation tests.
- Fit-to-bounds math tests.

**Docs to update:**
- docs/editor/physics.md collider section.

### BS-JD-401 - Static extension API v0

**Milestone:** M4  
**Priority:** P1  
**Area:** Extensibility

**Summary:** Formalize a stable, statically linked extension API before attempting dynamic loading.

**Why this matters:** Jackdaw has a larger extension/dylib ecosystem, but its docs also call out dylib challenges. Blacksite already has EditorPlugin, ActorInspectorSection, and command registry. Stabilize that first.

**Implementation notes:**
- Create editor::api module that re-exports only stable extension traits: EditorPlugin, EditorCommand, ActorInspectorSection, EditorComponentMeta registration, panel registration.
- Add PanelRegistration: id, title, icon, default_dock, ui callback.
- Add menu registration and command registration under one extension context.
- Move internal resources out of the public API or mark as unstable.
- Dogfood with game::editor_ext and a sample plugin crate inside examples/ or crates/editor_example_ext.

**Acceptance criteria:**
- A separate in-workspace crate can add a panel, command, component metadata, and inspector section without editing ui/mod.rs.
- API docs clearly mark stable vs internal.
- Existing game demo panel uses the API.

**Polish details:**
- Extensions should not need to know dock internals for simple panels.
- Extension errors should surface in Diagnostics panel.
- API names should be generic for future games, not FPS-specific.

**Tests:**
- Compile-check sample extension crate.
- Registry duplicate ID tests.

**Docs to update:**
- docs/editor/extensibility.md new page.

### BS-JD-402 - Extension and game prototype scaffolds

**Milestone:** M4  
**Priority:** P2  
**Area:** Extensibility

**Summary:** Add editor actions to create new game prototype or editor extension crates from templates.

**Why this matters:** Jackdaw can scaffold new games/extensions from its launcher. Since Blacksite is a sandbox for a future Bevy game, scaffolding will help transition from editor sandbox to real project.

**Implementation notes:**
- Add templates/blacksite_game and templates/blacksite_editor_extension.
- Launcher buttons: New Game Prototype, New Editor Extension.
- Template creates Cargo.toml, src/lib.rs, src/bin/editor.rs or extension lib, assets/project.ron.
- For now use static linking path; generated editor binary adds editor::EditorPluginGroup and user's game plugin.
- Optional: xtask new-game and xtask new-extension for non-UI flow.

**Acceptance criteria:**
- User can create a new prototype project from launcher and open it.
- Generated project builds with cargo check.
- Generated extension crate registers a sample panel.

**Polish details:**
- Show template version and upgrade note.
- Validate crate name and destination before creating files.
- After scaffold, offer 'Open in editor' and 'Open folder'.

**Tests:**
- Template generation tests in temp directory.
- cargo check generated minimal project in CI if feasible.

**Docs to update:**
- README Getting started
- docs/editor/extensibility.md.

### BS-JD-403 - Optional dylib extension exploration

**Milestone:** M4  
**Priority:** P3  
**Area:** Extensibility

**Summary:** Explore dynamic extension loading only after static extension API is stable.

**Why this matters:** Jackdaw supports dylib extensions but documents Windows limitations. Blacksite should not make dynamic loading a foundation until the simpler static model works.

**Implementation notes:**
- Write ADR comparing static plugins, hot game dylib, BRP/out-of-process tools, and dylib extension loading.
- Prototype Linux/macOS-only dylib loading with one tiny extension that registers a command.
- Reuse hot_reload concepts only if Bevy type identity is safe.
- Explicitly defer Windows support unless a clean ABI/type-sharing plan exists.
- Do not expose to normal users until unload/reload failure modes are understood.

**Acceptance criteria:**
- ADR states whether to pursue, defer, or reject dynamic extension loading.
- Prototype can be enabled behind experimental feature and is off by default.
- Failure to load extension does not corrupt project state.

**Polish details:**
- Experimental UI clearly labels risk.
- Loaded extension list shows path, status, error message, and reload button.

**Tests:**
- Feature-gated smoke test on supported OS only.
- Error-path tests for missing symbols if practical.

**Docs to update:**
- ADR
- docs/editor/extensibility.md experimental section.

### BS-JD-404 - BRP remote inspector write prototype

**Milestone:** M4  
**Priority:** P2  
**Area:** Remote/PIE

**Summary:** Prototype editing one Transform over BRP against a running game/editor world.

**Why this matters:** Jackdaw identifies remote inspector round-trip editing as an open PIE maturity gap. Blacksite already enables BRP in the editor; a narrow write path will clarify whether future game preview should be in-process or out-of-process.

**Implementation notes:**
- Add editor command brp.transform.set for selected entity or ActorId.
- Wire a small BRP client panel to connect to localhost editor/game endpoint.
- Start with Transform only, using ActorId mapping rather than raw Entity when possible.
- Round-trip: fetch entity list, display selected transform, edit value, send patch, verify update.

**Acceptance criteria:**
- Remote inspector can read and write Transform for a test entity.
- Errors are shown for stale entity IDs.
- The prototype is clearly marked experimental and does not replace in-process inspector.

**Polish details:**
- Show connection status, endpoint, latency/polling interval.
- Add 'copy BRP request' for debugging.
- Use value diff highlighting after write.

**Tests:**
- Mock command serialization tests.
- Manual two-process smoke instructions.

**Docs to update:**
- docs/editor/brp.md.

### BS-JD-405 - Out-of-process game preview spike

**Milestone:** M4  
**Priority:** P3  
**Area:** PIE

**Summary:** Investigate spawning the game as a separate process and syncing selected state back to the editor.

**Why this matters:** Blacksite currently has in-process PIE. Jackdaw's open challenges note the tradeoff: in-process is cheap but a game panic can take down the editor; out-of-process is safer but needs protocol work.

**Implementation notes:**
- Create a spike branch only. Do not merge half-finished protocol into main editor flow.
- Spawn game binary with --editor-remote and project path.
- Use BRP or a small protocol to request entity list, selected transform, play/stop state.
- Document latency, crash isolation, asset reload behavior, and complexity.
- Decide whether Blacksite needs this before a real game exists.

**Acceptance criteria:**
- Spike report with recommendation: keep in-process, adopt out-of-process later, or hybrid.
- If prototype exists, it can launch a game process and read a scene entity list.

**Polish details:**
- User-facing UI is not required for spike beyond diagnostics.
- Capture logs from child process in a panel if implemented.

**Tests:**
- N/A for spike; document manual reproduction.

**Docs to update:**
- ADR if decision affects architecture.

### BS-JD-501 - Editor sample scenes and regression pack

**Milestone:** M5  
**Priority:** P0  
**Area:** QA

**Summary:** Create curated sample scenes for brushes, materials, terrain, physics placement, and rendering.

**Why this matters:** Feature work becomes hard to evaluate without stable scenes. Blacksite already has showcase levels; expand this into a deliberate regression/demo pack.

**Implementation notes:**
- Create assets/levels/samples/brush_blockout.scn.ron, material_lab.scn.ron, terrain_sculpt.scn.ron, physics_drop.scn.ron.
- Add small source assets under assets/samples/ with license-safe primitives/textures.
- Add xtask validate-samples that loads scenes, validates authoring-only save, and checks missing asset refs.
- Add README section listing what each sample tests.

**Acceptance criteria:**
- Each major editor feature has a sample scene.
- CI validates sample scenes are authoring-only and references resolve.
- New contributors can open samples from File > Open Sample.

**Polish details:**
- Samples should be visually clear, not just technical fixtures.
- Add explanatory text objects or notes if supported; otherwise include docs screenshots later.

**Tests:**
- CI validate-levels includes samples.
- Asset ref resolver test over samples.

**Docs to update:**
- README sample scenes
- docs/editor/README.md.

### BS-JD-502 - Tool regression tests and undo invariants

**Milestone:** M5  
**Priority:** P0  
**Area:** QA

**Summary:** Add reusable tests for every modal tool and every editor operator.

**Why this matters:** Brushes, terrain, materials, and physics tools are stateful. Without undo/redo/cancel invariants, editor regressions will feel random.

**Implementation notes:**
- Create editor test helpers for spawning a minimal App with SharedTypesPlugin, EditorHistoryPlugin, and tool resources.
- Define invariant helpers: cancel_no_change, commit_marks_dirty, undo_restores_snapshot, redo_restores_commit, save_authoring_only.
- Apply to new operators as they land.

**Acceptance criteria:**
- Every new ticket that mutates scene data adds at least one operator invariant test.
- Tests run in cargo test -p editor or relevant crate without opening a window.
- A failing test includes operator ID and scenario.

**Polish details:**
- Keep tests fast; geometry-heavy tests use small fixtures.
- Add comments explaining why each invariant matters for editor UX.

**Tests:**
- This ticket creates the test harness.

**Docs to update:**
- docs/editor/debt-audit.md.

### BS-JD-503 - Performance budgets and editor profiler panel

**Milestone:** M5  
**Priority:** P2  
**Area:** Diagnostics

**Summary:** Add performance budgets for expensive editor systems and a panel that surfaces hot operations.

**Why this matters:** Brush mesh rebuilds, terrain chunk rebuilds, thumbnails, and asset scans can stall the editor. Blacksite already has diagnostics; extend it with editor-specific budgets.

**Implementation notes:**
- Instrument asset refresh, thumbnail generation, brush rebuild, terrain sculpt, scene save/load, and render target resize.
- Add EditorPerfStats resource with rolling timings and counts.
- Diagnostics panel shows slowest recent editor operations.
- Add optional log warnings when operation exceeds budget.

**Acceptance criteria:**
- Window > Diagnostics shows editor operation timings.
- Terrain/brush rebuilds report dirty chunks/faces count.
- Asset refresh reports changed files and elapsed time.

**Polish details:**
- Use simple green/yellow/red indicators.
- Do not spam logs during continuous sculpt/drag; aggregate per stroke.
- Add 'copy perf snapshot' for bug reports.

**Tests:**
- Stats aggregation unit tests.
- No strict timing tests in CI.

**Docs to update:**
- docs/editor/architecture.md diagnostics.

### BS-JD-504 - Documentation and issue board structure

**Milestone:** M5  
**Priority:** P0  
**Area:** Docs

**Summary:** Create docs pages and issue labels/milestones that match this roadmap.

**Why this matters:** Blacksite's AGENTS.md treats stale docs as bugs. This roadmap will only help if tickets, labels, and docs stay synchronized.

**Implementation notes:**
- Add docs/editor/jackdaw-inspired-roadmap.md based on this document.
- Add docs/editor/brushes.md, materials.md, terrain.md, physics.md as features land.
- Create labels: area/brushes, area/materials, area/terrain, area/physics, area/extensibility, priority/P0-P3, milestone/M0-M5, polish, tests.
- Create issue template with fields from this document.

**Acceptance criteria:**
- Every roadmap ticket has a matching issue or is explicitly deferred.
- Docs index links all new pages.
- Root README controls updated when shortcuts ship.

**Polish details:**
- Keep issue titles user-facing and outcome-focused.
- Add screenshots/gifs once features are visual.
- Add 'Known limitations' sections rather than hiding incomplete edges.

**Tests:**
- Docs link check if available; otherwise manual checklist.

**Docs to update:**
- This ticket is docs-focused.

### BS-JD-505 - First-hour usability polish pass

**Milestone:** M5  
**Priority:** P1  
**Area:** UX

**Summary:** Make the first hour in the editor feel guided: starter scene, tooltips, shortcut help, empty-state actions, and recovery messages.

**Why this matters:** A sandbox editor needs confidence-building. Jackdaw's docs and launcher-oriented flow make it clear how to start; Blacksite should do the same before the future game exists.

**Implementation notes:**
- Add first-run starter scene or guided empty-state overlay.
- Improve F1 shortcuts window with context-sensitive sections.
- Add empty-state buttons in Hierarchy, Asset Browser, Material Browser, and Viewport.
- Add consistent toast/status messages for successful saves, imports, tool commits, and failed operations.
- Add 'Reset editor layout', 'Open sample scene', and 'Create first brush' affordances.

**Acceptance criteria:**
- Fresh clone -> cargo run -p editor leads to visible useful scene or clear next action.
- F1 explains active tool shortcuts.
- Empty panels suggest actions instead of looking broken.
- Failed operations explain how to recover.

**Polish details:**
- Use concise language and avoid modal dialogs for routine hints.
- Hints disappear once user performs the action but can be restored.
- All messages include object names when possible.

**Tests:**
- Manual first-run checklist.
- Preference reset test if first-run state is persisted.

**Docs to update:**
- README Getting started.

## Suggested issue labels

`priority/P0`, `priority/P1`, `priority/P2`, `priority/P3`, `milestone/M0`, `milestone/M1`, `milestone/M2`, `milestone/M3`, `milestone/M4`, `milestone/M5`, `area/project`, `area/scene-io`, `area/inspector`, `area/viewport`, `area/brushes`, `area/materials`, `area/assets`, `area/terrain`, `area/physics`, `area/extensibility`, `area/remote`, `area/qa`, `polish`, `tests`, `docs`, `adr-needed`, `experimental`

## Issue template

```markdown
## Goal

## Current Blacksite context

## Jackdaw-inspired reference

## Implementation notes
- Files/modules:
- Data model changes:
- UI/UX behavior:
- Save/load/hydration impact:

## Acceptance criteria
- [ ]

## Polish checklist
- [ ] Preview/ghost/overlay
- [ ] Commit/cancel
- [ ] Undo/redo
- [ ] Status/error messages
- [ ] Docs updated
- [ ] Tests or sample scene

## Risks

## Out of scope
```

## Source inventory

Blacksite source paths are cited as `Falling-Metal-Interactive/Blacksite@main:<path>` because they were inspected through the Gitea repository tools. Jackdaw sources are public URLs inspected through web browsing.

- Blacksite: Falling-Metal-Interactive/Blacksite@main: Cargo.toml
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/Cargo.toml
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/lib.rs
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/bin/main.rs
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/ui/mod.rs
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/viewport/*
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/scene/scene_io.rs
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/assets/*
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/play/*
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/editor/src/ext/*
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/shared/src/lib.rs
- Blacksite: Falling-Metal-Interactive/Blacksite@main: crates/scene/src/lib.rs
- Blacksite: Falling-Metal-Interactive/Blacksite@main: docs/editor/README.md
- Blacksite: Falling-Metal-Interactive/Blacksite@main: docs/editor/architecture.md
- Blacksite: Falling-Metal-Interactive/Blacksite@main: docs/editor/roadmap.md
- Jackdaw: https://github.com/jbuehler23/jackdaw
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/README.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/developer-guide/architecture.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/developer-guide/crate-structure.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/developer-guide/extending-the-editor.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/developer-guide/open-challenges.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/user-guide/brushes.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/user-guide/materials-textures.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/user-guide/terrain.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/user-guide/physics.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/user-guide/scene-management.md
- Jackdaw: https://raw.githubusercontent.com/jbuehler23/jackdaw/main/book/src/user-guide/keyboard-shortcuts.md
