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

# Fnx PVP Leaderboard

> Complete installation, podium, provider, theme, and configuration reference.

> Complete installation, podium, provider, theme, and configuration reference.

`fnx-pvp-leaderboard` collects rankings from registered PVP providers and displays them in the panel and on optional in-world podiums.

## First installation

```cfg theme={null}
ensure oxmysql
ensure community_bridge

ensure fnx-pvp-panel
ensure fnx-pvp-leaderboard
```

Start gameplay plugins after the leaderboard.

This resource does not create its own database tables. `oxmysql` is used to read podium skin data from your framework's existing tables.

## First setup

1. Configure the panel entry and theme in `settings/public/client/cfg.lua`.
2. Configure ranking cache and podiums in `settings/public/server/cfg.lua`.
3. Replace every `vec4(0, 0, 0, 0)` podium coordinate before enabling that podium.
4. Confirm that `skinProvider` matches your clothing resource and that `PodiumSkin.Resolve` matches its database.

## Client configuration

### Panel plugin

| Key                               | Type    | Default                             | Explanation                                                                                                  |
| --------------------------------- | ------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `ClientCfg.Plugin.id`             | string  | `"leaderboard"`                     | Unique ID used to register and open this panel plugin. Do not reuse it for another plugin.                   |
| `ClientCfg.Plugin.labelKey`       | string  | `"plugins.leaderboard.label"`       | Locale key used as the plugin title.                                                                         |
| `ClientCfg.Plugin.descriptionKey` | string  | `"plugins.leaderboard.description"` | Locale key used as the plugin description.                                                                   |
| `ClientCfg.Plugin.icon`           | string  | `"fa-solid fa-trophy"`              | Font Awesome CSS class displayed by the panel.                                                               |
| `ClientCfg.Plugin.resource`       | string  | current resource                    | Resource that owns the plugin. Keep `GetCurrentResourceName()` unless you intentionally rename/integrate it. |
| `ClientCfg.Plugin.ui`             | string  | `"web/dist/index.html"`             | Built NUI page loaded for the plugin.                                                                        |
| `ClientCfg.Plugin.order`          | number  | `15`                                | Sort position inside the PVP panel; lower values appear earlier.                                             |
| `ClientCfg.Plugin.enabled`        | boolean | `true`                              | Registers and shows the plugin when true.                                                                    |

## Server configuration

### Leaderboard cache

| Key                                    | Type   | Default | Explanation                                                                                           |
| -------------------------------------- | ------ | ------- | ----------------------------------------------------------------------------------------------------- |
| `ServerCfg.Leaderboard.refreshSeconds` | number | `150`   | Seconds between automatic provider refreshes. Lower values are fresher but call providers more often. |
| `ServerCfg.Leaderboard.limit`          | number | `250`   | Maximum number of entries kept/requested for the global snapshot.                                     |
| `ServerCfg.Leaderboard.sortMetric`     | string | `"elo"` | Default metric. Supported configured values are `elo`, `wins`, `kills`, and `kd`.                     |

### Skin resolver

| Key                            | Type     | Explanation                                                                                                                                                                                           |
| ------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ServerCfg.PodiumSkin.Resolve` | function | Receives `identifier` and returns stored skin data or nil. The included function checks `users.skin` for ESX and active `playerskins.skin` rows for QBCore/Qbox. Edit its SQL if your schema differs. |
| `identifier`                   | string   | Framework identifier passed into the resolver after trimming.                                                                                                                                         |

### Podium entries

`ServerCfg.Podiums` is an array. Every podium object uses these keys:

| Key                   | Type                   | Explanation                                                                                                                                                        |
| --------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `enabled`             | boolean                | Creates this podium when true. Disable it while coordinates or skin integration are incomplete.                                                                    |
| `id`                  | string                 | Unique internal podium ID. Each podium needs a different value.                                                                                                    |
| `label`               | string                 | Human-readable podium name used for identification/debugging.                                                                                                      |
| `metric`              | string                 | Metric requested from the selected provider, such as `elo`, `wins`, `kills`, or `kd`.                                                                              |
| `provider`            | string                 | Registered provider ID. Official examples use `match`; it must match the provider's registration ID exactly.                                                       |
| `drawDistance`        | number                 | Maximum distance in game units at which podium peds are managed/drawn.                                                                                             |
| `resource`            | string or string array | Map/resource requirement for this podium. Use the resource names associated with that location.                                                                    |
| `excludedIdentifiers` | array                  | Identifiers that must be skipped when selecting ranked players for this podium.                                                                                    |
| `skinProvider`        | string                 | Clothing integration returned by the bridge or one of the supported configured providers: `fivem-appearance`, `illenium-appearance`, `qb-clothing`, or `esx_skin`. |
| `slots`               | array                  | Ordered podium positions. The first slot represents rank 1, the second rank 2, and the third rank 3.                                                               |

Each object inside `slots` uses:

| Key        | Type            | Explanation                                                                                                                  |
| ---------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `coords`   | vector4         | Ped X, Y, Z, and heading. Zero coordinates are placeholders and must be replaced.                                            |
| `model`    | string          | Fallback GTA ped model, normally a freemode model when loading player appearance.                                            |
| `scenario` | string or `nil` | GTA scenario played by the podium ped. Set nil for no scenario.                                                              |
| `loadSkin` | function        | Called with `self`, `identifier`, and `entry`; it must return appearance data. The default forwards to `PodiumSkin.Resolve`. |

## Shared files

The shared private file initializes the bridge, framework enum, debug printing, string helpers, JSON helpers, deep copying, and locale flattening. It exposes no customer cfg keys; edit public cfg files instead.

## Theme system

All color values are CSS strings. Radii are pixels and fonts are CSS font-family lists.

### General colors

| Key                    | Default                  | Explanation                  |
| ---------------------- | ------------------------ | ---------------------------- |
| `colors.panelBg`       | `#0b0b10`                | Main leaderboard background. |
| `colors.panelBgStrong` | `#070709`                | Darker background variant.   |
| `colors.accent`        | `#f97316`                | Primary highlight.           |
| `colors.accentStrong`  | `#fb923c`                | Strong active highlight.     |
| `colors.text`          | `#f5f5f5`                | Primary text.                |
| `colors.mutedText`     | `rgba(245,245,245,0.62)` | Secondary text.              |
| `colors.surface`       | `rgba(23,23,23,0.62)`    | Normal row/card surface.     |
| `colors.surfaceStrong` | `rgba(10,10,10,0.94)`    | Strong surface.              |
| `colors.border`        | `rgba(255,255,255,0.10)` | Borders and separators.      |
| `colors.overlay`       | `rgba(0,0,0,0.72)`       | Modal overlay.               |
| `colors.success`       | `#4ade80`                | Success foreground.          |
| `colors.successBg`     | `rgba(34,197,94,0.16)`   | Success background.          |
| `colors.danger`        | `#f87171`                | Error foreground.            |
| `colors.dangerBg`      | `rgba(239,68,68,0.16)`   | Error background.            |
| `colors.warning`       | `#fbbf24`                | Warning foreground.          |
| `colors.warningBg`     | `rgba(245,158,11,0.16)`  | Warning background.          |
| `colors.info`          | `#60a5fa`                | Information foreground.      |
| `colors.infoBg`        | `rgba(59,130,246,0.16)`  | Information background.      |

### Rating colors

| Key                     | Default   | Explanation          |
| ----------------------- | --------- | -------------------- |
| `colors.ratingElite`    | `#ffd51d` | Elite-tier color.    |
| `colors.ratingMaster`   | `#ff6754` | Master-tier color.   |
| `colors.ratingDiamond`  | `#ff35e3` | Diamond-tier color.  |
| `colors.ratingPlatinum` | `#e077ff` | Platinum-tier color. |
| `colors.ratingGold`     | `#7fa0ff` | Gold-tier color.     |
| `colors.ratingSilver`   | `#78e0ff` | Silver-tier color.   |
| `colors.ratingBase`     | `#d6e1ec` | Base/unranked color. |

### Dropdown colors

| Key                               | Default                  | Explanation                 |
| --------------------------------- | ------------------------ | --------------------------- |
| `colors.dropdownBg`               | `rgba(10,10,10,0.94)`    | Closed dropdown background. |
| `colors.dropdownBorder`           | `rgba(255,255,255,0.14)` | Dropdown border.            |
| `colors.dropdownText`             | `#f5f5f5`                | Selected-value text.        |
| `colors.dropdownArrow`            | `rgba(255,255,255,0.86)` | Dropdown arrow.             |
| `colors.dropdownFocus`            | `rgba(249,115,22,0.36)`  | Focus outline/glow.         |
| `colors.dropdownOptionBg`         | `#111217`                | Option-list background.     |
| `colors.dropdownOptionText`       | `#f5f5f5`                | Normal option text.         |
| `colors.dropdownOptionHoverBg`    | `rgba(249,115,22,0.18)`  | Hovered option background.  |
| `colors.dropdownOptionActiveBg`   | `rgba(249,115,22,0.38)`  | Selected option background. |
| `colors.dropdownOptionActiveText` | `#ffffff`                | Selected option text.       |

### Podium UI colors

| Key                     | Default                  | Explanation            |
| ----------------------- | ------------------------ | ---------------------- |
| `colors.podiumGold`     | `#ffd65a`                | Rank-one foreground.   |
| `colors.podiumSilver`   | `#cfd8e3`                | Rank-two foreground.   |
| `colors.podiumBronze`   | `#d58b51`                | Rank-three foreground. |
| `colors.podiumGoldBg`   | `rgba(255,214,90,0.10)`  | Rank-one background.   |
| `colors.podiumSilverBg` | `rgba(207,216,227,0.10)` | Rank-two background.   |
| `colors.podiumBronzeBg` | `rgba(213,139,81,0.10)`  | Rank-three background. |

### Radii and fonts

| Key             | Default            | Explanation                      |
| --------------- | ------------------ | -------------------------------- |
| `radii.panel`   | `12`               | Main panel radius in pixels.     |
| `radii.card`    | `8`                | Card/row radius in pixels.       |
| `radii.control` | `8`                | Filter control radius in pixels. |
| `radii.pill`    | `999`              | Fully rounded badge radius.      |
| `fonts.body`    | `Space Grotesk...` | Normal-text font stack.          |
| `fonts.display` | `Bebas Neue...`    | Heading font stack.              |

## Developer info

| Server export        | Parameters           | Result/purpose                                          |
| -------------------- | -------------------- | ------------------------------------------------------- |
| `GetEntries`         | `metric, limit`      | Returns entries for one metric with an optional limit.  |
| `GetSnapshot`        | none                 | Returns the current cached leaderboard snapshot.        |
| `Refresh`            | none                 | Forces provider refresh; do not call it for every kill. |
| `RegisterProvider`   | `pluginId, provider` | Registers or replaces one server-side provider.         |
| `UnregisterProvider` | `pluginId`           | Removes the provider registered under that ID.          |

Use the official Matches, Lobbies, Redzone, or Aimlab server code as the canonical provider-shape example.

## Common issues

### Peds appear at 0, 0, 0

The v1 and v2 examples contain zero coordinates. Replace every enabled slot coordinate.

### A skin is missing

Verify `skinProvider`, identifier type, database table, active flag, and skin JSON. Adapt `PodiumSkin.Resolve` for custom schemas.

### A provider is missing

Start the leaderboard before gameplay plugins and ensure `provider` exactly matches their registration ID.

### Rankings feel old

Reduce `refreshSeconds` carefully or call `Refresh()` after a meaningful batch update.

### The filter keeps the old colors

Dropdowns have dedicated `dropdown*` keys; changing only `surface` does not restyle all dropdown states.

## Common folders

| Path                             | What it is for                                                                       |
| -------------------------------- | ------------------------------------------------------------------------------------ |
| `fxmanifest.lua`                 | FiveM manifest. It loads the resource files in the correct order.                    |
| `settings/public/client/cfg.lua` | Client settings that server owners are expected to edit.                             |
| `settings/public/server/cfg.lua` | Server settings that server owners are expected to edit.                             |
| `settings/private/**/_cfg.lua`   | Internal/default settings. Do not edit unless you are modifying the resource itself. |
| `client/public/*.lua`            | Public client API files and safe integration files.                                  |
| `client/private/*.lua`           | Internal client runtime code.                                                        |
| `server/public/*.lua`            | Public server API files and exports.                                                 |
| `server/private/*.lua`           | Internal server runtime code.                                                        |
| `shared/public/*.lua`            | Shared public data or integration constants.                                         |
| `shared/private/*.lua`           | Shared internal helpers loaded by the resource.                                      |
| `locales/*.json`                 | Locales for ui and game.                                                             |
| `web/dist/`                      | Built NUI files used in-game. Do not edit these by hand.                             |

```txt theme={null}
fnx-pvp-leaderboard/
|-- client/
|   |-- private/
|   |   \-- _main.lua
|   \-- public/
|       |-- draw.lua
|       |-- esx_skin.lua
|       |-- fivem_appearance.lua
|       |-- illenium_appearance.lua
|       \-- qb_clothing.lua
|-- locales/
|   \-- *.json
|-- server/
|   |-- private/
|   |   \-- _main.lua
|   \-- public/
|       \-- main.lua
|-- settings/
|   |-- private/
|   |   |-- client/
|   |   |   \-- _cfg.lua
|   |   \-- server/
|   |       \-- _cfg.lua
|   \-- public/
|       |-- client/
|       |   \-- cfg.lua
|       \-- server/
|           \-- cfg.lua
|-- shared/
|   \-- private/
|       \-- _main.lua
|-- web/
|   \-- dist/
\-- fxmanifest.lua
```
