nqtr-routine

Exact captured content · path skills/routine/SKILL.md · sha256 41afcaf9e5a15d85… · revision 4b90054711c6a86f7f2a9eb2ae90428137bc20c1

Download the exact captured file

---
name: nqtr-routine
description: Use when scheduling NQTR character routines — CommitmentBaseModel (where a character is at a given time), RegisteredCommitments, timeSlot/dateScheduling/priority/executionType, linking at init (routine in the room constructor) vs runtime (room.addCommitment / "# add routine X in room"), removing with routine.remove / "# remove routine X", and custom Commitment classes.
---

# NQTR routine (commitments)

Official docs: [pixi-vn.com/nqtr/routine](https://pixi-vn.com/nqtr/routine). Index: [nqtr](../getting-started/SKILL.md). Ink commands: [nqtr-ink](../ink/SKILL.md).

A **commitment** says that a character is busy in a room during a time slot. The routine is the set of commitments active now; it decides which characters are in the current room and what happens when the player interacts with them.

## Initialize

`new CommitmentBaseModel(id, character | characters | undefined, props)`, then `RegisteredCommitments.add(...)` (**required**). `character` is a character id/instance, or an array.

```ts title="content/routine.ts"
import { CommitmentBaseModel, RegisteredCommitments } from "@drincs/nqtr";
import { narration } from "@drincs/pixi-vn";

export const aliceSleep = new CommitmentBaseModel("alice_sleep", "alice", {
    priority: 1,
    timeSlot: { from: 20, to: 10 }, // wraps over midnight
    onRun: async (_, props) => {
        await props.navigate({ to: "/game/narration" });
        await narration.jump("talk_alice_sleep", props);
    },
});

RegisteredCommitments.add(aliceSleep);
```

`CommitmentProps`: `name`, `timeSlot`, `dateScheduling`, `image`, `icon`, `onRun`, `disabled`/`hidden` (boolean or flag name), `priority` (default 0), `executionType`.

- `executionType: "interaction"` (default): `onRun` runs when the player interacts with the character. `"automatic"`: `onRun` runs automatically when the player enters the room — remove the commitment when no longer needed or it repeats every time.
- A disabled commitment is ignored, so the character is not in the room but free for other commitments.
- A character cannot be in two places: among valid simultaneous commitments of the same character the highest `priority` wins; by default runtime-added commitments beat init-time ones.

## Link (one commitment → one room)

1. **At initialization** — `routine: ["alice_sleep"]` in the `RoomBaseModel` constructor. Not saved.
2. **During the game** — saved with the game.

```ink
# add routine alice_smokes in terrace
```

```ts
terrace.addCommitment("alice_smokes");
```

## Unlink

Init-time links cannot be removed: add a higher-priority commitment for the same character and time slot instead. Runtime links:

```ink
# remove routine alice_smokes
```

```ts
import { routine } from "@drincs/nqtr";
routine.remove("alice_smokes");       // optional second argument: roomId
```

## Query

`RegisteredCommitments.get(id)` / `.values()`. `routine.currentRoutine` (active commitments), `routine.roomCommitments[roomId]`, `routine.characterCommitments[characterId]`, `routine.getCommitmentByCharacter(...)`, `routine.clearExpiredRoutine()`.

## Custom class

Extend `CommitmentStoredClass` (`super(id, characters, props.onRun, props)`), implement `CommitmentInterface`, augment it in `nqtr.d.ts` (`name`, `sprite?`, `background?`, `icon?`, `disabled`, `hidden`). Persist `disabled`/`hidden` with `getStorageProperty`/`setStorageProperty`, override `isActive` (false when hidden) and `run` (invalidate UI afterwards), like the templates.

## Pitfalls

- Commitments depend on [time](../time/SKILL.md): nothing changes until time advances (`# wait`).
- Forgetting `RegisteredCommitments.add` or the character not being registered.