> For the complete documentation index, see [llms.txt](https://docs.tworst.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tworst.com/scripts/builder-job/interface.md).

# Interface

The job ships four separate UIs. Two are for players, two are for admins.

| UI                      | Opened with                                        | Who      |
| ----------------------- | -------------------------------------------------- | -------- |
| **Job Menu**            | The HQ NPC                                         | Everyone |
| **Sync & Keys panel**   | `/builderjobsettings`, or `/keys` for the Keys tab | Everyone |
| **Admin Panel**         | `/builderadmin`                                    | Admins   |
| **Site & Zone Builder** | `/tw_bp`                                           | Admins   |

***

## Job Menu

The main menu, opened by talking to the NPC at the company HQ. It has four pages down the side:

| Page            | What's on it                                                                                                           |
| --------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Home**        | Region list with reward, level requirement and crew size; expand a region for its details, then create or join a lobby |
| **Leaderboard** | Top earners and most jobs completed — sortable by money or job count                                                   |
| **Training**    | The practice field: pick a machine module, work through the steps, finish with a medal                                 |
| **Settings**    | Language, sound volumes, UI Move, daily missions and your job history                                                  |

Alongside the menu, these panels appear during a job:

* **Team panel** — crew members, live score per player, and the reward split control for the owner
* **Task list** — current objective and progress; hold **K** for the detailed breakdown
* **Daily mission** — the rotating task and its progress
* **Invite prompt** — accept with **Y**, decline with **N** (`Config.Keys`)
* **Finish screen** — what the job paid, per member, with the rank bonus broken out

{% hint style="info" %}
Every one of these panels can be repositioned by the player from **Settings → UI Move**, and their layout is saved per player. `Config.DefaultUIPositions` only sets the starting point.
{% endhint %}

{% hint style="success" %}
**Language is picked here, per player.** All 12 shipped languages appear in the Settings page selector; `Config.Locale` only sets what a player sees before they choose. Adding a `locales/<code>.lua` file makes it show up in this list automatically.
{% endhint %}

***

## Sync & Keys Panel — `/builderjobsettings`

A separate two-tab panel — **not** the Settings page inside the job menu. Player-facing, always available.

### Sync tab — "Sync Quality"

This is where a player trades visual detail for frames. It is the single most useful page for anyone on a weaker PC.

**Quality preset** — one of `Performance`, `Balanced`, `High`, `Ultra`.

**Detail level** — `Low`, `Medium`, `High`, plus two special modes:

| Mode             | What it does                                                       |
| ---------------- | ------------------------------------------------------------------ |
| ⚡ **Auto**       | Measures the player's FPS and suggests/applies the level that fits |
| 🎬 **Cinematic** | Forces everything on regardless of the toggles — for video capture |

Changing any individual toggle drops the level to **Custom** automatically.

**Individual toggles** — each one shows its own cost hint in the UI:

| Toggle                    | What turning it off does                                                                           |
| ------------------------- | -------------------------------------------------------------------------------------------------- |
| Hook ground marker        | Removes the target circle and ground scan under the hook                                           |
| Sling ropes               | Hides the ropes tying the load to the hook                                                         |
| Hydraulic animation       | Your own crane's cylinders freeze                                                                  |
| Rope sway                 | Rope hangs straight instead of swinging — **visual only**, the physics still run for the broadcast |
| Machine sounds            | Mutes engine / hydraulic / winch loops                                                             |
| Mirrored hydraulics       | Stops animating cylinders on *other people's* machines                                             |
| Pump hydraulics           | Stops the pump's 26 cylinders — the heaviest single item while pouring                             |
| Particle effects          | No concrete pour or dust particles (GPU-heavy on weak cards)                                       |
| Green outlines            | No highlight on piles and slots — **you need this to see what you can grab**                       |
| 3D \[E] badge on the load | The hint moves into the crane HUD as a text line instead                                           |
| Boom-vs-truck guard       | Drops the per-frame box test; the boom may clip through the truck bed                              |

**Numeric controls:**

| Control                    | Meaning                                                                                              |
| -------------------------- | ---------------------------------------------------------------------------------------------------- |
| Machines animating at once | `0` = all. On a crowded site the machines beyond this count freeze until you get close.              |
| Own crane render rate      | Every frame / 30 Hz / 20 Hz — **your screen only**; everyone else still sees your crane at full rate |

{% hint style="success" %}
These are **client-side preferences**, saved per player with KVP. They never change what other players see and they never change gameplay — a player on Low earns exactly what a player on Ultra earns.
{% endhint %}

### Keys tab — "Key Bindings"

Every machine key, rebindable in-game. The bindings are grouped into pages that match `config/keybinds.lua`:

| Page              | Covers                                                   |
| ----------------- | -------------------------------------------------------- |
| **General**       | Interact, cabin, hook, carry, task list                  |
| **Mobile Crane**  | Slew, boom, telescope, knuckle, winch, precision, camera |
| **Concrete Pump** | Boom sections, outriggers, hopper, pour                  |
| **Tower Crane**   | Slew, trolley, hook, cabin camera                        |

Click a row, press the new key, done. A **Reset** button restores the defaults for the page. `/keys` opens this tab directly.

{% hint style="info" %}
`config/keybinds.lua` sets the **defaults**. Anything a player rebinds here is stored on their own client and wins over the config.
{% endhint %}

***

## Admin Panel — `/builderadmin`

Opened with `Config.AdminPanel.command` (default `builderadmin`). Access is checked **server-side** against `Config.Admins` before any data is sent — a non-admin gets a refusal, not an empty panel.

### Summary cards

Across the top: **Online** (and how many lobbies), **Today** (money + jobs), **This week**, **All time**, and **Workers** (players with at least one finished job).

### Tabs

| Tab         | What you get                                                                                                                  |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Lobbies** | Every active lobby — owner, members, region, task progress, elapsed time                                                      |
| **Players** | Top earners by money and jobs, with a search box for name or identifier; click a row for that player's detail and job history |
| **Regions** | Per-region usage — how often each one is started, drawn as a comparative bar                                                  |
| **Logs**    | The in-game event log, filtered by category chips                                                                             |

### Actions

The panel is **not** read-only. Two write actions are available, each behind a click-twice "Sure?" confirmation:

| Action         | Where       | What it does                                                                  |
| -------------- | ----------- | ----------------------------------------------------------------------------- |
| **Force end**  | Lobbies tab | Ends a stuck lobby and runs the cleanup path for it                           |
| **Reset site** | Regions tab | Resets a loaded region's scene — use it when a site is left in a broken state |

{% hint style="warning" %}
Both actions are re-checked against `Config.Admins` on the server when they run, not just when the panel opens. Every use is written to the `admin` log category.
{% endhint %}

### Logs

Category chips filter the stream: `All`, `Job start`, `Job finish`, `Lobby`, `Economy`, `Admin`, `Security`, `Error`. A chip shows a dot when that category has a Discord webhook wired up.

{% hint style="info" %}
The log page reads the event stream from **server memory**, so it works whether or not you have configured any Discord webhook. It needs `Config.Discord.panelLog = true`; `Config.Discord.panelKeep` sets how many entries are held (default 300).
{% endhint %}

Dashboard data is cached for `Config.AdminPanel.cacheSeconds` (default 60). `topLimit` caps the player list, `scanLimit` caps how many players are scanned for the statistics, and `stuckMinutes` decides when a lobby is flagged as stuck.

***

## Site & Zone Builder — `/tw_bp`

The in-game tool for placing build sites and managing their zones — this is how you add a new build location without editing coordinates by hand. Gated by `Config.Admins`; run `/cranesiteid` to print your own identifier if you need to add yourself.

### Placement

`/tw_bp go [design]` spawns a ghost of the design and puts you in placement mode. There are three camera modes:

| Mode         | Controls                                                                                        |
| ------------ | ----------------------------------------------------------------------------------------------- |
| **Walk**     | `WASD` walk · `◄ ►` rotate · `↑ ↓` height · `SPACE` camera                                      |
| **Orbit**    | Mouse orbit · Wheel zoom · `WASD` move house · `◄ ►` rotate · `↑ ↓` height · `G` snap to ground |
| **Free cam** | Mouse look · `WASD` fly · `F` bring house to cursor · `◄ ►` rotate · `V` back to orbit          |

`TAB` opens the panel, `ENTER` confirms, `⌫` cancels. `Q`/`E` cycle between designs while roaming.

A step rail across the top tracks you through **Design → Position → Checks → Save**, and live checks warn about bad ground, a missing zone, or being too close to another site *before* you save.

### Panel tabs

| Tab         | What it's for                                                                                                                                         |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Sites**   | Every build site. Rows are badged `CONFIG` (from `config/jobs/*.lua`) or `JSON` (from `plank_sites.json`). Config sites are read-only from the panel. |
| **Zones**   | The sync/watcher area of each site — polygon point count, radius, centre, distance, and which sites use it. Show in world, set a waypoint, or delete. |
| **Designs** | The house/structure catalogue you place from, with filters and in-game reference photos                                                               |
| **Health**  | The validation report                                                                                                                                 |

### Zones — why they matter

{% hint style="danger" %}
A site with **no zone dies silently** — the scene is never built, with no error. And if **two sites land in the same zone**, the server can resolve to the wrong one and swallow the sync request.

Zones are generated automatically when you save a site, so in normal use this takes care of itself. The Zones tab is there to catch the cases where it hasn't.
{% endhint %}

Only `JSON` zones with no sites using them can be deleted from the panel; zones defined in config are protected.

### Health tab

Runs the same checks as `server/core/config_validator.lua` — one source of truth, not a second copy:

| Icon | Meaning                                     |
| ---- | ------------------------------------------- |
| ✕    | The job would break silently                |
| !    | Visual or logic risk                        |
| ⏳    | Saved to file, but not live in this session |

{% hint style="warning" %}
**Saved changes need a restart.** A site or zone you save is written to JSON, but it only goes live after `restart tw-builderjob` — `files{}` is handed to the client when the resource starts. That is what the ⏳ marker is telling you.
{% endhint %}
