Custom Rewards
A custom reward definition is a reward you write once and reuse everywhere. It comes in two kinds:
- Command runs one or more console commands, which is how many plugins (Heli Signals, XPerience, Ganja) hand out their rewards.
- Item gives an item, with an optional skin and name. This is how you pay out a server currency made from an item.
Instead of retyping it on every contract, define it once here, then add a Custom reward that references it by key with an amount.
The biggest advantage is reusable editing: fix the definition and every contract that references it is fixed too, including contracts you exported months ago. The plugin looks up the definition when the reward is claimed, not when the contract is authored.
Custom reward definitions are stored in the custom_reward_data.json data file and authored with
the web editor.
Every definition has a kind, a display name and an optional icon, stored under a key you choose.
A Command definition adds the commands to run, plus optional reverse commands and a unit label. An
Item definition adds the item, an optional skin ID and an optional item name.
{ "customRewards": { "EasyHeliSignal": { "kind": "Command", "displayName": "Easy Heli Signal", "displayNameTranslations": null, "commands": [ "hsgive easy {playerId} {amount}" ], "reverseCommands": [], "unitLabel": null, "unitLabelTranslations": null, "icon": null, "iconColor": null, "iconRaw": false }, "Weed": { "kind": "Command", "displayName": "Weed", "displayNameTranslations": null, "commands": [ "ganja.give weed low_quality {amount} {playerId}" ], "reverseCommands": [], "unitLabel": null, "unitLabelTranslations": null, "icon": null, "iconColor": null, "iconRaw": false }, "Cash": { "kind": "Item", "displayName": "Cash", "displayNameTranslations": null, "item": "paper", "skinId": 3731371060, "itemName": "Cash", "itemNameTranslations": null, "icon": null, "iconColor": null, "iconRaw": false } }, "version": { "Major": 1, "Minor": 16, "Patch": 1 }}The key (EasyHeliSignal) is the identifier that Custom rewards reference. displayName is the text
players see when a reward using the definition sets no title of its own, and
displayNameTranslations holds optional per-language overrides for it (see
Translating your content).
Item definitions
Section titled “Item definitions”Item definitions are made for server currencies: an item with a skin and a custom name that most of
your contracts pay out. The example above is paper with workshop skin 3731371060, named Cash.
With an Item reward you would repeat the item, skin and name on every
contract. With an Item definition you write them once, and each Custom reward that references it
gives amount of that item.
A Custom reward using an Item definition pays like an Item reward:
- When the player’s inventory is full, the claim stops. The player needs to make some room and claim again. When the plugin gives the reward on its own, for example when the contract expires, the items drop at the player’s feet instead.
- If claiming fails halfway, the plugin takes the items back, like any other item reward.
- The menu shows the item with its skin and the item count. Set
iconto show your own image instead. - A skin sold by Facepunch only goes on the item for players who own it. Other players get the plain item, which does not stack with the skinned one. The plugin warns at load when a definition uses one of these skins.
itemName goes on the item itself, while displayName names the reward in the menu. Leave
itemName null to keep the game’s name.
An Item definition has no commands, reverseCommands or unitLabel. If you add them by hand, the
plugin removes them with a warning. A definition whose item is not a real Rust item is removed at
load, and the rewards using it act like a missing definition.
To give the same item from a shop or a kit, use contracts.give_item.
To make an objective match the same item, write it as paper:3731371060 in the objective’s items list. See Targeting custom items.
Plugins you might use
Section titled “Plugins you might use”Anything with a console command that takes a player works for a Command definition. The ones that come up most are Heli
Signals, XPerience, ZLevels Remastered, Ganja, Kits, and battlepass or leaderboard plugins. Read the
command off that plugin’s own page, then drop {playerId} and {amount} into it. Contracts does
not check that the plugin is installed, so test the command in the server console first.
Paying out an item? Use an Item definition.
Fields
Section titled “Fields”Command
Section titled “Command”| Field | Type | Description |
|---|---|---|
kind | string | Exactly 'Command' |
commands | string[] | Console commands to run when the reward is claimed, top to bottom. Every command supports runtime placeholders such as {playerId} and {playerName}. Include {amount} in any of them to make every usage carry an amount that substitutes into it. |
reverseCommands | string[] | Console commands that take back what the commands gave, with the same placeholders. They run in the order written, and only when claiming fails halfway and the rewards already given roll back. Empty when the reward cannot be taken back. |
unitLabel | string | null | Short unit shown beside the amount, like "XP". Only valid when the command contains {amount}. Null shows the amount alone. |
unitLabelTranslations | map | null | Per-language overrides for unitLabel, 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 unitLabel instead. null when there are none. |
Shared fields (5)
| Field | Type | Description |
|---|---|---|
displayName | string | Label shown on the reward when a usage sets no title. The record key stays the identifier Custom rewards reference. |
displayNameTranslations | map | null | Per-language overrides for displayName, 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 displayName instead. null when there are none. |
icon | string | null | Direct image URL for the icon on rewards using this definition. A reward's own icon beats it. Null (or omitted) shows the item for an Item definition. For a Command definition it keeps the default lightning icon, or the per-type Custom override from the plugin config when one is set. |
iconColor | string | null | Color for the icon, as hex (#rrggbb or #rrggbbaa), rgb() or rgba(). Null (or omitted) inherits the per-type or default color. Invalid colors warn at plugin load and render white. Does nothing when an Item definition shows its item. |
iconRaw | boolean | Set true when the icon is a full-color image (a logo, custom art) so it renders in its own colors. When false the image renders as a solid color, which is right for monochrome icons. |
| Field | Type | Description |
|---|---|---|
kind | string | Exactly 'Item' |
item | string | Rust item shortNames, lowercase dotted (e.g. rifle.ak, rifle.bolt, wood, stones, metal.fragments, scrap, hqm, lowgradefuel). |
skinId | integer | null (min 0) | Skin put on the given items, as the skin's workshop ID. null for the item's default look. A skin sold by Facepunch only shows for players who own it. Other players get the item without the skin, and those items do not stack with skinned ones. |
itemName | string | null | Custom name put on the given items. Separate from displayName, which names the reward in the menu. null or blank leaves the item's own name. |
itemNameTranslations | map | null | Per-language overrides for itemName, 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 itemName instead. null when there are none. |
Shared fields (5)
| Field | Type | Description |
|---|---|---|
displayName | string | Label shown on the reward when a usage sets no title. The record key stays the identifier Custom rewards reference. |
displayNameTranslations | map | null | Per-language overrides for displayName, 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 displayName instead. null when there are none. |
icon | string | null | Direct image URL for the icon on rewards using this definition. A reward's own icon beats it. Null (or omitted) shows the item for an Item definition. For a Command definition it keeps the default lightning icon, or the per-type Custom override from the plugin config when one is set. |
iconColor | string | null | Color for the icon, as hex (#rrggbb or #rrggbbaa), rgb() or rgba(). Null (or omitted) inherits the per-type or default color. Invalid colors warn at plugin load and render white. Does nothing when an Item definition shows its item. |
iconRaw | boolean | Set true when the icon is a full-color image (a logo, custom art) so it renders in its own colors. When false the image renders as a solid color, which is right for monochrome icons. |
Referencing a definition
Section titled “Referencing a definition”A Custom reward on a contract or objective points at a definition
with its reward field:
{ "type": "Custom", "title": "", "description": "", "eligiblePermissions": [], "hidden": false, "reward": "Weed", "amount": 500, "icon": null, "iconColor": null, "iconRaw": false}When this reward is claimed, the plugin substitutes {amount} with 500 and runs
ganja.give weed low_quality 500 {playerId} on the server console. With "reward": "Cash" the
same reward gives 500 Cash instead.
Placeholders
Section titled “Placeholders”Command definitions only. Every command and reverse command takes every placeholder from the
Command reward table, plus {amount}, which is
replaced with the amount set on the reward that references the definition.
Put {amount} in any of the commands and every reward using the definition needs an amount. A
reverse command or a unit label can only use the amount when at least one command takes it.
Reverse commands
Section titled “Reverse commands”Console commands normally cannot be taken back, so a failure halfway through claiming a multi-reward
contract would leave players keeping partial payouts. The reverseCommands list fixes that: it
holds the commands that undo commands, in the order they should run. When giving out rewards fails
halfway during a claim, the plugin runs the reverse commands for each command reward it already gave,
with the same placeholder substitution, and the player can claim again later.
Leave it empty ([]) when the reward cannot be undone. Plain
Command rewards can carry their own reverseCommands
too.
An Item definition needs no reverse command. The plugin takes the items back on its own.
Missing definitions
Section titled “Missing definitions”A Custom reward can point at a definition that no longer exists, for example after a delete or a typo in a hand-edited file. In the editor this shows a warning, and export still works. On the server the plugin logs a warning at load and shows the reward as ineligible to every player, so the contract stays playable and only that reward is never granted.
