Prestige
As a player’s Contract Score grows they reach prestige tiers and each tier pays rewards they claim from the prestige view in the menu.
You write the track yourself, so it has exactly the tiers you define and it ends at the last one.
Tiers are stored in the prestige_data.json data file and authored with the
web editor.
By default, the prestige track is enabled, but no tiers are defined, essentially making it inactive until you add them.
Prestige track
Section titled “Prestige track”{ "tiers": [ { "threshold": 500, "title": null, "titleTranslations": null, "description": null, "descriptionTranslations": null, "rewards": { "tier_500_scrap": { "type": "Item", "title": "", "description": "", "eligiblePermissions": [], "hidden": false, "item": "scrap", "quantity": 500 } } }, { "threshold": 2000, "title": "Veteran", "titleTranslations": { "es": "Veterano" }, "description": "For the players who stuck around all wipe.", "descriptionTranslations": { "es": "Para los jugadores que se quedaron toda la wipe." }, "rewards": { "tier_2000_cash": { "type": "Economics", "title": "", "description": "", "eligiblePermissions": [], "hidden": false, "amount": 1000 } } }, { "threshold": 5000, "title": null, "titleTranslations": null, "description": null, "descriptionTranslations": null, "rewards": {} } ], "version": { "Major": 1, "Minor": 16, "Patch": 1 }}| Field | Type | Description |
|---|---|---|
threshold | integer (min 1) | The total Contract Score a player needs to reach this tier. Must be above 0 and different from every other tier. Tiers are listed from the lowest threshold to the highest. |
title | string | null | Optional name shown in the prestige view next to the tier number. null shows the number alone. The leaderboard never shows it. |
titleTranslations | map | null | Per-language overrides for title, mapping a language code (like "fr" or "zh-CN") to the translated text. Players whose language has no entry (matched case-insensitively, no region fallback) or a blank one see title instead. null when there are none. |
description | string | null | Optional text shown in the details panel when a player clicks the tier in the prestige view. null shows no description. |
descriptionTranslations | map | null | Per-language overrides for description, mapping a language code (like "fr" or "zh-CN") to the translated text. Players whose language has no entry (matched case-insensitively, no region fallback) or a blank one see description instead. null when there are none. |
rewards | map | What the player gets when they claim the tier, in the same shape as a contract's rewards. Every reward type works except Score. A tier with no rewards still counts toward the player's tier but has nothing to claim. |
Rules and Validations
Section titled “Rules and Validations”- A tier’s number is its place in the list, starting at 1. There is no id and no key to keep track of.
thresholdis the total CS a player needs to reach the tier. It must be above 0 and different from every other threshold in the track. The threshold defines the tier’s position on the track.- Keep the list from the lowest threshold to the highest. If it is out of order, the plugin sorts it at load, warns in the console and saves the sorted file back. The editor already takes care of this for you.
- Every reward type works except Score. CS is what the track runs on, so a tier paying CS would push players further up the track for claiming it. A Score reward inside a tier is dropped at load with a console warning.
- A tier with no rewards is still valid. Players reach it and it moves their tier number, there is just nothing for them to claim. The third tier above is one of those.
- An empty
tierslist is a valid file. The track then has nothing to show and nothing to pay and the menu button stays hidden.
What players see
Section titled “What players see”A star button appears in the menu header. It is only shown when prestige is on and the track has at least one tier and it turns your accent color while the player has a tier waiting to be claimed.
A tier row is in one of four states:
- Claimable: the player has the score and has not taken the rewards yet. The row is highlighted
in your accent color and the state cell is a Claim button. With
Claim Tiers In Orderon, only the lowest claimable tier gets the highlight and a working Claim button. Higher claimable tiers show a greyed out Claim until the ones below are taken. - Claimed: the rewards are already taken.
- Reached: the player has the score but there is nothing to claim, either because the tier has no rewards or because none of them are for this player.
- Locked: the player is short of the threshold. The cell reads how much more CS they need and the rewards are still drawn so they know what they are chasing.
Clicking a tier row shows that tier in the details panel on the right: its description, each reward with its amount, and a Claim button when the tier is claimable.
Claiming in order
Section titled “Claiming in order”By default, a player can claim their claimable tiers in any order. That breaks tier rewards that run commands in a set order. The common case is a chat tag group per tier: each tier removes the lower tier groups and adds its own. A player who claims tier 3 and then tier 2 ends up in both groups and shows both tags in chat.
Turn on Prestige > Claim Tiers In Order to make players claim their lowest claimable tier first.
A tier with no reward for the player is skipped, so it never blocks the tiers above it.
Claim All follows the same order.
Tier 3 of a chat tag track could look like this:
{ "threshold": 5000, "title": "Veteran", "titleTranslations": null, "rewards": { "tier_3_tag": { "type": "Command", "title": "Veteran chat tag", "description": "", "eligiblePermissions": [], "hidden": false, "commands": [ "oxide.usergroup remove {playerId} prestige1", "oxide.usergroup remove {playerId} prestige2", "oxide.usergroup add {playerId} prestige3" ], "reverseCommands": [], "icon": null, "iconColor": null, "iconRaw": false } }}The leaderboard column
Section titled “The leaderboard column”With the track on, the leaderboard gains a Tier column next to each player’s score, showing their current tier number (a dash for players who have not reached tier 1 yet).
That number is worked out from the score every time the board is drawn: it is the count of tiers the player’s CS has reached.
Losing and regaining score
Section titled “Losing and regaining score”contracts.take_score, a reward reversal or a wipe all lower a player’s current tier, because the
number follows the score.
Claimed tiers stay claimed. A tier a player already took stays taken even if their score falls back under it, so you never pay the same tier twice. A tier they reached but never claimed goes back to Locked and waits there until their score comes back.
Locking contracts and categories
Section titled “Locking contracts and categories”A contract or a category can carry a minPrestigeTier, which is the lowest tier a player needs
before they can accept it. A category’s tier is a floor for every contract in it and when both set
one, the higher of the two applies. A locked contract stays in rotation and stays in the list.
Edge cases:
- The lock is an accept gate and nothing more. A player who drops below the tier keeps every contract they already hold, including the progress on it and the reward at the end.
- A tier above the length of your track is still enforced, so nobody can accept that contract. The plugin prints a console warning at load for each one, so a typo or a deleted tier is easy to spot. The editor also has mechanisms to prevent this from happening, so you don’t have to worry about it as much.
- With
Prestige>Enabledoff, every tier lock is ignored and the contracts accept normally. The plugin prints one console warning at load listing what it let through.
The field sits on both the contract and the category.
Config
Section titled “Config”Prestige > Enabled turns the whole track on or off (see Prestige):
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | boolean | true | Turns the prestige track on. Off hides the prestige view and the leaderboard tier column, skips the tier messages, and ignores every tier lock. The prestige data file still loads. |
Claim Tiers In Order | boolean | false | Players have to claim their lowest claimable tier first. Higher tiers show a greyed out Claim button until the ones below are taken. Turn it on when tier rewards run commands that depend on order, like a chat tag group per tier. |
UI > Prestige holds the view’s page size (see UI):
| Field | Type | Default | Description |
|---|---|---|---|
Tiers Per Page | integer (min 1) | 25 | How many tiers each page of the prestige view lists. |
The star button itself takes an icon override under UI > Icons > Ui > Prestige, like every
other icon the plugin ships.
The track follows your existing Score > ResetOnWipe setting, because tiers are made of score.
There is no separate prestige wipe setting. If you wish to keep prestige tiers across wipes, you should set Score > ResetOnWipe to false.
Admins can clear both at any time with contracts.wipe_scores, which wipes claimed tiers along with
the scores (see Commands).
What prestige is not
Section titled “What prestige is not”TL;DR; The prestige system is deliberately designed NOT to become a leveling or progression system, so it doesn’t overshadow the plugin’s core vision, which is focused on questing.
I want Contracts’ purpose to remain focused on the unique questing experience it delivers to your players. The prestige system was almost abandonned because I was concerned it would shift the focus away from questing and into a leveling/progression system.
Instead, I deliberately designed the prestige system to complement the existing questing experience rather than creating new mechanics to define what “prestige” means on Contracts. It’s essentially one big long-term quest. This is done by:
- piggybacking on contract/category lock mechanics that already existed
- reusing existing rewards
- making use of CS instead of using another plugin (e.g. Skill Tree) to track progression, giving CS another purpose beyond the leaderboard.
