> For the complete documentation index, see [llms.txt](https://buildsystem.eintosti.de/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://buildsystem.eintosti.de/v4/getting-started/custom-statuses-and-categories.md).

# Custom Statuses & Categories

In BuildSystem 4.0, world statuses and navigator categories are dynamic registries configured via `/setup` or configuration files.

***

## 1. Core Concepts

### 1.1 Custom World Statuses (`BuildWorldStatus`)

Statuses define progress state and behavior. Each status object contains the following properties:

| Property            | Description                                                                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `id`                | Unique lower-case key (e.g., `in_progress`). Persisted in configuration files.                                         |
| `displayName`       | Display name in menus and chat. Supports standard color codes.                                                         |
| `color`             | Color prefix applied to the status.                                                                                    |
| `icon`              | `XMaterial` shown in selection menus.                                                                                  |
| `order`             | Sorting weight (lower numbers appear first in lists).                                                                  |
| `permission`        | **Dynamic Permission**: Node required to assign this status (see below).                                               |
| `buildingAllowed`   | Set `false` to block block place/break changes in carrying worlds.                                                     |
| `progressesTo`      | Optional status ID target for auto-progression on first block edit.                                                    |
| `statusSlot`        | Slot (0-26) the status occupies in the `/worlds setStatus` picker, set in the status editor.                           |
| `shownInStatusMenu` | Whether the status appears in the picker. Hidden statuses wait in the editor's palette.                                |
| `builtIn`           | Identifies seeded default statuses. Built-ins can be edited or deleted; the flag controls default re-seeding on reset. |

#### Dynamic Status Permissions

To change a world's status, a player requires a dynamic permission node derived from the status id:

* **Built-in statuses** keep their legacy node with underscores removed — e.g. `in_progress` → `buildsystem.setstatus.inprogress`.
* **Custom statuses** use their full id — e.g. `my_status` → `buildsystem.setstatus.my_status`.

This keeps existing permission setups working while guaranteeing two custom statuses can never collapse onto the same node.

#### Universal Archive Bypass

A single bypass node covers all statuses where `buildingAllowed` is `false`: `buildsystem.bypass.archive`

***

### 1.2 World Visibility (`Visibility`)

* **`EVERYONE`**: Public worlds visible to all players.
* **`ADDED_PLAYERS`**: Restricted worlds visible only to the creator and whitelisted builders.

***

### 1.3 Navigator Categories (`NavigatorCategory`)

Categories define navigator menu tabs. They group worlds by visibility and status.

| Property           | Description                                                                                                              |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `id`               | Unique lower-case key (e.g., `public`). Referenced by folders and layouts.                                               |
| `displayName`      | Title shown on the navigator tab item.                                                                                   |
| `color` / `icon`   | Styling in menus.                                                                                                        |
| `visibilities`     | Allowed visibilities grouped (`EVERYONE`, `ADDED_PLAYERS`, or both).                                                     |
| `statusIds`        | List of status IDs grouped in this category.                                                                             |
| `shownInNavigator` | Set `true` to render this category as a tab in the `/worlds` menu.                                                       |
| `navigatorSlot`    | Tab position (0-26) in the navigator GUI.                                                                                |
| `builtIn`          | Identifies seeded default categories. Built-ins can be edited or deleted; the flag controls default re-seeding on reset. |

#### Per-Category Commands & Visibility

Every category gets a `/worlds <id>` command shortcut that opens its tab, generated from the navigator — so creating a category adds its command and deleting one removes it. The dynamic permission `buildsystem.navigator.<categoryId>` controls both the shortcut and whether the tab shows in the navigator. It is granted by default, so denying it hides a category *and* disables its command together. If a category id matches a real subcommand (e.g. `delete`), the subcommand always wins the name and the shortcut is dropped.

***

## 2. Default Configurations

Built-in statuses and categories seeded on first plugin boot:

### Built-in Statuses (`statuses.yml`)

| ID                | Display Name    | Color             | Icon         | Order | Block Modify | Auto-Progress |
| ----------------- | --------------- | ----------------- | ------------ | ----- | ------------ | ------------- |
| `not_started`     | Not Started     | `&c` (Red)        | `RED_DYE`    | 1     | Allowed      | `in_progress` |
| `in_progress`     | In Progress     | `&6` (Gold)       | `ORANGE_DYE` | 2     | Allowed      | —             |
| `almost_finished` | Almost Finished | `&a` (Green)      | `LIME_DYE`   | 3     | Allowed      | —             |
| `finished`        | Finished        | `&2` (Dark Green) | `GREEN_DYE`  | 4     | Allowed      | —             |
| `archive`         | Archive         | `&3` (Aqua)       | `CYAN_DYE`   | 5     | **Blocked**  | —             |
| `hidden`          | Hidden          | `&7` (Gray)       | `BONE_MEAL`  | 6     | Allowed      | —             |

A status is shown in the navigator purely through category membership — there is no per-status visibility flag. The built-in `hidden` status stays out of the navigator simply because no built-in category lists it (see [§3](#3-world-to-category-mapping-logic)).

### Built-in Categories (`categories.yml`)

| ID        | Display Name | Color | Icon          | Visibilities                | Grouped Statuses                                            | Slot |
| --------- | ------------ | ----- | ------------- | --------------------------- | ----------------------------------------------------------- | ---- |
| `public`  | Worlds       | `&b`  | `PLAYER_HEAD` | `EVERYONE`                  | `not_started`, `in_progress`, `almost_finished`, `finished` | 11   |
| `archive` | Archive      | `&3`  | `PLAYER_HEAD` | `EVERYONE`, `ADDED_PLAYERS` | `archive`                                                   | 12   |
| `private` | Private      | `&a`  | `PLAYER_HEAD` | `ADDED_PLAYERS`             | `not_started`, `in_progress`, `almost_finished`, `finished` | 13   |

{% hint style="info" %}
`public` is the default category and `not_started` is the default status. The last remaining **status** can't be deleted, so a world always has a valid status to fall back to. **Categories** have no such guard — you can delete every one, leaving the navigator empty until you reset to defaults.
{% endhint %}

***

## 3. World-to-Category Mapping Logic

When the `/worlds` navigator renders, it filters and groups worlds dynamically:

* **Inclusive Membership**: A world is grouped by a category if its visibility and status ID are listed. A world appears in every category that groups it. If tabs overlap, the world is listed under all matching categories simultaneously.
* **Primary Category**: If a world must resolve to a single category (e.g. choosing which folder a new world is saved under by default), the plugin assigns the first matching category based on the navigator slot layout, or falls back to the default `public` category.

If a world's status is not listed in any category, it is excluded from navigator listings. This is exactly how the built-in `hidden` status works — no category groups it, so worlds set to `hidden` never appear in the navigator.

***

## 4. Custom Skull Textures & %viewer%

Categories, worlds, and folders support custom player head skin textures when their icon material is set to `PLAYER_HEAD`.

* **Viewer's Head (`%viewer%`)**: Renders the head of the player viewing the menu.
* **Custom Skins**: Renders specified base64 skin textures, UUIDs, or usernames.
* **Default Fallbacks**: If blank or absent, heads resolve asynchronously:
  * **Private Worlds**: Renders the world creator's skin.
  * **Public Worlds**: Renders a head matching the world's folder name.
  * **Categories**: Renders the viewer's head for private groupings, or a standard navigator skin for public tabs.

***

## 5. Deleting & Resetting Safeguards

* **Deleting a Status**: Drop it onto the delete target in the status editor. Worlds carrying it are reassigned to the default status (`not_started`), and the id is pruned from every category's status list. The last remaining status can't be deleted.
* **Deleting a Category**: Drop it onto the delete target (textured skull) in the navigator editor. Because statuses are shared, worlds re-route to another matching tab (or the default) on the next render, and folders pinned to the category are re-homed to the default. Any category can be deleted, including the last — the navigator then stays empty until you reset to defaults.
* **Resetting to Defaults**: Each layout editor has a reset control. **Left-click** resets only the layout (built-in entries return to their default slots; custom entries are kept but removed from the menu). **Right-click** resets everything, restoring any deleted built-in statuses or categories. Deleting `statuses.yml` and `categories.yml` and restarting achieves the same full reset.

***

## 6. The In-Game Setup Menu (`/setup`)

Administrators with `buildsystem.setup` permission can edit registries directly in-game. The hub branches into three configuration panels:

### 6.1 Default World Icons

Sets default item representation used for Normal, Flat, Nether, End, or Void worlds upon creation. Features a reset control.

![Setup GUI Hub](/files/ea5ZpGvaLtxfV7YQ9Gk2)

### 6.2 World Statuses

The status editor is the drag-and-drop counterpart of the **Navigator Layout Editor** (§6.3): the top inventory is a live preview of the `/worlds setStatus` picker, and your own inventory holds the controls plus a palette of statuses not currently in the picker. This is where the picker's appearance is configured.

* **Arrange**: Pick a status up from the preview or palette and drop it onto a slot to place it; drop it outside the preview to take it out of the picker.
* **Create / Edit / Delete**: Click the create button to name a new status, shift-click a status to open its property editor, or drop a status onto the delete target to remove it.
* **Property editor**: Name, color (dye picker), icon (item picker), order, the `buildingAllowed` toggle, and the auto-progression target a world advances to on first edit. Toggle items show their state in the lore (e.g. `Currently: Enabled/Disabled`) and glint when active.

### 6.3 Navigator Layout Editor (Drag & Drop)

Handles positioning, tab properties, category creation, and deletion in a single screen. The top inventory displays a live 27-slot preview of the navigator.

* **Category Creation & Edits**: Click the create category button (textured skull) to register a new category. Right-click any category to open its property editor (name, color picker, skull textures, grouped visibilities, member statuses listed in order, and slot).
* **Inventory snapshotting**: Player inventories are snapshotted and cleared, then replaced with menu controls (available categories, back button, delete category skull, and layout pins). Real inventories are restored when the GUI closes, the player disconnects, or the server stops.
* **Drag-and-Drop Placement**: Click a category in the palette to pick it up, and click a preview slot above to place it. While held on the cursor, the category previews as a design-color glass pane. Dropping a category outside the preview removes it from the layout (returns it to the palette). Clicking is cancelled, protecting control items.
* **Settings Button**: The settings gear button is part of the layout. It can be moved, dropped outside to remove it from the navigator, or re-added from the palette. A settings slot value of `-1` hides it.

![Navigator Layout Editor](/files/dwm4hkiDviD11i0R9tfU)

***

## 7. Shared GUI Components

The `/setup` editors share the following GUI components:

* **16-Color Dye Picker**: Opens a panel of dye swatches sorted by color family, corresponding 1:1 to legacy chat codes. Selection carries an enchant glint. Click "Back" to return to the editor.

  ![Color Picker Panel](/files/TeKckkGAiWulx3WPOYHA)
* **Item Picker Grid**: Displays every obtainable Minecraft item. The left 8 columns show items, and the 9th column houses scrolling navigation arrows (scrolls one row at a time). The name filter searches both raw material keys (e.g. `minecraft:stone`) and display names. Item names in the grid are colorized.
* **Player Head Customizer**: Right-click the icon control item to input a base64 texture, `viewer`, or `none`.
