Complete queues, matchmaking, maps, loadouts, hooks, theme, and API reference.
fnx-pvp-matches provides ranked queues, custom team matches, rounds, Elo, inventories, stats, and leaderboard integration.
First installation
First setup
Configure client behavior, server rules, andshared/public/_main.lua. Every enabled map needs unique identification, valid team spawns, and correct inventory item names.
Client configuration
Runtime
| Key | Default | Explanation |
|---|---|---|
Runtime.closePanelOnJoin | true | Closes the panel after joining. |
Runtime.deathEvents | true | Enables built-in death events. Disable if one custom detector replaces them. |
Runtime.countdown.enabled | true | Enables the visual countdown. |
Runtime.countdown.sound | true | Enables countdown sound. |
Runtime.countdown.volume | 0.5 | Sound volume from 0 to 1. |
Runtime.countdown.holdMs | 2200 | Milliseconds the final countdown state remains visible. |
Runtime.invincible.enabled | true | Master transition-invincibility switch. |
Runtime.invincible.beforeRound | true | Protects during prestart. |
Runtime.invincible.afterRound | true | Protects after a round. |
Runtime.antiTeamKill.enabled | true | Blocks teammate damage using relationship groups. |
Runtime.antiTeamKill.disableMelee | true | Also blocks teammate melee damage. |
Runtime.antiTeamKill.groupA | "PVP_MATCH_A" | Relationship-group name for team A. |
Runtime.antiTeamKill.groupB | "PVP_MATCH_B" | Relationship-group name for team B. |
Runtime.returnCoords | nil | Optional client return vec4. |
ClientCfg.Death | {} | Overrides panel death defaults; empty inherits them. |
Client hooks
| Key | Arguments | Called when |
|---|---|---|
Events.OnMatchStart | payload | Match begins. |
Events.OnRoundPrestart | payload | Prestart begins; default code equips ox_inventory weapon. |
Events.OnRoundStart | payload | Combat begins. |
Events.OnRoundEnd | payload | Round ends. |
Events.OnMatchEnd | payload | Match completes. |
Events.OnMatchLeave | payload | Local player leaves. |
Events.OnPlayerDeadOnMatch | payload, activeMatch | Local death is accepted. |
Events.OnPlayerKillOnMatch | payload, activeMatch | Local kill is accepted. |
Events.OnGameEventTriggered | callback or nil | Optional raw game-event callback. |
Client commands
These commands are registered client-side by the match runtime.| Command | Purpose |
|---|---|
/leavematch | Leaves the active match. |
/leaveparty | Leaves the current party. |
+fnx_pvp_match_tab | Internal key-mapped command that opens the match scoreboard. |
-fnx_pvp_match_tab | Internal key-mapped command that closes the match scoreboard. |
| Key mapping | Default key | Label |
|---|---|---|
+fnx_pvp_match_tab | TAB | Show match scoreboard |
Server configuration
Queue and warning
| Key | Default | Explanation |
|---|---|---|
Queue.modes | 1v1 to 6v6 | Allowed ranked queue sizes. Format must be NvN. |
Queue.defaultElo | 0 | Starting match Elo. |
Queue.matchFoundNotifyTime | 6500 | Match-found notification duration in milliseconds. |
Queue.warning.enabled | bridge-dependent | Enables inventory-change confirmation. |
Queue.warning.holdSeconds | 1 | Confirmation hold time. |
Queue.warning.timeoutSeconds | 30 | Confirmation expiry. |
Matchmaking
| Key | Default | Explanation |
|---|---|---|
Matchmaking.ranked | true | Uses Elo restrictions/updates for ranked queue. |
Matchmaking.requireSameMap | true | Requires compatible selected map. |
Matchmaking.eloGap.initial | 250 | Initial maximum Elo difference. |
Matchmaking.eloGap.expandEverySeconds | 30 | Search time between gap expansions. |
Matchmaking.eloGap.expandBy | 100 | Elo added at every expansion. |
Matchmaking.eloGap.max | 1000 | Final maximum Elo difference. |
Custom matches
| Key | Default | Explanation |
|---|---|---|
Custom.firstTo | {6,9,13} | Allowed target scores. |
Custom.maxTeamSize | 6 | Maximum members per custom team. |
Custom.updateStats | false | Saves normal stats from custom matches. |
Custom.updateElo | false | Changes Elo from custom matches. |
Custom.requireBalancedTeams | false | Requires equal team sizes when true. |
Match runtime
| Key | Default | Explanation |
|---|---|---|
Match.firstTo | 6 | Default rounds/points required to win. |
Match.roundTime | 300 | Round limit in seconds. |
Match.countdown | 5 | Pre-round countdown in seconds. |
Match.prestartDelay | 2500 | Server prestart delay in milliseconds. |
Match.roundEndDelay | 5500 | Delay after a round in milliseconds. |
Match.loadTimeout | 15000 | Player/map load timeout in milliseconds. |
Match.bucketBase | 40000 | First match routing bucket. |
Match.returnBucket | 0 | Bucket restored after leaving. |
Match.returnCoords | nil | Optional server return vec4. |
Elo and inventory
| Key | Default | Explanation |
|---|---|---|
Elo.kFactor | 32 | Elo sensitivity. Higher values produce larger changes. |
Elo.minDelta | 6 | Minimum applied Elo change. |
Elo.maxDelta | 40 | Maximum applied Elo change. |
Inventory.enabled | bridge-dependent | Enables snapshot/loadout management. |
Inventory.keepInventory | false | Disables match inventory/loadout management and lets players keep items. |
Inventory.mode | "auto" | auto, bridge, or native. |
Inventory.weaponMetadata.enabled | true | Gives weapon ammo/components inside weapon metadata instead of as separate inventory items. |
Inventory.weaponMetadata.durability | 10000 | Durability value written to weapon metadata when metadata mode is enabled. |
Inventory.weaponMetadata.ammo | true | Stores configured ammo in weapon metadata and skips the separate ammo item grant. |
Inventory.weaponMetadata.components | true | Stores configured components in weapon metadata and skips separate component item grants. |
Inventory.ammoRefill.enabled | true | Enables automatic ammo refill checks. |
Inventory.ammoRefill.threshold | 0.5 | Refill only when current ammo is below this fraction of configured ammo. |
Inventory.ammoRefill.roundEnd | true | Checks/refills ammo at round end. |
Inventory.snapshotConfiguredItemsOnly | false | When true, snapshots only items known to match configuration. |
Inventory.restoreOnNextJoin | true | Restores a pending snapshot when the player next joins after interruption. |
Rewards
ServerCfg.Rewards controls item/account rewards. Rewards are given independently from match loadouts, so they still work when Inventory.keepInventory is true.
| Key | Explanation |
|---|---|
Rewards.kill.enabled | Enables rewards for every kill. |
Rewards.kill.items | Items/accounts given on kill. |
Rewards.killStreaks.enabled | Enables killstreak rewards. |
Rewards.killStreaks.public | When false, players need command-granted access before receiving streak rewards. |
Rewards.killStreaks.rewards[streak] | Rewards given when the player reaches that streak value. |
reward.item | Inventory item name given through the configured inventory bridge. |
reward.account | Framework account name such as bank; requires a framework/account bridge. |
reward.amount | Base reward amount. It is multiplied by the player’s reward multiplier. |
reward.metadata | Optional item metadata passed to the inventory. |
Logs
Each log category supportsenabled, username, avatar, webhooks, and embed. webhooks is an array, so one category can send to multiple Discord webhooks. embed is a Lua function and can be fully customized per server.
| Category | Sent when |
|---|---|
Logs.admin | Admin/internal actions such as reward permission or multiplier changes. |
Logs.matchCreated | A match is created. |
Logs.matchEnd | A match ends; includes map, mode, reason, winner, score, duration, team totals, and player stats. |
Logs.matchEndByType | Optional per-mode override for matchEnd webhooks/settings, e.g. 1v1, 2v2, or custom. |
Logs.inventoryStored | A player’s inventory snapshot is stored before match loadout is applied. |
Logs.inventoryRestore | A player’s original inventory and pending rewards are restored. |
Reward commands
| Key | Explanation |
|---|---|
Commands.giveStreakRewards.active | Registers the streak reward access command. |
Commands.giveStreakRewards.name | Default command name: givematchstreakrewards. |
Commands.giveStreakRewards.permission | Permission required to use the command. |
Commands.setRewardMultiplier.active | Registers the reward multiplier command. |
Commands.setRewardMultiplier.name | Default command name: setmatchrewardmultiplier. |
Commands.setRewardMultiplier.permission | Permission required to use the command. |
giveStreakRewards only when Rewards.killStreaks.public is false. setRewardMultiplier changes the multiplier used by kill and streak rewards.
Server hooks
| Key | Arguments |
|---|---|
Events.OnMatchStart | match |
Events.OnRoundPrestart | match |
Events.OnRoundStart | match |
Events.OnRoundEnd | match, winnerTeam, reason |
Events.OnMatchEnd | match, winnerTeam, reason |
Events.OnPlayerDeadOnMatch | match, deadPlayer, killerPlayer, payload |
Events.OnPlayerKillOnMatch | match, killerPlayer, deadPlayer, payload |
Events.OnPlayerLeaveMatch | match, player, dropped |
Shared files
shared/public/_main.lua obtains REVIVE_EVENT from the panel and defines Maps.
Map schema
| Key | Explanation |
|---|---|
name | Unique map ID. Duplicate names make selection ambiguous. |
resource | One or more map resource names used as availability requirements. |
label | Human-readable map name. |
image | Local filename or supported URL shown in the UI. |
coords | General vec3 map position. |
swap | Enables team-side swapping between rounds. |
firstTo | Map-specific target score. |
roundTime | Map-specific round limit in seconds. |
weapons | Loadouts offered on this map. |
extraItems | Extra inventory items given with the match loadout. Ignored when Inventory.keepInventory is true or inventory management is disabled. |
winningTeamRewards | Items/accounts given to winners at match end. These are real rewards and are given even when Inventory.keepInventory is true. |
teams | Available team spawn definitions. |
Shared weapon and team keys
| Key | Explanation |
|---|---|
weapons[].id | Unique weapon selection ID. |
weapons[].hash | GTA weapon hash. |
weapons[].label | Display label. |
weapons[].ammo | Ammo issued. |
weapons[].components | GTA component hashes. |
weapons[].itemsData.weapon | Inventory weapon item. |
weapons[].itemsData.ammo | Inventory ammo item. |
weapons[].itemsData.components | Inventory component items. |
teams[].name | Unique team display/name. |
teams[].spawn | Team vec4 spawn and heading. |
Theme system
| Key | Explanation |
|---|---|
colors.panelBg | Main panel background. |
colors.panelBgStrong | Darker background. |
colors.accent | Primary highlight. |
colors.accentStrong | Strong active highlight. |
colors.text | Primary text. |
colors.mutedText | Secondary text. |
colors.surface | Normal card surface. |
colors.surfaceStrong | Strong card surface. |
colors.border | Borders and separators. |
colors.overlay | Modal overlay. |
colors.success | Success foreground. |
colors.successBg | Success background. |
colors.danger | Error foreground. |
colors.dangerBg | Error background. |
colors.warning | Warning foreground. |
colors.warningBg | Warning background. |
colors.info | Information foreground. |
colors.infoBg | Information background. |
colors.ratingElite | Elite rating tier. |
colors.ratingMaster | Master rating tier. |
colors.ratingDiamond | Diamond rating tier. |
colors.ratingPlatinum | Platinum rating tier. |
colors.ratingGold | Gold rating tier. |
colors.ratingSilver | Silver rating tier. |
colors.ratingBase | Base/unranked tier. |
radii.panel | Main panel corner radius in pixels. |
radii.card | Card corner radius in pixels. |
radii.control | Input/control corner radius in pixels. |
radii.pill | Badge radius; 999 creates a pill. |
effects | Reserved effects table, currently empty. |
fonts.body | Normal-text CSS font stack. |
fonts.display | Heading CSS font stack. |
Developer info
Client exports
| Export | Parameters | Returns / purpose |
|---|---|---|
IsInMatch | none | Returns whether the local player is in an active match. |
ReportDeath | payload | Reports a local match death. |
CanReportDeath | none | Returns whether a new death report is currently accepted. |
Server exports
| Export | Parameters | Returns / purpose |
|---|---|---|
GetLeaderboardPage | request | Returns the requested match leaderboard page. |
GetStats | identifier | Returns stored match statistics for an identifier. |
GetPanelStats | source, identifier | Returns match statistics formatted for the PVP panel. |
GetPanelRank | source, identifier | Returns panel rank data for the identifier. |
GetLeaderboardEntries | limit, sortMetric | Returns leaderboard entries with optional limit and sorting. |
SyncPlayer | source | Reloads/synchronizes one player’s match data. |
GetActiveMatch | source | Returns the active match associated with the player. |
IsInMatch | source | Returns whether the server player is in a match. |
Common issues
No opponent is found
Check mode, selected map, same-map requirement, and Elo gap expansion.Wrong spawn or map
Ensure every map name is unique and every team spawn is valid.Inventory is not restored
Check inventory mode, item names, snapshot scope, andrestoreOnNextJoin.
Some configured weapons are not given
Each weapon is applied with its ammunition and components as one package. If a complete package does not fit, only that weapon is skipped. Other weapons are still given and the player receives one notification showing how many weapons were skipped.Deaths count twice
Use one detector and callCanReportDeath() before a custom report.
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. |
Weapon is holstered/folded instead of equipped during PvP flow
Open:fnx-pvp-matches/settings/public/server/cfg.luaFind:
ServerCfg.Events.OnRoundPrestart
Write inside:
