Documentation Index
Fetch the complete documentation index at: https://docs.cc-scripts.com/llms.txt
Use this file to discover all available pages before exploring further.
cc_lib.TaskUI is the on-screen task list that every CC Scripts heist uses to show its objectives. Lists are owned server-side: state lives on the server, viewers (players) subscribe via Show, and updates broadcast to every viewer.
Create only allocates the list and starts its master timer. Players don’t see anything until Show adds them as viewers.
Concepts
Server-owned state
Every list and every objective lives on the server. Clients only receive deltas. On respawn the client requests a full re-sync automatically.
One active task
The list renders the first non-
complete objective as the active task. Counter chips and timer chips are only visible on the active task — they’re hidden on pending/complete/failed tasks even if their underlying value is non-null.Per-task chips
Each task can carry a counter (
{ current, total }) and/or a timer ({ timeLeft }). Both render as small chips next to the task text. Counters and timers are independent — a task can have one, both, or neither.Boundaries are caller-defined
Expiry callbacks fire but don’t auto-fail the task. Status, counter, and timer are all orthogonal — what they mean for the heist’s flow is up to you.
Lifecycle
Create accepts:
| Field | Type | Default | Notes |
|---|---|---|---|
title | string | '' | Header text. |
description | string | '' | One-line description under the header. |
position | 'left' | 'right' | 'right' | Which corner the list anchors to. |
maxTime | number (seconds) | 0 | If > 0, starts a 1 Hz master countdown. 0 means no master timer. |
objectives | Objective[] | {} | Initial task list. See Objective shape. |
id | string | auto | Optional fixed id. If a list with this id exists it’s destroyed first. |
onTimerEnd | function(id) | — | Fires once when maxTime hits 0. |
onTaskTimerEnd | function(id, taskId) | — | Fires when any per-task timer hits 0. |
onComplete | function(id) | — | Fires once when every objective has status == 'complete'. |
Objective shape
status is rarely set on the initial list — it defaults to pending and the renderer promotes the first pending one to active automatically.
Master timer
The list-level countdown drawn in the header.| Function | What it does |
|---|---|
cc.TaskUI.SetTime(id, seconds) | Set the master timer to a specific value. |
cc.TaskUI.AddTime(id, seconds) | Add seconds. Flashes a +Ns bubble next to the chip. |
cc.TaskUI.DeductTime(id, seconds) | Subtract seconds. Flashes a -Ns bubble. Floors at 0. |
cc.TaskUI.GetTime(id) | Returns the current remaining seconds. |
onTimerEnd callback fires once and the timer stops — the list itself remains until you Destroy it.
Task status
'complete' on the last remaining objective triggers onComplete once.
Counter chip
A small numeric badge next to a task. Useful for “hack 4 computers” or “grab 6 bags” objectives.current <= 0, regardless of total. Pair with SetStatus(id, taskId, 'complete') to advance to the next task.
Per-task timer chip
AMM:SS countdown badge next to a task. The chip styling matches the counter chip — neutral background, no traffic-light coloring — so timers and counters sit side by side cleanly.
A per-task timer is only visible while its task is the active one, the same way the counter chip is gated. The server ticks it regardless, so start the timer at the moment the task becomes active if you want the player to see the full countdown.
API
0 or a negative number to SetTaskTimer is treated as a clear and behaves like ClearTaskTimer. Calling SetTaskTimer while a timer is already running atomically replaces it — the previous ticker thread exits via a generation token.
Expiry behavior
When the chip ticks down to0:
- The chip disappears (broadcast as
timer = nil). onTaskTimerEnd(listId, taskId)fires once on the server.- The task’s
statusis not auto-changed. Decide what expiry means in the callback.
Worked example: time-pressured vault
A vault objective where the player has 25 seconds from the moment the task becomes active. Late = fail.SetTaskTimer is called, ticks down at 1 Hz, and vanishes either on ClearTaskTimer or on its own expiry (which also fires onTaskTimerEnd).
Dynamic objectives
AddTask appends a new objective at runtime — useful for bonus/side objectives that only appear if the player triggers them. The new objective can carry an initial counter and/or timer.
RemoveTask — once added, a task is part of the list until the list is destroyed. Mark it complete or failed to neutralize it.
API reference
List
| Function | Returns | Notes |
|---|---|---|
Create(data) | string (list id) | See the section above. |
Show(id, src) | boolean | Adds a viewer; sends them the full state. |
Hide(id, src) | boolean | Removes a viewer. List stays alive. |
GetViewers(id) | number[] | Server ids currently subscribed. |
Exists(id) | boolean | |
Destroy(id) | boolean | Tears down for every viewer. |
Tasks
| Function | Returns |
|---|---|
AddTask(id, task) | boolean |
SetStatus(id, taskId, status) | boolean |
Counter chip
| Function | Returns |
|---|---|
SetCounter(id, taskId, current, total) | boolean |
IncrementCounter(id, taskId, delta) | boolean |
Master timer
| Function | Returns |
|---|---|
SetTime(id, seconds) | number (new value) |
AddTime(id, seconds) | number |
DeductTime(id, seconds) | number |
GetTime(id) | number | nil |
Per-task timer
| Function | Returns |
|---|---|
SetTaskTimer(id, taskId, seconds) | boolean |
ClearTaskTimer(id, taskId) | boolean |
AddTaskTime(id, taskId, seconds) | number | boolean |
DeductTaskTime(id, taskId, seconds) | number | boolean |
GetTaskTime(id, taskId) | number | nil |
exports.cc_lib:TaskUI_<Name>(...) — for example exports.cc_lib:TaskUI_SetTaskTimer(id, taskId, 25). Prefer the GetLib() form for readability; use the export form when you need to invoke from a context where holding a reference to cc.TaskUI is awkward.
Player keybind
The TaskUI registers+taskui_toggle (default key K) on every client — pressing it collapses/expands every list that player can see. The keybind is registered automatically by cc_lib; you don’t need to wire anything up.