nqtr-ink

Exact captured content · path skills/ink/SKILL.md · sha256 86ac947e417b97ff… · revision 4b90054711c6a86f7f2a9eb2ae90428137bc20c1

Download the exact captured file

---
name: nqtr-ink
description: Use when writing .ink files in a Pixi'VN project that uses @drincs/nqtr — every NQTR hashtag command (# enter room, # set time, # set date, # wait, # add/remove activity, # add/remove routine, # start/continue quest) and the quest state variables (questId_started, _completed, _failed, _currentStageIndex), plus createNqtrHandler setup and options. Prefer this over TypeScript labels whenever ink is configured.
---

# NQTR in ink

Official docs: [pixi-vn.com/nqtr](https://pixi-vn.com/nqtr). Ink basics, Vite plugin and the generic hashtag-command mechanism: skill `pixi-vn-ink`. Entities referenced here (rooms, activities, commitments, quests) must already be defined and registered in TypeScript, see [nqtr](../getting-started/SKILL.md).

## When to use this skill

Use it for any `.ink` line that changes or reads NQTR state. If the project uses ink, write NQTR interactions here instead of in TypeScript labels.

## Setup

```ts
import { createNqtrHandler } from "@drincs/nqtr/ink";

createNqtrHandler(); // once, with the other ink initialization
```

`createNqtrHandler(options?)` registers all commands below plus the quest variable getter. Options: `timeConverter(time: string) => number` (default: `"01:30"` → `1.5`, i.e. replaces `:` with `.`), `dateConverter(date: string) => number` (default `Number`), `wait(delta)` (replace the default time/date increase), and `activityIds` / `commitmentIds` / `questIds` / `roomIds` (readonly id arrays, e.g. the `nqtr*Ids` generated by `vitePluginNqtr`, to validate ids). Without id arrays any string is accepted. `nqtrHandler()` is a deprecated alias.

## Commands

In the syntax below `<...>` is a placeholder, not ink interpolation.

| Command | Effect |
| --- | --- |
| `# enter room <roomId>` | `navigator.currentRoom = room`; location and map follow |
| `# set time <time>` | `timeTracker.currentTime`; accepts `18`, `18.30`, `18:30` |
| `# set date <date>` | `timeTracker.currentDate` |
| `# wait` | advance time by `timeTracker.defaultTimeSpent` |
| `# wait <time>` | advance time by that many hours (rolls over to the next date after `dayEndTime`) |
| `# wait days <n>` | advance `n` days, time reset to `dayStartTime` |
| `# wait days <n> hours <t>` | advance both |
| `# add activity <activityId> in <roomId>` | runtime link (saved with the game) |
| `# remove activity <activityId> from <roomId>` | unlink a runtime-linked activity |
| `# add routine <commitmentId> in <roomId>` | runtime-link a commitment (saved) |
| `# remove routine <commitmentId>` | remove a runtime-linked commitment |
| `# start quest <questId>` | `quest.start(props)` |
| `# continue quest <questId>` | `quest.continue(props)`, i.e. go to the next stage |

Unknown ids log a warning (`Room x not found`) and the command is skipped. Commands go on their own line or as a tag on a content line; follow the placement rules from `pixi-vn-ink-hashtag-commands`.

```ink
=== start ===
# enter room mc_room
# set time 08:00
# add activity order_product in mc_room
# start quest aliceQuest
mc: Let's begin.
# wait 2
# wait days 1 hours 8
-> DONE
```

## Quest variables

The handler also resolves read-only quest state in ink expressions, where `<id>` is the quest id:

| Variable | Type |
| --- | --- |
| `<id>_started` | boolean |
| `<id>_completed` | boolean |
| `<id>_failed` | boolean |
| `<id>_currentStageIndex` | number (0-based; `stages.length` once completed) |

```ink
=== talk_alice ===
{ aliceQuest_currentStageIndex:
- 0: -> talk_alice0
- 1: -> talk_alice1
- else: alice: Thanks for the book.
}
-> DONE

= talk_alice0
alice: Can you order me a book from the PC?
# continue quest aliceQuest
-> DONE
```

```ink
+ {aliceQuest_started && not aliceQuest_completed} Ask about the quest
```

Do not declare `VAR aliceQuest_started` in ink; the value comes from NQTR. Failing a quest has no hashtag command: set `quest.failed = true` in TypeScript (or from a custom hashtag command, see `pixi-vn-ink-hashtag-commands`).

## Not available from ink

Creating/registering entities, `timeTracker.initialize`, `navigator` queries beyond `enter room`, `quest.advanceIfCompleted`, hiding/disabling entities, `timeTracker.isWeekend`/`currentTimeSlot`. Do these in TypeScript, or expose them with a custom hashtag command / external function.

## Typical call from the UI into ink

Activities and commitments run `onRun(entity, props)` in TypeScript; to hand over to ink, jump to the knot: `await narration.jump("knot_name", props)` (ink knots are Pixi'VN labels). See [nqtr-activity](../activity/SKILL.md).