# Integrations

All integrations are optional. Mira starts without them too, only the respective extra features fall away, no errors.

## Overview

| Plugin | Adds | Without it |
|---|---|---|
| **PlaceholderAPI** | `%mira_...%` in chat, tab, holograms, messages | Placeholders just stay unresolved |
| **Vault** | Offer economy to other plugins or use a foreign one (`economy.internal: false`) | Economy runs normally, no bridge |
| **LuckPerms** | Prefix/suffix, groups, permission-based limits, group spawns | Limits only global, not per group |
| **CoreProtect** | Jobs exploit protection (no money for self-placed blocks), transaction logs | Simple RAM fallback (lost on restart) |
| **WorldGuard / GriefPrevention** | RTP and mob teleport avoid protected regions/claims | RTP can land in foreign land |
| **BetterHud** | Balance, job and team events as a HUD popup | Shown as actionbar/chat |
| **Nexo / Carpentary** | Custom items/blocks/furniture in shops and jobs | Vanilla items only |

## PlaceholderAPI

Detected automatically. All placeholders; the claim module's start with `%miraclaim_`:

| Placeholder | Description | Example |
|---|---|---|
| `%mira_balance%` | Raw balance | `1500.50` |
| `%mira_balance_formatted%` | With symbol/separator | `1,500.50 Coins` |
| `%mira_balance_short%` | Short with symbol | `⛃ 1,500.50` |
| `%mira_nick%` | Nickname (plain text) | `CoolName` |
| `%mira_nick_raw%` | Nickname with formatting | `<red>Cool</red>` |
| `%mira_has_nick%` | Has a nickname? | `true`/`false` |
| `%mira_homes_count%` | Set homes | `3` |
| `%mira_homes_limit%` | Home limit | `5` / `unlimited` |
| `%mira_rtp_count%` | RTP uses | `12` |
| `%mira_rtp_cooldown%` | Remaining cooldown | `30 seconds` / `0` |
| `%mira_rtp_cooldown_<world>%` | Cooldown per world | `2 minutes 15 seconds` |
| `%mira_rtp_price_<world>%` | RTP cost per world | `500.00 Coins` |
| `%mira_joinmsg%` / `_leavemsg%` | Custom join/leave message? | `true`/`false` |
| `%mira_team_name%` / `_tag%` / `_color%` | Team name, tag, colour | `CoolTeam` / `[CT]` / `red` |
| `%mira_team_rank%` / `_rank_id%` / `_rank_weight%` | Rank, id, weight | `Moderator` / `0` / `2` |
| `%mira_team_rank_count%` | Ranks in the team | `5` |
| `%mira_team_can_<perm>%` | May the player do this? | `yes`/`no` |
| `%mira_team_score%` / `_balance%` / `_members%` | Score, treasury, members | `4500` / `25000.00` / `8` |
| `%mira_team_level%` / `_level_name%` | Team level | `3` / `Silver` |
| `%mira_team_top_<n>%` | Team at rank n by score | `TopTeam` |
| `%mira_jobs_count%` / `_points%` | Active jobs, points | `3` / `150.00` |
| `%mira_jobs_name_<n>%` | n-th active job | `Miner` |
| `%mira_jobs_level_<job>%` / `_xp_<job>%` | Level, XP in a job | `15` / `250.5` |
| `%mira_jobs_income_<job>%` / `_title_<job>%` | Income, title | `5000.00` / `Expert Miner` |
| `%mira_sleep_percentage%` / `_sleeping%` / `_required%` | Sleep threshold (number or percentage), sleeping, required | `25%` / `2` / `3` |
| `%mira_lp_prefix%` / `_suffix%` | LuckPerms prefix/suffix (text) | `[ADMIN]` |
| `%mira_lp_prefix_raw%` / `_suffix_raw%` | with formatting | `<gold>[ADMIN]</gold>` |
| `%mira_lp_group%` / `_group_display%` | Group, display name | `admin` / `Administrator` |
| `%miraclaim_owner%` | Owner of the claim at the player's position (`Wilderness` outside claims, `offline` when the player is not online) | `Steve` |
| `%miraclaim_in_claim%` / `%miraclaim_in_own_claim%` | In a claim / in own claim? | `true`/`false` |
| `%miraclaim_blocks_total%` / `_blocks_used%` / `_blocks_available%` | Claim blocks total, used, available | `1200` / `800` / `400` |
| `%miraclaim_claim_count%` | Number of own claims | `3` |
| `%miraclaim_combat_tagged_seconds_left%` | Seconds left on the combat tag | `0` |

Usable in chat (`chat.*`), tab (`tab.yml`), holograms, join/leave messages and broadcasts.

## LuckPerms

Provides group, prefix/suffix, meta values, membership and numeric limits. **Permission-based limits** (highest value wins):

```text
homes.limit.<n> / homes.limit.unlimited
jobs.max.<n>    / jobs.max.unlimited
shop.limit.<n>  rtp.limit.<n>  jobs.maxlevel.<n>  jobs.boost.<mult>
```

**Group spawns** apply before the global spawn:

```yaml
spawn:
  group-spawns:
    vip:
      world: "world"
      x: 100
      y: 100
      z: 100
```

## CoreProtect

On every block break it checks whether the block was player-placed per history, then no job income is paid. Without CoreProtect, Mira only remembers placed blocks in RAM (lost on restart).

If CoreProtect goes down at runtime, Mira reports it once, switches the jobs check to its own memory of placed blocks and throttles lookup failures to one warning per minute. When CoreProtect comes back, Mira reconnects automatically; a Jobs module that was switched off in the meantime needs a restart.

Optional logs (toggle per module in `modules/*.yml`):

| Event | Log name in CoreProtect |
|---|---|
| Job block break | `#jobs-<player>` |
| Shop buy / sell | `#shop-buy-<player>` / `#shop-sell-<player>` |
| Team chest break | `#teamclaim-<player>` |

## Which module uses what

| Module | Integration | For |
|---|---|---|
| Jobs | CoreProtect, Nexo, Carpentary, BetterHud | Exploit protection, custom items, popups |
| Shop | CoreProtect, Nexo, Carpentary | Logs, custom items |
| Team | CoreProtect | Chest-break logs |
| RTP | WorldGuard, GriefPrevention | Avoid landing in foreign land |
| Chat/Tab | LuckPerms, Nexo | Prefix/suffix, symbols |

> **Tip:** The switches for Nexo/Carpentary/CoreProtect live in the module files (`jobs.yml` under `jobs.integrations.*`, `team.yml` under `team.integrations.coreprotect.*`). Only BetterHud has its own file.

## Example config (betterhud.yml)

```yaml
enabled: true

betterhud:
  elements:
    balance:
      enabled: true
      popup-name: ""
      popup-duration: 60
    team-tag:
      enabled: true
      popup-name: ""
      popup-duration: 60
```
