# Commands

Every admin command lives under one root: **`/truckeradmin`**.

Run `/truckeradmin help` in-game or in the txAdmin console for a quick reference.\
This document is the full version.

## Permissions

Each subcommand is ace-gated. Either grants access:

```cfg
add_ace group.admin command.trucker            allow   # everything
add_ace group.admin command.trucker.add        allow   # only /truckeradmin add ...
add_ace group.admin command.trucker.remove     allow   # only /truckeradmin remove ...
add_ace group.admin command.trucker.company     allow   # only /truckeradmin company ...
add_ace group.admin command.trucker.db         allow   # only /truckeradmin db ...
add_ace group.admin command.trucker.whoami     allow
```

Server console (`source = 0`, txAdmin Live Console) always passes the check.\
Commands that *must* be run from in-game chat (because they read your `source`) are marked **player-chat only** below.

## Quick reference

| Command                                          | Effect                                             |
| ------------------------------------------------ | -------------------------------------------------- |
| `/truckeradmin help`                             | print command list                                 |
| `/truckeradmin whoami`                           | dump identifier diagnostic for the caller          |
| `/truckeradmin add xp <id> <n>`                  | grant XP, auto-levels                              |
| `/truckeradmin add sp <id> <n>`                  | grant skill points                                 |
| `/truckeradmin add level <id> <n>`               | force-set driver level (sets exp to threshold)     |
| `/truckeradmin add deliveries personal <id> <n>` | log N synthetic completed runs to player history   |
| `/truckeradmin add deliveries company <id> <n>`  | bump player's company `total_deliveries`           |
| `/truckeradmin add earnings personal <id> <n>`   | log 1 synthetic run with `$n` payout               |
| `/truckeradmin add earnings company <id> <n>`    | bump player's company `total_earnings`             |
| `/truckeradmin add km <id> <n>`                  | bump player's company `total_km`                   |
| `/truckeradmin remove <field> ...`               | mirror of `add`, clamped at `0`                    |
| `/truckeradmin company create <name>`            | create a company; caller becomes the owner         |
| `/truckeradmin company disband <id>`             | dissolve the player's company (and notify members) |
| `/truckeradmin company weekly_reset`             | zero `weekly_deliveries` on every member           |
| `/truckeradmin db wipe confirm`                  | drop every koja-trucker table + recreate empty     |

`<id>` is always the FiveM **server id** (e.g. `1`, `42`) of the *target* player.\
`<n>` is always a positive integer.

## `/truckeradmin add ...`

Adds value to a player or their company.\
Every adjuster also pushes a fresh `getPlayerData` / company refresh to the affected tablet so the UI updates live without re-opening.

### `add xp <playerId> <amount>`

Personal XP. Recalculates level after every change:

* **Level up** for each `Config.Levels[level + 1]` threshold crossed; each level-up grants `+1` skill point.
* Used together with `remove xp` it level-downs symmetrically (rare but supported).

```
/truckeradmin add xp 1 250        → src 1 gets +250 XP, may level up
/truckeradmin remove xp 1 1000    → src 1 loses 1000 XP, may level down
```

### `add sp <playerId> <amount>`

Direct mutation of `skill_points`. Clamped at `0`.

```
/truckeradmin add sp 1 5
/truckeradmin remove sp 1 2
```

### `add level <playerId> <amount>`

Sets level to `current + amount` (or `current - amount` for `remove`).\
`exp` is reset to the threshold of the new level so progress bars don't look broken. Skill points are **not** retroactively granted by this command — use `add sp` separately if you intend to compensate.

```
/truckeradmin add level 1 3       → +3 levels, exp pinned to new threshold
/truckeradmin remove level 1 1
```

### `add deliveries <scope> <playerId> <amount>`

| Scope      | What it does                                                            |
| ---------- | ----------------------------------------------------------------------- |
| `personal` | Inserts `<amount>` synthetic completed history rows (vehicle = `admin`) |
| `company`  | Bumps `total_deliveries` on the player's current company                |

```
/truckeradmin add deliveries personal 1 3
/truckeradmin add deliveries company  1 10
```

> **`personal` cannot be removed** — history is append-only by design.\
> Use `/truckeradmin db wipe confirm` if you need a clean slate.

### `add earnings <scope> <playerId> <amount>`

| Scope      | What it does                                                     |
| ---------- | ---------------------------------------------------------------- |
| `personal` | Inserts **one** synthetic history row with `earnings = <amount>` |
| `company`  | Bumps `total_earnings` on the player's current company           |

```
/truckeradmin add earnings personal 1 5000     → $5000 in player's history
/truckeradmin add earnings company  1 50000    → $50k onto firm's books
```

> Same append-only caveat as `deliveries personal`.

### `add km <playerId> <amount>` (company only)

Bumps `total_km` on the player's current company. No personal km counter exists (the game doesn't track it per-player today).

```
/truckeradmin add km 1 250
/truckeradmin remove km 1 50
```

## `/truckeradmin remove ...`

Same fields as `add`. Every numeric stat is clamped at `0`. Personal deliveries/earnings cannot be removed (see notes above).

## `/truckeradmin company ...`

### `company create <name>` **player-chat only**

Creates a new company; the caller becomes its owner.

```
/truckeradmin company create Iron Wheel Logistics
```

Fails with `name_taken` if the name (or a previously-disbanded one) already exists — names are globally unique. Also fails if the caller is already in a company.

### `company disband <playerId>`

Dissolves the company that `<playerId>` belongs to. All members get the `Convoy disbanded`/`Company closed` toast, the row is marked `disbanded=1` in the DB, and every member's `KOJA.Server.PlayerCompany` entry is cleared.

```
/truckeradmin company disband 1
```

### `company weekly_reset`

Zeroes `weekly_deliveries` on every member of every company.\
Intended for a scheduled cron call once a week.

```
/truckeradmin company weekly_reset
```

## `/truckeradmin db wipe confirm`

:::hint{type="danger"}
**Destructive.** Drops every koja-trucker table (`koja-trucker`, `koja-trucker-companies`, `koja-trucker-company-*`, `koja-trucker-accounts`, `koja-trucker-shipment-history`), recreates them empty via `KOJA.Server.Schema.DDL`, then clears all in-memory state.
:::

The literal `confirm` argument is required — tab-completing to the bare `/truckeradmin db wipe` just prints a warning.

```
/truckeradmin db wipe             → prints warning, does nothing
/truckeradmin db wipe confirm     → wipes
```

Players already connected stay connected but their cached data is gone — the next `setAccount` push (triggered when they open the tablet) shows the register screen again.

## `/truckeradmin whoami` **player-chat only**

Prints a diagnostic line to the server console with:

* `src` — server id
* `in-game` — FiveM-reported name
* `display` — registered account display name (if any)
* `raw_id` — what `KojaLib.Server.GetPlayerIdentifier` returns
* `resolved_id` — what `KOJA.Server.GetIdentifier` returns (char-aware)

Plus a dump of every per-character field on the ESX `Player` object (`charId`, `characterId`, `PlayerData.citizenid`, …). Use the output to wire `Config.GetIdentifier` if your multichar plugin exposes a custom field.

The player also gets `resolved_id: <value>` echoed to their own chat.

## File map

| File                      | Owns                                                                      |
| ------------------------- | ------------------------------------------------------------------------- |
| `server/admin.lua`        | every `/truckeradmin …` subcommand + dispatch                             |
| `server/db/schema.lua`    | table DDL — exposes `KOJA.Server.Schema.DDL`                              |
| `server/skills.lua`       | skill-point math + `purchaseSkill` NUI callback                           |
| `server/company/core.lua` | `ResetWeeklyStats`, `Company.Create`, `Disband` (admin layer wraps these) |

To add a new subcommand, append a handler to the `SUBCOMMANDS` table in `server/admin.lua` and document it here.

## Related pages

- [Installation](/jobs/trucker/installation) — Make sure these are installed and started before Koja Trucker.
- [Features](/jobs/trucker/features) — Koja Trucker includes a full set of progression, social, and admin-driven systems.
- [Configuration](/jobs/trucker/configuration) — Almost everything is editable live from the in-game admin panel (no restart), and persisted to data/config.json. You can also edit that file directly.
- [Trucker](/jobs/trucker) — back to the section overview
