Contracts
A contract is a single quest: a small bundle of one or more objectives to
complete and one or more rewards paid out when it is done. Contracts are stored in the
contracts_data.json data file and surfaced to players by being listed in a category.
You author contracts with the web editor. The shape below is what it reads and writes. For a hand-written, copy-pasteable example, see Create your first contract.
Fields
Section titled “Fields”| Field | Type | Description |
|---|---|---|
title |
string (non-empty) | The name players see. Required. |
description |
string | A short blurb shown under the title. May be empty if the title says it all. |
objectives |
map (1 or more) | The goals to complete. See Objectives. |
rewards |
map (1 or more) | What the contract pays out on completion. See Rewards. |
progressionType |
enum: Independent/Sequential/Progressive | How the objectives unlock (see below). Independent is the default. |
replayCooldown |
number (1 or more) or null |
How long a player waits after completing this contract before they can take it again, in seconds. null lets the category decide (see below). |
costs |
map (0 or more) | What the player pays to accept the contract. Empty means it is free to take (see below). |
objectives, rewards and costs are stored as keyed maps, not arrays. Each key is a unique id you choose, and the
key order is the display order. (Reordering in the editor rewrites this order.)
Progression type
Section titled “Progression type”progressionType controls the order players tackle a contract’s objectives:
Independent: every objective is active at once. The default, and the right choice for most contracts.Sequential: objectives must be completed in order, so only the first incomplete one is active. Later objectives are visible but locked.Progressive: likeSequential, but locked objectives are hidden in the menu until they unlock, so the contract reveals itself step by step.
The contract lifecycle
Section titled “The contract lifecycle”A contract moves through these states for a given player:
- Accepted: the player opted into an available contract, and progress is now tracked.
- Completed: every objective is met and the reward is ready to be claimed.
- Claimed: the player collected their reward, before it is auto-claimed at the next rotation.
- Abandoned: the player dropped the contract before finishing it. This can happen to make room for new contracts when the max active contracts limit is reached.
- Expired: the contract’s category rotated while it was still in progress, so partial progress is lost (a clock decision, distinct from abandoning).
Replayable contracts
Section titled “Replayable contracts”By default a contract is locked once completed and claimed, until the category rotates. A replay cooldown changes that. Set one and the player can take the same contract again after a wait.
Three fields decide the cooldown, one on the contract and two on the category:
| Field | Where | What it does |
|---|---|---|
replayCooldown |
contract | The wait for this contract, in seconds. |
replayCooldown |
category | The wait for every contract in the category that does not set its own. |
ignoreContractCooldown |
category | When on, the category’s wait is used for every contract in it, regardless of their own. |
A category with ignoreContractCooldown on and a null replayCooldown cancels any cooldown,
whatever the contracts themselves say.
0 means no wait at all. The player claims the reward and can take the contract again right away.
The wait starts at completion, not at the claim. A player who finishes a contract and claims an hour later has already burned an hour of the wait. They do still have to claim (or abandon) the previous run before taking it again, so no reward is ever lost.
What players see
Section titled “What players see”While a contract cools down, the status chip on its card turns into a live countdown with a clock icon, It flips back to Available by itself when it hits zero. Open the contract and the details pane shows the Accept button greyed out with the time left under it.
Pausable contracts
Section titled “Pausable contracts”A player can pause an in-progress contract instead of dropping it. A paused contract keeps everything it had and gives up the active slot it was using, so the player can take something else without losing progress.
How many contracts a player can keep paused is set by Max Paused Contracts in the
permissions config.
- A paused contract has two buttons: Resume and Abandon. It tracks no progress, cannot be turned in, and its objective rewards cannot be claimed while it is paused. Its card chip reads PAUSED in gray, and pausing unpins the contract from the HUD.
- Resuming needs a free active slot. It runs the same checks as accepting a contract, both the global limit and the category one, so a player at their cap has to claim, drop or pause something else first.
- Abandoning a paused contract works like abandoning any other contract.
- When a rotation ends, paused contracts are wiped along with everything else.
- Objective cooldown and burst windows run on real time and keep counting while a contract is paused.
A contract paused for longer than the window comes back with a full cooldown again.
- This creates a small loophole where Playtime objectives with a cooldown can be paused while waiting for the cooldown to expire.
Purchasable contracts
Section titled “Purchasable contracts”A contract can ask the player to pay something to take it. This is ideal for high stakes contracts. It gives the player a reason to hurry and complete the contract before it expires, or risk losing their investment.
Cost types
Section titled “Cost types”| Type | What | Dependencies |
|---|---|---|
Item |
A quantity of a Rust item | Nothing |
Economics |
In-game currency | The Economics plugin |
ServerRewards |
RP | The ServerRewards plugin |
"costs": { "entry_fee": { "type": "Economics", "amount": 500 }, "entry_scrap": { "type": "Item", "item": "scrap", "quantity": 100, "skinId": null }}| Field | Type | Description |
|---|---|---|
type | string | Exactly 'Item' |
item | string | Rust item shortNames, lowercase dotted (e.g. rifle.ak, rifle.bolt, wood, stones, metal.fragments, scrap, hqm, lowgradefuel). |
quantity | integer (min 1) | How many of the item the player pays. |
skinId | integer | null (min 0) | Only items carrying this workshop skin ID count as payment. null accepts any skin. |
Economics
Section titled “Economics”| Field | Type | Description |
|---|---|---|
type | string | Exactly 'Economics' |
amount | number | How much Economics currency the player pays. May be a decimal. Greater than 0. |
Server Rewards
Section titled “Server Rewards”| Field | Type | Description |
|---|---|---|
type | string | Exactly 'ServerRewards' |
amount | integer (min 1) | How many Server Rewards points (RP) the player pays. |
What players see
Section titled “What players see”A contract with costs shows a price tag next to the reward icons on its card, and a Cost section in the details pane. Pressing Accept opens a confirm dialog instead of taking the contract right away. The dialog lists every cost, marks in red the ones the player cannot cover and by how much, and only lets them confirm when they can pay for all of it.
Nothing is ever paid back
Section titled “Nothing is ever paid back”Once the player confirms, the payment is gone. There is no case where Contracts hands it back. E.g.:
- Abandoning the contract
- A category rotation ending mid-contract.
- Closing or deleting the category.
- A server wipe.
That is by design: the buy-in is what earns the contract a reward that big, so it has to be a real risk.
Completing the contract does not refund the payment. Add it to the rewards if you want the player to get it back.
Skinned item costs
Section titled “Skinned item costs”An item cost with a skinId only counts items carrying that exact skin. This is how you build a
custom currency out of a skinned item. Leave skinId
as null for any skin counts.
