# Tech Spec: Unity-style Component List for a Bevy Level Editor

## Purpose

The component list is the main authoring UI for a selected **Actor** in the level. In this editor, an **Actor** is a Bevy `Entity` plus editor-facing metadata: stable ID, display name, hierarchy position, prefab/link info, and a curated list of inspectable components.

The inspector should feel similar to Unity:

```text
Actor Header
Transform
Component A
Component B
Component C
...
Sticky Footer:
  Search components...
  + Add Component
```

The Add Component button belongs at the bottom of the component stack, not under Transform.

## Core Rules

- Bevy components are the source of truth.
- The editor exposes components through a registry.
- Inspector ordering is editor metadata, not ECS truth.
- Transform is pinned to the top.
- Runtime systems must never depend on inspector order.

## Actor Model

Each actor should contain:

```rust
Actor
ActorName
InspectorOrder
AuthoringComponentStates
ActorKind // derived compatibility/display hint
```

Use stable IDs for save files:

```text
ActorId
  Stable identity persisted to disk.

Entity
  Runtime-only ECS identity.

ComponentInstanceId
  Stable identity for repeatable authoring items.
```

Never serialize raw Bevy Entity IDs into level files.

## Component Registry

Every editor-visible component should be registered.

```rust
pub struct EditorComponentDescriptor {
    pub id: &'static str,        // stable editor/protocol identity
    pub type_name: &'static str,
    pub display_name: &'static str,
    pub addable: bool,
    pub removable: bool,
    pub reorderable: bool,
}
```

The registry controls:

- Scene persistence and reflected presence
- Visibility
- Addability
- Removal rules
- Custom inspectors
- Search metadata
- Categories
- Requirements, recommendations, and conflicts

Add, remove, reset, copy/paste, and extension-owned edits use reflected
`ComponentTransaction` history. All component deltas plus the derived `ActorKind` update are one
undo step. See [the extensibility guide](extensibility.md) and
[ADR 0034](../adr/0034-registry-driven-authoring-components.md).

## Inspector Layout

Single-column layout only.

```text
Header

Transform

Static Mesh Renderer

Physics

Audio

Gameplay

---------------------
Search Components...
+ Add Component
```

The footer remains visible while scrolling.

## Component Cards

Each component contains:

```text
[Enabled]
[Collapse Arrow]
[Icon]
Component Name
[Dirty Indicator]
[Menu]
```

Menu actions:

- Reset
- Copy
- Paste Values
- Move Up
- Move Down
- Remove
- Open Documentation

Transform is special:

- Cannot remove
- Cannot move
- Can reset

## Add Component Flow

```text
Open Palette
Search
Select Component
Create Default Instance
Insert Component
Expand Component
Mark Dirty
Push Undo Command
```

The component palette supports:

- Search
- Categories
- Favorites
- Recent Components
- Compatibility Checks

## Asset Selectors

Assets should never look like plain text boxes.

Bad:

```text
Mesh: assets/models/Dumpster.fbx
```

Good:

```text
[Preview Thumbnail]

Mesh1000
Dumpster.fbx

[Browse]
[Locate]
[Clear]
```

Asset selector requirements:

- Thumbnail preview
- Drag/drop support
- Open in asset browser
- Missing asset warnings
- Type filtering

## Static Mesh Renderer

This renderer is restricted to unrigged, non-animated geometry. Imported parts marked skinned, or
parts from a source containing animation, are not valid static slots.

Recommended structure:

```rust
pub struct StaticMeshRenderer {
    pub slots: Vec<MeshRenderSlot>,
}
```

Each slot:

```rust
pub struct MeshRenderSlot {
    pub id: ComponentInstanceId,
    pub mesh: EditorAssetRef,
    pub material: EditorAssetRef,
}
```

Inspector:

```text
Static Mesh Renderer

▼ Slot 0 Dumpster
  Mesh Selector
  Material Selector
  Collider Settings

▼ Slot 1 Dumpster Lid
  Mesh Selector
  Material Selector

▶ Slot 2 Dumpster Lid_02

+ Add Slot
```

Collapsed slots reduce inspector height.

## Skinned Mesh Renderer

Rigged, skin-bound, or animated model geometry uses a separate asset-owned renderer:

```rust
pub struct SkinnedMeshRenderer {
    pub asset_id: String,
    pub path: String,
    pub scene_index: usize,
}
```

It has no independent static slots. Hydration instantiates the source hierarchy beneath a
`HydratedSkinnedMeshRoot`, retaining Bevy joint entities, inverse bind poses, `SkinnedMesh`
bindings, and animation-player placement. The inspector shows the source, scene, and stable asset
ID; source reassignment happens through asset placement rather than field-by-field mesh editing.
`AnimationControllerDesc` is an optional sibling component and requires this renderer.

## Property Drawing

Generic reflection is the fallback.

Custom inspectors should exist for:

- Transform
- Static Mesh Renderer
- Skinned Mesh Renderer
- Materials
- Physics
- Audio
- Navigation

Useful field metadata:

```rust
#[editor(min = 0.0)]
#[editor(max = 100.0)]
#[editor(unit = "m/s")]
```

## Serialization

Recommended level structure:

```rust
LevelAsset
  Actors[]

ActorRecord
  Components[]
```

Separate:

- Runtime Components
- Editor Components
- Transient Components

## Undo / Redo

Every change becomes a command.

```rust
trait UndoableCommand {
    fn apply();
    fn undo();
}
```

Examples:

- Set Position
- Assign Mesh
- Assign Material
- Add Component
- Remove Component

Numeric dragging should create one undo record.

## Multi-Selection

Support:

- Common Components
- Mixed Values
- Batch Editing

Example:

```text
Position

X  —
Y  0.0
Z  —
```

## Prefab Overrides

Fields can be:

- Inherited
- Overridden
- Added
- Removed

Visual indicators:

```text
Blue Dot
Field Override

Bold Component
Component Override
```

Use stable slot IDs for overrides instead of array indices.

## Component Categories

```text
Rendering
Physics
Audio
Gameplay
Navigation
Scripting
Editor
```

Support:

- Favorites
- Recently Used
- Plugin Components

## Acceptance Criteria

- Single-column inspector.
- Transform pinned to top.
- Sticky bottom Add Component footer.
- Asset selectors with previews.
- Searchable component palette.
- Undo/redo for every edit.
- Stable Actor IDs.
- Multi-selection support.
- Prefab override support.
- Inspector order independent from ECS runtime behavior.
