# In-game manuals

QMAW pages, item triggers and links.

QMAW is the in-game contextual manual. Hover an item in an inventory or recipe viewer and press the manual key (F1 by default). Native fluid entries in JEI and REI also offer their matching manuals. [until NTM 1.0.1: With Left Shift held, the key opens the item's presentation, when it has one, instead of its manual.][since NTM 1.0.1: With the Presentation modifier key (Left Shift by default) held, the key opens the item's presentation, when it has one, instead of its manual.]

Pages and triggers are **server datapack data**. The server sends its catalog on join and after `/reload`. Panel textures, item models and sounds are client resources.

See the [workshop manual example](https://movblock.mov/ntm-next/wiki/manuals/example.md) for a complete pack.

## Files, IDs and overrides

Put a page at `data/<namespace>/qmaw/<path>.json`. Its page ID is `<namespace>:<path>`.

- Add your own page with a new namespace/path.
- Replace an existing page by using its exact path in a higher-priority datapack. Overrides replace the entire record.
- The built-in copper page is `data/hbm/qmaw/material/copper.json`, with ID `hbm:material/copper`.

## Page fields

| Field | Meaning and default | Range |
| - | - | - |
| `name` | Case-sensitive nonblank link name in this page's namespace, without `:`. | |
| `icon` (Optional) | Native item ID or stack object, shown in the page header and before links to the page. | |
| `icon.id` | Item ID. | |
| `icon.count` (Optional) | Stack size; default 1. | `[1, 99]` |
| `icon.components` (Optional) | Item-component values. | |
| `title` | Nonempty locale-to-text map; every value must be nonblank. | |
| `title.<locale>` | Locale code such as en_us mapped to page text. | |
| `content` | Nonempty locale-to-text map; every value must be nonblank. | |
| `content.<locale>` | Locale code such as en_us mapped to page text. | |
| `trigger` (Optional) | Item-predicate object or list of OR alternatives; omitted or empty means link-only. | |
| `trigger.items` (Optional) | Item ID, item tag, or list of item IDs. | |
| `trigger.count` (Optional) | Exact count or min/max object; default unrestricted. | `[0, i32::MAX]` |
| `trigger.count.min` (Optional) | Minimum stack count when count is an object. | `[0, i32::MAX]` |
| `trigger.count.max` (Optional) | Maximum stack count when count is an object; at least count.min. | `[0, i32::MAX]` |
| `trigger.components` (Optional) | Exact item-component values. | |
| `trigger.predicates` (Optional) | Partial item-component predicates. | |
| `aliases` (Optional) | One nonblank namespace-local link name or list; default empty. | |
| `priority` (Optional) | Higher values win competing trigger matches; default 0. | `i32` |

Locale keys are lowercase, such as `en_us`, `ru_ru` and `zh_cn`. For title and body independently, the client selects its locale, falls back to `en_us`, then displays the missing-localization message. Provide `en_us` for fallback text.

A body can insert another page's body with `{{Page Name}}`. The name resolves within the current page's namespace; `{{namespace:page/path}}` addresses a page ID directly. Each inserted page selects its own translation for the client's locale, then its `en_us` body, then the inserted name. A missing page name displays as plain text without the braces. Composition cycles and nesting deeper than 100 pages fail when the page opens.

Names and aliases must be unique within a namespace. Pack priority resolves same-ID overrides before the uniqueness check.

## Item predicates and selection

Each trigger uses the vanilla item-predicate fields `items`, `count`, `components` and `predicates`:

```json
{
  "items": ["minecraft:paper", "minecraft:book"],
  "count": {"min": 2, "max": 16}
}
```

- `items` accepts one item ID, one `#tag`, or a list of item IDs. Use a standalone `#tag` for tag matching.
- `count` accepts an exact nonnegative integer or an object with optional `min`/`max`. Bounds must be exact nonnegative integers and `min` cannot exceed `max`. Omitted count, or `{}`, leaves the count unrestricted.
- `components` matches exact component values. `predicates` uses registered partial component predicates. Their component payloads retain their own native codecs; see [Ingredients and Components](https://movblock.mov/ntm-next/wiki/ingredients-and-components.md).
- A deliberately empty predicate `{}` matches every nonempty stack.

Highest `priority` wins. At the same priority, a matching trigger with `components` or `predicates` precedes an item-only match. Remaining ties use lexical page ID order.

Native fluid help queries the same predicates using that fluid's `hbm:fluid_icon` representation. To match a fluid regardless of quantity, pressure or display tint:

```json
{
  "items": "hbm:fluid_icon",
  "predicates": {"hbm:fluid_content": "hbm:oil"}
}
```

This predicate matches fluid type. The built-in oil pages use this form; matching a foreign fluid requires an explicit predicate.

## Text and links

`<br>` starts a line; use `<br><br>` for a paragraph break. Text wraps to the panel width, including long words and CJK text.

| Syntax | Resolution | |
| - | - | - |
| `[[Workshop Notes]]` | Name/alias in the current page's namespace. | |
| \`\[\[Read the notes | Workshop Help]]\` | Display label on the left, namespace-local name/alias on the right. |
| \`\[\[Copper | hbm:material/copper]]\` | Explicit page ID; works across namespaces. |

A target containing `:` is a page ID. Names and aliases are case-sensitive. Unresolved targets appear red and remain non-clickable.

## Reloads and rejected data

On successful `/reload`, connected clients receive a new catalog. An open page updates its text and title, removes invalid history entries, and closes if its page ID has disappeared. Disconnect clears the received catalog.

Schema errors identify the resource file; duplicate cross-page names identify both IDs.
