Rewards
Two things configure rewards here:
- how rewards are presented in the menu
- the reward multipliers that pay higher-ranked players more for the same contract. (What each reward actually grants is defined per contract, not here. See the reward reference.)
{ "Rewards": { "Show Ineligible Rewards": true, "Multipliers": { "Level Source": { "Plugin": null, "Method": null, "Key": null }, "Tiers": [] } }}Fields
Section titled “Fields”| Field | Type | Default | Description |
|---|---|---|---|
Show Ineligible Rewards | boolean | true | Show rewards a player is not eligible for (missing the reward's permission) in the menu instead of hiding them. |
A reward is ineligible for a player when they lack the reward’s eligiblePermissions (see the
reward reference). Left on, the menu still lists those rewards and marks
them as ineligible for that player. Set it to false to hide them from that player instead.
Multipliers
Section titled “Multipliers”A multiplier tier defines who it matches and what those players get paid, per reward type. Contracts checks every tier against the player it is about to pay and each reward type takes the highest multiplier among the tiers that matched.
- A tier matches on a minimum level, on a permission, or on both. Both set means the player needs both.
- A tier with neither matches every player, which can be useful if you want to run double payout events.
- Tiers never stack, so a VIP tier can never cut a level tier’s payout. The order you list them in does not matter.
- Only amounts are multiplied: Economics, ServerRewards, Score and custom reward amounts. Item quantities and Command rewards are not and contract costs are never touched.
- ServerRewards and Score are whole numbers, so the result is rounded. Economics and custom amounts keep their decimals.
- The menu shows the amount the player will actually get.
- On the Lite edition every multiplier is 1, regardless of what is configured.
| Field | Type | Default | Description |
|---|---|---|---|
Tiers | object[] | [] | Multiplier tiers, each with the match condition and what it pays them. When several tiers match a player, every reward variant takes the highest multiplier across them. |
Level Source
Section titled “Level Source”Instead of implementing different leveling systems explicitly (Skill Tree, XPerience, ZLevels, etc.), Contracts takes a dependency-agnostic approach where you specify: the plugin, the method on it that gives back a level and a key if that plugin tracks more than one level. Contracts calls that method with the player every time it pays a reward, so a level up counts right away. While it makes it a bit less straightforward than hardcoding support for each plugin, this means the reward multipliers work with multiple current plugins out-of-the-box immediately and future potential plugins as well.
Method Signature
Section titled “Method Signature”This approach relies on the plugin using a common method signature that every other plugin used to design this feature followed.
MethodName(player: BasePlayer | ulong | string, key?: string)If it doesn’t, Contracts won’t be able to read the player’s level correctly. In that case, you can:
- Contact the plugin developer to add a compatible method for reading the player’s level.
- Use a permission-based approach instead, which does not rely on the plugin’s level method and is actually simpler to use.
- Request an update to the plugin to include a compatible method signature (in the #feedback Discord channel).
| Field | Type | Default | Description |
|---|---|---|---|
Plugin | string | null | null | Name of the plugin Contracts asks for a player's level, spelled the way the plugin list spells it ("SkillTree", "XPerience"). null means no level source, so tiers with a Min Level never match and tiers with a Permission keep working. |
Method | string | null | null | The method on that plugin that gives back a level, taken from its API docs (e.g. "GetPlayerLevel" for Skill Tree). Contracts calls it with the player and reads the number it returns. Set it together with Plugin. |
Key | string | null | null | Second argument for plugins that track several levels, usually a skill name ("WC" for ZLevels woodcutting, "Mining" for Skill System). Leave it null for plugins with one overall level. |
Here’s a couple configuration examples from popular leveling plugins at the time of writing:
| Leveling plugin | Plugin |
Method |
Key |
Notes |
|---|---|---|---|---|
| Skill Tree | SkillTree |
GetPlayerLevel |
leave null |
One overall level. A player it has never seen is level 0. |
| XPerience | XPerience |
GetXPCache |
"level" |
One overall level. |
| ZLevels Remastered | ZLevelsRemastered |
GetLevel |
a skill code: "WC", "M", "S", "A", "C", "F" |
One level per skill, so pick the skill you pay on. |
| Skill System | SkillSystem |
GetSkillLevel |
a skill name: "Mining", "Woodcutting" |
One level per skill, so pick the skill you pay on. |
ZLevels Remastered and Skill System track a level per skill instead of one overall level. Pick the
one skill you want to pay on with Key, or use that plugin’s own level rewards to grant a
permission and match a tier on that permission instead.
Any plugin not listed above with some kind of “give me this player’s level” method can still work. If the plugin is not
loaded or the method name is wrong, Contracts prints one warning in the console (so it doesn’t spam repeatedly) and tiers with a
Min Level stop matching. Tiers that match on a permission keep paying.
| Field | Type | Default | Description |
|---|---|---|---|
Min Level | number | null (min 0) | null | Lowest level a player needs for this tier to match. Needs a Level Source to work. null means the tier does not look at the level. |
Permission | string | null | null | Permission a player needs for this tier to match. Any permission name works, including one another plugin grants. null means the tier does not look at permissions. A tier with no Min Level and no Permission matches every player. |
Economics | number | 1 | Multiplies Economics reward amounts. 1 pays the authored amount. |
ServerRewards | number | 1 | Multiplies ServerRewards (RP) reward amounts, rounded to a whole number. 1 pays the authored amount. |
Score | number | 1 | Multiplies contract score reward amounts, rounded to a whole number. 1 pays the authored amount. |
SkillTreeXp | number | 1 | Multiplies Skill Tree XP reward amounts. 1 pays the authored amount. |
SkillTreePoints | number | 1 | Multiplies Skill Tree skill point reward amounts, rounded to a whole number. Point amounts are small, so 1.5x on 1 point pays 2. 1 pays the authored amount. |
Custom | map | {} | Multipliers for custom reward amounts, keyed by the custom reward key. The key is matched without case, like every other custom reward lookup. A key you omit pays the authored amount, and a custom reward with no amount is never multiplied. |
A full example
Section titled “A full example”Skill Tree levels paying more the higher a player climbs, plus a prestige tier:
"Multipliers": { "Level Source": { "Plugin": "SkillTree", "Method": "GetPlayerLevel", "Key": null }, "Tiers": [ { "Min Level": 10, "Permission": null, "Economics": 1.0, "ServerRewards": 1.0, "Score": 1.0, "SkillTreeXp": 1.25, "SkillTreePoints": 1.0, "Custom": { "EasyHeliSignal": 1.0 } }, { "Min Level": 20, "Permission": null, "Economics": 1.25, "ServerRewards": 1.0, "Score": 1.0, "SkillTreeXp": 1.5, "SkillTreePoints": 1.0, "Custom": { "EasyHeliSignal": 1.5 } }, { "Min Level": 90, "Permission": null, "Economics": 2.5, "ServerRewards": 1.0, "Score": 1.0, "SkillTreeXp": 5.0, "SkillTreePoints": 1.0, "Custom": { "EasyHeliSignal": 2.0 } }, { "Min Level": null, "Permission": "skilltree.prestige1", "Economics": 1.5, "ServerRewards": 1.0, "Score": 1.0, "SkillTreeXp": 1.0, "SkillTreePoints": 1.0, "Custom": {} } ]}A player at level 95 matches the first three tiers, so they get 2.5x Economics, 5x Skill Tree XP and
2x on the EasyHeliSignal custom reward, the highest of each. Give that player the prestige
permission and their Economics stays at 2.5x, because 2.5 beats the prestige tier’s 1.5.
EasyHeliSignal is only an example key. A Custom entry does nothing unless you have a
custom reward under that exact key, so put your own keys there.
