Routine
Initialize
To initialize a commitment, create a new instance of the CommitmentBaseModel class (or your custom class) and add it to the game commitment dictionary when the game is initialized.
It is recommended to import the instances at project startup, see the src/main.ts file.
To create a new instance of CommitmentBaseModel, you need the following parameters:
id: A unique identifier (string). Used to reference thecommitmentin the game (must be unique).character: The character or characters that are in the commitment and so in the room. It can be a single character or an array of characters.props: An object with the commitment's properties:name: The name of the commitment (Optional).image: The image of the commitment (Optional). It can be a string with the path to the image or a function that returns aContainerChild(Optional).icon: The React icon of the commitment (Optional). It can be a React element or a function that returns a React element (Optional).onRun: A function that is called when the commitment is run. It receives two parameters:- The
commitmentinstance itself. event: The event that triggered the run. It is an instance ofOnRunEvent<CommitmentInterface>, which contains methods to navigate to other routes, jump to labels, and more.
- The
disabled: Whether the commitment is disabled. It can be a boolean or a function that returns a boolean (optional, default isfalse). If it is disabled, this commitment will not be taken into consideration, so the characters will not be in the room, but will be busy with other commitments.hidden: Whether the commitment is hidden. It can be a boolean or a function that returns a boolean (optional, default isfalse). If it is hidden, the commitment will not be displayed in the UI.priority: The priority of the commitment. The higher the number, the higher the priority (optional, default is0).executionType: The execution type of the commitment. It can be "automatic" or "interaction". If it is "automatic", theonRunfunction will be called automatically when the player is in the room. If it is "interaction", the player must interact with the character to run theonRunfunction (optional, default is "interaction").dateScheduling: Used to schedule what date it will be added and removed. It is an instance ofDateSchedulingInterface(Optional).timeSlot: The time slot in which the commitment will be active. It is an instance ofTimeSchedulingInterface(Optional).
import { CommitmentBaseModel, RegisteredCommitments } from "@drincs/nqtr";
import { narration } from "@drincs/pixi-vn";
import { NARRATION_ROUTE } from "../constans";
import { TALK_SLEEP_LABEL_KEY } from "../labels/variousActionsLabelKeys";
import { aliceTalkMenuLabel } from "../labels/variousActionsLabels";
import { alice } from "./characters";
export const aliceSleep = new CommitmentBaseModel("alice_sleep", alice, {
priority: 1,
timeSlot: {
from: 20,
to: 10,
},
onRun: async (_, event) => {
await event.navigate(NARRATION_ROUTE);
await narration.jump(TALK_SLEEP_LABEL_KEY, event);
},
});
export const aliceGoSchool = new CommitmentBaseModel("alice_go_school", alice, {
timeSlot: {
from: 8,
to: 14,
},
priority: 2,
});
export const aliceSmokes = new CommitmentBaseModel("alice_smokes", alice, {
timeSlot: {
from: 10,
to: 20,
},
onRun: async (_, event) => {
await event.navigate(NARRATION_ROUTE);
await narration.jump(aliceTalkMenuLabel, event);
},
});
RegisteredCommitments.add([aliceSleep, aliceGoSchool, aliceSmokes]);RegisteredCommitments.add is required to save the commitments in the game.
You can also create a function to load commitments. The important thing is that it is called at least once before the commitments are used in the game, otherwise they will not be available.
Link
For an commitment to be linked to a room, the room must be included in the Commitment instance. The relationship between a commitment and a room is one-to-many, meaning that a rooms can be linked to multiple commitments, but a commitment can only be linked to one room (a character cannot be in two places at the same time).
There are two ways to do this:
During game initialization
For a commitment to be available to the player, it must be linked to a room.
import { RegisteredRooms, RoomBaseModel } from "@drincs/nqtr";
import { mcHome } from "./locations";
import { aliceSleep } from "./routine";
export const aliceRoom = new RoomBaseModel("alice_room", mcHome, {
name: "Alice room",
background: "location_aliceroom",
routine: [aliceSleep],
});
RegisteredRooms.add([aliceRoom]);During the game
You can also link a commitment to a room during the game. This feature is useful if you want to temporarily add a commitment. The list of routine added this way will be included in your game saves.
To link a commitment to a room during the game, you can use the addCommitment method.
import { newLabel, showImageContainer } from "@drincs/pixi-vn";
import { aliceSmokes } from "../routine";
import { terrace } from "../rooms";
const startLabel = newLabel("start", [
async () => {
terrace.addCommitment(aliceSmokes);
},
]);
export default startLabel;Unlink
To detach a commitment from a room, you must first consider how it was linked.
If it was linked during the game initialization, it cannot be removed. However, you can add another commitment with the same character at the same time slot, so the character will be occupied with the new commitment and therefore will no longer be present in the previous room. By default, priority is given to the commitment added during gameplay over the one added during initialization, but this behavior can be modified using the priority property.
If it was linked during gameplay, it can be removed using the removeCommitment method.
import { aliceSmokes } from "../routine";
import { routine } from "@drincs/nqtr";
routine.remove(aliceSmokes);Get
To get a commitment by its id, use the RegisteredCommitments.get function.
import { RegisteredCommitments } from "@drincs/nqtr";
const aliceWorks = RegisteredCommitments.get('alice_works');Get all
To get all commitments, use the RegisteredCommitments.values function.
import { RegisteredCommitments } from "@drincs/nqtr";
const commitments = RegisteredCommitments.values();Custom class
Templates
In all templates, the Commitment class is already defined in the file models/nqtr/Commitment.ts. You can use it directly or modify it to suit your needs.
It is recommended to create your own class Commitment that extends CommitmentStoredClass and "override" the interface CommitmentInterface to add, edit, or remove properties or methods.
For example, if you want to create a class Commitment, you must "override" the interface CommitmentInterface to use your properties or methods. (See the file nqtr.d.ts)
Now you can create a class Commitment that extends CommitmentStoredClass and implements the CommitmentInterface. (For more information on how to create a class in TypeScript, read the official documentation)
To create a property that stores its value in the game storage, you can create Getters/Setters and use the this.getStorageProperty() / this.setStorageProperty() methods. (See the file Commitment.ts)
import {
ActiveScheduling,
CommitmentInterface,
CommitmentStoredClass,
CommitmentStoredClassProps,
OnRunAsyncFunction,
OnRunEvent,
OnRunProps,
} from "@drincs/nqtr";
import { CharacterInterface } from "@drincs/pixi-vn";
import { PixiUIParam, PixiUIProp, ReactUIParam, ReactUIProp } from "./ui-elements";
export default class Commitment extends CommitmentStoredClass implements CommitmentInterface {
constructor(
id: string,
characters: CharacterInterface | CharacterInterface[],
props: {
name?: string;
image?: PixiUIParam<Commitment>;
background?: PixiUIParam<Commitment>;
icon?: ReactUIParam<Commitment>;
onRun?: OnRunEvent<CommitmentInterface>;
disabled?: boolean | (() => boolean);
hidden?: boolean | (() => boolean);
} & CommitmentStoredClassProps,
) {
characters = Array.isArray(characters) ? characters : [characters];
super(id, characters, props.onRun, props);
this.name = props.name || "";
this._image = props.image;
this._background = props.background;
this._icon = props.icon;
this._defaultDisabled = props.disabled || false;
this._defaultHidden = props.hidden || false;
}
readonly name: string;
private readonly _image?: PixiUIParam<Commitment>;
get sprite(): PixiUIProp | undefined {
const image = this._image;
if (typeof image === "function") {
return (runProps: OnRunProps) => image(this, runProps);
}
return image;
}
private readonly _background?: PixiUIParam<Commitment>;
get background(): PixiUIProp | undefined {
const background = this._background;
if (typeof background === "function") {
return (runProps: OnRunProps) => background(this, runProps);
}
return background;
}
private readonly _icon?: ReactUIParam<Commitment>;
get icon(): ReactUIProp | undefined {
const icon = this._icon;
if (typeof icon === "function") {
return (runProps: OnRunProps) => icon(this, runProps);
}
return icon;
}
private _defaultDisabled: boolean | (() => boolean) = false;
get disabled(): boolean {
let value = this.getStorageProperty<boolean>("disabled") || this._defaultDisabled;
if (typeof value === "function") {
return value();
}
return value;
}
set disabled(value: boolean) {
this.setStorageProperty("disabled", value);
}
private _defaultHidden: boolean | (() => boolean) = false;
get hidden(): boolean {
let value = this.getStorageProperty<boolean>("hidden") || this._defaultHidden;
if (typeof value === "function") {
return value();
}
return value;
}
set hidden(value: boolean) {
this.setStorageProperty("hidden", value);
}
override isActive(options?: ActiveScheduling): boolean {
if (this.hidden) {
return false;
}
return super.isActive(options);
}
override get run(): OnRunAsyncFunction {
return async (runProps: OnRunProps) => {
const res = await super.run(runProps);
await runProps.invalidateInterfaceData();
return res;
};
}
}