Skip to main content
cc_heistcontracts keeps every player’s VICE balance, XP, level, alias, and training progress in a dedicated heist_profiles table, cached in memory while the player is online and flushed periodically (and on drop) to MySQL. These exports are the supported way for other resources — admin menus, reward systems, custom commands — to read or change that state. All exports are server-side.
Profiles are loaded lazily on first access. The first export call for a given src blocks on a one-shot DB read; subsequent calls hit the cache.

Currency (VICE)

VICE is the soft currency earned from completing heists and spent in the marketplace. The balance is always a non-negative integer; deltas are floored.

AddVice

Credit VICE to the player and append a credit entry to their ledger.
local ok, newBalance = exports.cc_heistcontracts:AddVice(src, 500, 'pacific:vault_bonus')
src
number
required
Player server id.
amount
number
required
Positive integer. Non-integer values are floored; values ≤ 0 are rejected.
note
string
Free-form label written to the ledger. Use a stable identifier (e.g. 'pacific:vault_bonus') so the ledger reads cleanly in the dashboard.
Returns: ok (boolean), newBalance (number) on success. Returns false alone if the profile cannot be resolved or the amount is invalid.

RemoveVice

Debit VICE from the player. Fails (without mutating) if the balance is too low.
local ok, balance = exports.cc_heistcontracts:RemoveVice(src, 250, 'shop:mask_skull')
if not ok then
    -- balance is still the current (unchanged) balance
end
src
number
required
Player server id.
amount
number
required
Positive integer to debit.
note
string
Ledger label.
Returns: ok (boolean), balance (number). On insufficient funds, returns false, currentBalance.

GetVice

Read the current VICE balance.
local balance = exports.cc_heistcontracts:GetVice(src)
src
number
required
Player server id.
Returns: number, or nil if no profile could be resolved.

XP and level

Levels are derived from cumulative XP via the curve configured in shared/config.lua. AddXp rolls the player up as many levels as the new XP total covers — gaining a huge chunk of XP at once can level the player up multiple times in a single call.

AddXp

Grant XP to an online player. Level-ups are applied automatically.
local ok, level, xp = exports.cc_heistcontracts:AddXp(src, 1200)
src
number
required
Player server id.
amount
number
required
Positive integer. Floored; values ≤ 0 are rejected.
Returns: ok (boolean), level (number), xp (number) on success.

GrantXpByAlias

Grant XP to a player identified by their dashboard alias. Works whether the player is online (mutates the cached profile and lets the periodic flush persist it) or offline (updates the DB row directly).
local ok, info = exports.cc_heistcontracts:GrantXpByAlias('NightOwl', 500)
if ok then
    print(info.citizenid, info.levelBefore, info.levelAfter, info.xpAfter)
end
alias
string
required
Case-insensitive alias lookup.
amount
number
required
Positive integer.
Returns on success: true, info table:
info.src
number | nil
Server id if the player is online, nil if offline.
info.citizenid
string
Resolved citizenid for the alias.
info.levelBefore
number
Level prior to the grant.
info.levelAfter
number
Level after applying the grant.
info.xpAfter
number
XP total after the grant.
Returns on failure: false, errCode where errCode is one of 'invalid_amount', 'not_found', 'db'.

GetXp

Current XP total (cumulative, not level-relative).
local xp = exports.cc_heistcontracts:GetXp(src)
src
number
required
Player server id.
Returns: number, or nil if no profile could be resolved.

GetLevel

Current level.
local level = exports.cc_heistcontracts:GetLevel(src)
src
number
required
Player server id.
Returns: number, or nil if no profile could be resolved.

GetLevelProgress

Convenience accessor that returns everything you need to draw a progress ring or “X / Y to next level” label in one call.
local p = exports.cc_heistcontracts:GetLevelProgress(src)
-- p = { level = 7, xp = 4250, base = 3600, inLevel = 650, span = 1400 }
-- percent through current level = p.inLevel / p.span
src
number
required
Player server id.
Returns: a table, or nil if no profile could be resolved.
level
number
Current level.
xp
number
Current cumulative XP.
base
number
Cumulative XP at the start of the current level.
inLevel
number
XP accumulated within the current level (xp - base, clamped).
span
number
XP needed to fill the current level (nextLevelReq - base).

Identity

GetAlias

Read the player’s dashboard alias. Returns nil if the player has not yet chosen one (the dashboard prompts for an alias on first open).
local alias = exports.cc_heistcontracts:GetAlias(src)
src
number
required
Player server id.
Returns: string | nil.

Training

The training side of the dashboard is gated by two flags: an overall unlock, and a per-minigame unlock that controls which games appear in the training list. Both are persisted.

IsTrainingUnlocked

if exports.cc_heistcontracts:IsTrainingUnlocked(src) then
    -- player has access to the training panel
end
src
number
required
Player server id.
Returns: boolean.

HasTrainingMinigame

local owned = exports.cc_heistcontracts:HasTrainingMinigame(src, 'pattern')
src
number
required
Player server id.
id
string
required
Minigame identifier (matches the cc_minigames export name, lowercased — e.g. 'pattern', 'crack', 'lockpick').
Returns: boolean.

UnlockTraining

Idempotent: unlocks the overall training panel for the player.
exports.cc_heistcontracts:UnlockTraining(src)
src
number
required
Player server id.
Returns: booleantrue on success (including when already unlocked).

UnlockTrainingMinigame

Idempotent: unlocks a specific training minigame for the player.
exports.cc_heistcontracts:UnlockTrainingMinigame(src, 'crack')
src
number
required
Player server id.
id
string
required
Minigame identifier (see HasTrainingMinigame).
Returns: booleantrue on success (including when already unlocked).

Contract integration exports

Separate from the per-profile API above, cc_heistcontracts also exposes the integration surface used by heist resources themselves:
ExportPurpose
:RegisterContract(data, entry_point, opts?)Register a contract with the dashboard/marketplace. See Registering Contracts.
:StartContract(nameOrId, runtimeData)Legacy direct-start helper for old scripts.
:ApplyCooldown(contractId, locationId)Stamp a per-location cooldown.
:FinishContract(src, success)Mark a heist done for one player. Awards VICE+XP on success = true.
:FinishHeist(groupName, success)Convenience: finish for every member of a cc_lib.Groups group.
Use FinishContract / FinishHeist for normal heist completion — they already credit VICE and XP from the contract’s reward table. Reach for AddVice / AddXp only when you need to grant extra rewards outside the contract flow (e.g. one-off events, admin tools, side-objectives).