Skip to content
Contractsv1.16.1

Custom Rewards

⭐ Premium

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 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 icon to 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.

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.

FieldTypeDescription
kindstringExactly 'Command'
commandsstring[]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.
reverseCommandsstring[]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.
unitLabelstring | nullShort unit shown beside the amount, like "XP". Only valid when the command contains {amount}. Null shows the amount alone.
unitLabelTranslationsmap | nullPer-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)
FieldTypeDescription
displayNamestringLabel shown on the reward when a usage sets no title. The record key stays the identifier Custom rewards reference.
displayNameTranslationsmap | nullPer-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.
iconstring | nullDirect 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.
iconColorstring | nullColor 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.
iconRawbooleanSet 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.
FieldTypeDescription
kindstringExactly 'Item'
itemstringRust item shortNames, lowercase dotted (e.g. rifle.ak, rifle.bolt, wood, stones, metal.fragments, scrap, hqm, lowgradefuel).
skinIdinteger | 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.
itemNamestring | nullCustom 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.
itemNameTranslationsmap | nullPer-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)
FieldTypeDescription
displayNamestringLabel shown on the reward when a usage sets no title. The record key stays the identifier Custom rewards reference.
displayNameTranslationsmap | nullPer-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.
iconstring | nullDirect 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.
iconColorstring | nullColor 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.
iconRawbooleanSet 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.

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.

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.

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.

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.