# PrefabOf actor

The `PrefabOf<T>` type is a specialized parameter type that allows game designers to select a prefab asset in the editor while ensuring it contains a specific type of actor.

### The Problem

When using the generic `Prefab` type for a parameter, a level designer can pick *any* prefab asset from the project.

```typescript
@Parameter()
spawnPrefab: Prefab
```

If your gameplay logic expects the prefab to contain a specific actor (e.g., a `WeaponActor` or a `HealthPackActor`), picking the wrong prefab will lead to runtime errors or broken behavior. This requires constant communication between programmers and designers to ensure the right assets are used.

### The Solution: `PrefabOf<T>`

By using `PrefabOf<T extends BaseActor>`, you can restrict the selection in the editor to only those prefabs that have a [prefab-main-actor](https://docs.hology.app/gameplay/actors/prefab-main-actor "mention") of type `T` (or a subclass of `T`).

#### Benefits

1. **Editor Safety**: The editor's asset picker will filter out any prefabs that don't match the required main actor type.
2. **Type Safety**: When you spawn an actor using a `PrefabOf<T>` parameter, the engine automatically returns an instance typed as `T`.
3. **Subclass Support**: It works with any prefab whose main actor is a subclass of `T`, allowing for polymorphic behavior.

***

### Use Case Example

Imagine a **Weapon Box** that spawns a weapon when opened. You want to ensure that only prefabs representing weapons can be assigned to the box.

#### 1. Define the Parameters

In your actor class, use `PrefabOf<WeaponActor>` for the parameter.

```typescript
import { Actor, BaseActor, Parameter, PrefabOf } from '@hology/core'
import { WeaponActor } from './weapon-actor'

@Actor()
class WeaponBox extends BaseActor {
  @Parameter()
  weaponPrefab: PrefabOf<WeaponActor>

  async open() {
    // Spawning from a PrefabOf<WeaponActor> returns a WeaponActor instance
    const weapon = await this.world.spawnActor(this.weaponPrefab, this.object.position)
    
    // You can now safely call weapon-specific methods
    weapon.equip()
  }
}
```

#### 2. Editor Interaction

When a level designer selects the `WeaponBox` in the editor:

* They will see the `weaponPrefab` parameter.
* The asset picker will **only show prefabs** that have an actor of type `WeaponActor` (or its subclasses like `SwordActor` or `GunActor`) set as their **Main Actor**.

***

### Comparison: `Prefab` vs `PrefabOf<T>`

| Feature               | `Prefab`              | `PrefabOf<T>`                                          |
| --------------------- | --------------------- | ------------------------------------------------------ |
| **Editor Selection**  | Any prefab asset      | Only prefabs with Main Actor of type `T`               |
| **Spawn Return Type** | `PrefabInstance`      | The actor instance itself as `T` (automatically typed) |
| **Intent**            | Generic instantiation | Specific gameplay requirements                         |
| **Spawn method**      | `world.spawnPrefab`   | `world.spawnActor`                                     |
| **Remove method**     | `world.removePrefab`  | `world.removeActor`                                    |

***

### Technical Note: Main Actor Required

For a prefab to be selectable by a `PrefabOf<T>` parameter, it **must** have a [prefab-main-actor](https://docs.hology.app/gameplay/actors/prefab-main-actor "mention") defined. If a prefab does not have a Main Actor, it will not appear in the filtered list, even if it contains an actor of type `T` somewhere in its hierarchy.
