> ## Documentation Index
> Fetch the complete documentation index at: https://mythicframework.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Doors - Exports

> Door lock management, elevator controls, and dynamic door operations

The Doors component manages door lock states, elevator floor access, lockpicking, and dynamic door creation.

## Overview

Access via `Doors` (server-side only).

<CardGroup cols={2}>
  <Card title="Lock Control" icon="lock">
    Lock and unlock doors
  </Card>

  <Card title="Elevators" icon="elevator">
    Multi-floor elevator management
  </Card>

  <Card title="Dynamic Doors" icon="plus">
    Runtime door creation
  </Card>

  <Card title="Lockpicking" icon="key">
    Lockpick support
  </Card>
</CardGroup>

<Warning>
  **Server-Side Only:** Door state changes must be performed on the server. Changes are automatically broadcast to all clients.
</Warning>

***

## Door Methods

### Doors:SetLock

Set the lock state of a door.

```lua theme={null}
Doors:SetLock(doorId, newState, doneDouble)
```

<ParamField path="doorId" type="string|number" required>
  Door string ID or numeric index
</ParamField>

<ParamField path="newState" type="boolean|nil" required>
  `true` = locked, `false` = unlocked, `nil` = toggle
</ParamField>

<ParamField path="doneDouble" type="boolean" optional>
  Internal flag for double-door handling (do not set manually)
</ParamField>

<ResponseField name="state" type="boolean|nil">
  New lock state, or `nil` if door not found
</ResponseField>

**Behavior:**

* If the door has a `double` property, both doors are updated
* If the door has `autoLock`, it will re-lock after the specified seconds
* Broadcasts `Doors:Client:UpdateState` to all clients

**Example:**

```lua theme={null}
-- Lock a door
Doors:SetLock('mrpd_front', true)

-- Unlock a door
Doors:SetLock('mrpd_front', false)

-- Toggle a door
Doors:SetLock('mrpd_front', nil)

-- Lock door after a robbery
AddEventHandler('mythic-robbery:server:Started', function(source, robberyId, doorId)
    Doors:SetLock(doorId, true)
end)
```

***

### Doors:IsLocked

Check if a door is currently locked.

```lua theme={null}
Doors:IsLocked(doorId)
```

<ParamField path="doorId" type="string|number" required>
  Door string ID or numeric index
</ParamField>

<ResponseField name="locked" type="boolean">
  `true` if locked
</ResponseField>

**Example:**

```lua theme={null}
if Doors:IsLocked('mrpd_front') then
    TriggerClientEvent('mythic-notifications:client:Send', source, {
        message = 'This door is locked',
        type = 'error'
    })
end
```

***

### Doors:SetForcedOpen

Force a door to open visually (e.g., after breaching).

```lua theme={null}
Doors:SetForcedOpen(doorId)
```

<ParamField path="doorId" type="string|number" required>
  Door string ID or numeric index
</ParamField>

**Example:**

```lua theme={null}
-- Breach a door
Doors:SetLock(doorId, false)
Doors:SetForcedOpen(doorId)
```

***

### Doors:SetElevatorLock

Set the lock state of an elevator floor.

```lua theme={null}
Doors:SetElevatorLock(elevatorId, floorId, newState)
```

<ParamField path="elevatorId" type="string" required>
  Elevator identifier
</ParamField>

<ParamField path="floorId" type="number" required>
  Floor index
</ParamField>

<ParamField path="newState" type="boolean|nil" required>
  `true` = locked, `false` = unlocked, `nil` = toggle
</ParamField>

<ResponseField name="state" type="boolean|nil">
  New lock state, or `nil` if not found
</ResponseField>

**Example:**

```lua theme={null}
-- Lock the top floor of MRPD elevator
Doors:SetElevatorLock('mrpd_elevator', 3, true)
```

***

## Dynamic Door Exports

These are resource exports (not component methods) for runtime door management.

### GetAllDoors

```lua theme={null}
exports['mythic-doors']:GetAllDoors()
```

<ResponseField name="doors" type="table">
  All door definitions
</ResponseField>

***

### AddDynamicDoor

Add a door at runtime (saved to database).

```lua theme={null}
exports['mythic-doors']:AddDynamicDoor(doorData)
```

<ParamField path="doorData" type="table" required>
  Door definition (see Configuration page)
</ParamField>

***

### RemoveDynamicDoor

Remove a dynamic door.

```lua theme={null}
exports['mythic-doors']:RemoveDynamicDoor(doorIndex)
```

***

### UpdateDynamicDoor

Update an existing dynamic door.

```lua theme={null}
exports['mythic-doors']:UpdateDynamicDoor(doorIndex, doorData)
```

***

### GetAllElevators

```lua theme={null}
exports['mythic-doors']:GetAllElevators()
```

***

### AddDynamicElevator

```lua theme={null}
exports['mythic-doors']:AddDynamicElevator(data)
```

***

### UpdateDynamicElevator

```lua theme={null}
exports['mythic-doors']:UpdateDynamicElevator(elevatorIndex, data)
```

***

### RemoveDynamicElevator

```lua theme={null}
exports['mythic-doors']:RemoveDynamicElevator(elevatorIndex)
```

***

## Server Callbacks

| Callback                      | Description                                  |
| ----------------------------- | -------------------------------------------- |
| `Doors:Fetch`                 | Returns all door and elevator data + configs |
| `Doors:ToggleLocks`           | Toggle a door lock (checks authorization)    |
| `Doors:Lockpick`              | Attempt to lockpick a door                   |
| `Doors:Elevators:ToggleLocks` | Toggle elevator floor lock                   |
| `Doors:Elevator:Validate`     | Validate elevator usage                      |

***

## Events

| Event                              | Direction       | Description                 |
| ---------------------------------- | --------------- | --------------------------- |
| `Doors:Client:UpdateState`         | Server → Client | Door lock state changed     |
| `Doors:Client:SetForcedOpen`       | Server → Client | Door forced open            |
| `Doors:Client:UpdateElevatorState` | Server → Client | Elevator floor lock changed |
| `Doors:Client:AttemptLockpick`     | Server → Client | Start lockpick minigame     |
| `Doors:Server:LockpickFailed`      | Client → Server | Lockpick attempt failed     |

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use String IDs for Important Doors" icon="tag">
    ```lua theme={null}
    -- ✅ Good: Named door, easy to reference
    { id = "mrpd_front", model = 2089009131, coords = vector3(...), locked = true }

    -- ❌ Bad: No ID, must use numeric index
    { model = 2089009131, coords = vector3(...), locked = true }
    ```
  </Accordion>

  <Accordion title="Check Lock State Before Actions" icon="shield-check">
    ```lua theme={null}
    -- Check if a door is accessible before allowing entry
    if Doors:IsLocked('vault_door') then
        TriggerClientEvent('mythic-notifications:client:Send', source, {
            message = 'The vault is locked',
            type = 'error'
        })
        return
    end
    ```
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Doors - Configuration" icon="gear" href="/api/doors/configuration">
    Door and elevator definitions
  </Card>

  <Card title="Jobs API" icon="briefcase" href="/api/jobs/exports">
    Job restrictions for doors
  </Card>

  <Card title="Admin Callbacks" icon="shield-halved" href="/api/admin/callbacks">
    Admin door management tools
  </Card>
</CardGroup>
