> 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/getting-started-installation/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 14 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.

{% hint style="success" %}
**New in v1.0.1 — the tool warns about zone conflicts before you save**, so the "two sites in one zone" case above is caught at save time rather than discovered in the field.
{% endhint %}

### Disabling a single site

Also new in v1.0.1: individual construction sites can be switched off from `/tw_bp` without removing the region they belong to. Use it when one location clashes with something on your map but the rest of the region is fine.

Crews can also be assigned to a **random available site**, which spreads them out instead of piling every crew onto the same location.

### 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 %}
