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

# MMO Profile Menu

> Configuration for the 3D entity-based MMO Profile selection menu

The `mmo_profile_menu` manifest entry configures an immersive 3D profile selection experience. The player's camera is locked, entities represent each profile slot, and navigation is done via scroll wheel, WASD, or click actions.

## Configuration

<ResponseField name="mmo_profile_menu" type="Map" required>
  <Expandable title="Properties">
    <ResponseField name="title" type="Var<String>">
      Menu title displayed in the HUD. Supports MiniMessage. Default: `<gradient:#ffd700:#ffaa00>Select Your Profile</gradient>`
    </ResponseField>

    <ResponseField name="displayMode" type="ProfileDisplayMode">
      How profile entities are displayed. Options: `ALL` (all configured slots), `UNLOCKED_ONLY` (only unlocked profiles), `CAROUSEL` (one at a time with scrolling). Default: `CAROUSEL`
    </ResponseField>

    <ResponseField name="profileSlots" type="List<ProfileSlotConfig>">
      Pre-configured profile slots. Configure up to the max number of profiles players can have (e.g., 10 slots). Each slot maps to an entity definition.
    </ResponseField>

    <ResponseField name="basePosition" type="Var<Position>">
      Base camera position. Supports in-game position capture. When `usePlayerLocation` is true, this acts as an offset from the player's current location.
    </ResponseField>

    <ResponseField name="usePlayerLocation" type="Boolean">
      If true, `basePosition` is treated as an offset from the player's location. Default: `false`
    </ResponseField>

    <ResponseField name="slotSpacing" type="Double">
      Horizontal spacing between profile slot camera positions (in blocks). Default: `3.0`
    </ResponseField>

    <ResponseField name="defaultMaxProfiles" type="Int">
      Default maximum number of profiles for a player. Default: `3`
    </ResponseField>

    <ResponseField name="permissionLimits" type="List<ProfileLimit>">
      Permission-based overrides for profile slot limits.
    </ResponseField>

    <ResponseField name="forceProfileSelection" type="Boolean">
      If true, the player CANNOT close the menu without selecting a profile. Sneak, WASD close, and right-click delete are blocked. Default: `false`
    </ResponseField>

    <ResponseField name="wasdNavigation" type="Boolean">
      If true, A/D keys navigate between profile slots instead of closing the menu. Default: `true`
    </ResponseField>

    <ResponseField name="closeOnSneak" type="Boolean">
      Close the menu when the player sneaks. Ignored when `forceProfileSelection` is true. Default: `true`
    </ResponseField>

    <ResponseField name="wasdScrollCooldownMs" type="Long">
      Cooldown in milliseconds between WASD navigation inputs. Default: `200`
    </ResponseField>

    <ResponseField name="onOpenSound" type="Sound">
      Sound played when the menu opens.
    </ResponseField>

    <ResponseField name="onCloseSound" type="Sound">
      Sound played when the menu closes.
    </ResponseField>

    <ResponseField name="onNavigateSound" type="Sound">
      Sound played when navigating between profile slots.
    </ResponseField>

    <ResponseField name="onSelectSound" type="Sound">
      Sound played when a profile is selected.
    </ResponseField>

    <ResponseField name="onHoverSound" type="Sound">
      Sound played on hover/change focus (reserved).
    </ResponseField>

    <ResponseField name="onOpenActions" type="List<Ref<ActionEntry>>">
      Actions executed when the menu opens.
    </ResponseField>

    <ResponseField name="onCloseActions" type="List<Ref<ActionEntry>>">
      Actions executed when the menu closes.
    </ResponseField>

    <ResponseField name="onSelectActions" type="List<Ref<ActionEntry>>">
      Actions executed when any profile is selected.
    </ResponseField>
  </Expandable>
</ResponseField>

## ProfileSlotConfig

Each profile slot in the `profileSlots` list.

<ResponseField name="profileSlots[]" type="Map">
  <Expandable title="Properties">
    <ResponseField name="slotIndex" type="Int">
      The 0-based index of this slot. Used for ordering.
    </ResponseField>

    <ResponseField name="entityDefinition" type="Ref<ManifestEntry>">
      Reference to an existing entity definition. Use the entry picker to select from available definitions (Entity, BetterModel, ModelEngine, or MythicMob NPC).
    </ResponseField>

    <ResponseField name="cameraOffsetX" type="Double">
      Camera offset X (left/right) relative to the base position for this slot.
    </ResponseField>

    <ResponseField name="cameraOffsetY" type="Double">
      Camera offset Y (up/down).
    </ResponseField>

    <ResponseField name="cameraOffsetZ" type="Double">
      Camera offset Z (forward/backward).
    </ResponseField>

    <ResponseField name="entitySpawnOffsetX" type="Double">
      Entity spawn offset X from base position.
    </ResponseField>

    <ResponseField name="entitySpawnOffsetY" type="Double">
      Entity spawn offset Y.
    </ResponseField>

    <ResponseField name="entitySpawnOffsetZ" type="Double">
      Entity spawn offset Z.
    </ResponseField>

    <ResponseField name="onSelectActions" type="List<Ref<ActionEntry>>">
      Actions executed when this specific profile slot is selected.
    </ResponseField>

    <ResponseField name="onNavigateActions" type="List<Ref<ActionEntry>>">
      Actions executed when the player navigates to this slot.
    </ResponseField>
  </Expandable>
</ResponseField>

## ProfileLimit

<ResponseField name="permissionLimits[]" type="Map">
  <Expandable title="Properties">
    <ResponseField name="permission" type="String">
      The permission node required.
    </ResponseField>

    <ResponseField name="limit" type="Int">
      The profile limit granted by this permission.
    </ResponseField>
  </Expandable>
</ResponseField>

## Controls

| Input              | Action                                                                    |
| :----------------- | :------------------------------------------------------------------------ |
| Scroll Wheel       | Navigate left/right between profiles                                      |
| A / D              | Navigate left/right (`wasdNavigation: true`)                              |
| Left Click         | Select the focused profile                                                |
| Right Click        | Delete the focused profile (with Paper confirmation dialog)               |
| Shift + Left Click | Create a new profile on an empty slot (with Paper input dialog)           |
| Sneak              | Close the menu (`closeOnSneak: true`, blocked if `forceProfileSelection`) |

## Behavior Matrix

| `forceProfileSelection` | `wasdNavigation` | WASD       | Sneak      | R-Click Delete |
| :---------------------- | :--------------- | :--------- | :--------- | :------------- |
| `false`                 | `true`           | Navigate   | Close menu | Allowed        |
| `false`                 | `false`          | Close menu | Close menu | Allowed        |
| `true`                  | `true`           | Navigate   | Blocked    | Blocked        |
| `true`                  | `false`          | Ignored    | Blocked    | Blocked        |
