LogoPixi’VN

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 the commitment in 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.
  • room: The room where the commitment is. It must be an instance of RoomInterface.
  • 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 a ContainerChild (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 commitment instance itself.
      • event: The event that triggered the run. It is an instance of OnRunEvent<CommitmentInterface>, which contains methods to navigate to other routes, jump to labels, and more.
    • disabled: Whether the commitment is disabled. It can be a boolean or a function that returns a boolean (optional, default is false). 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 is false). 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 is 0).
    • executionType: The execution type of the commitment. It can be "automatic" or "interaction". If it is "automatic", the onRun function will be called automatically when the player is in the room. If it is "interaction", the player must interact with the character to run the onRun function (optional, default is "interaction").
    • dateScheduling: Used to schedule what date it will be added and removed. It is an instance of DateSchedulingInterface (optional).
    • timeSlot: The time slot in which the commitment will be active. It is an instance of TimeSchedulingInterface (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";
import { aliceRoom, classRoom, terrace } from "./rooms";

const aliceSleep = new CommitmentBaseModel("alice_sleep", alice, aliceRoom, {
    priority: 1,
    timeSlot: {
        from: 20,
        to: 10,
    },
    onRun: (_, event) => {
        event.navigate(NARRATION_ROUTE);
        narration.jumpLabel(TALK_SLEEP_LABEL_KEY, event);
    },
});

const aliceGoSchool = new CommitmentBaseModel("alice_go_school", alice, classRoom, {
    timeSlot: {
        from: 8,
        to: 14,
    },
    priority: 2,
});

const aliceSmokes = new CommitmentBaseModel("alice_smokes", alice, terrace, {
    timeSlot: {
        from: 10,
        to: 20,
    },
    onRun: (_, event) => {
        event.navigate(NARRATION_ROUTE);
        narration.jumpLabel(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.

Add

Initializing a commitment will not add it to the game. To do this, you'll need to use one of the following methods:

During game initialization

You can add a commitment to your routine during game initialization. This is useful for tasks that should always be present in the game, such as daily routines of characters.

import { routine } from "@drincs/nqtr";
import { aliceGoSchool, aliceSleep } from "../values/routine";

export function initializeNQTR() {
    // ...

    routine.fixedRoutine = [aliceSleep, aliceGoSchool]; 
}

During the game

You can also add a commitment to your routine during gameplay. This feature is useful if you want to temporarily add a commitment. The list of tasks added this way will be included in your game saves.

To add a commitment to your routine during gameplay, you can use the routine.add method.

import { aliceSmokes } from "../routine";
import { routine } from "@drincs/nqtr";

routine.add(aliceSmokes);

Remove

To remove a commitment from your routine, you can use the routine.remove method. This will remove the commitment from the game and it will not be saved in the game saves.

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 {
    CommitmentInterface,
    CommitmentStoredClass,
    CommitmentStoredClassProps,
    OnRunEvent,
    OnRunProps,
    RoomInterface,
} from "@drincs/nqtr";
import { CharacterInterface } from "@drincs/pixi-vn";
import { ReactElement } from "react";

export default class Commitment extends CommitmentStoredClass implements CommitmentInterface {
    constructor(
        id: string,
        characters: CharacterInterface | CharacterInterface[],
        room: RoomInterface,
        props: {
            name?: string;
            image?: string | ContainerChild | ((props: Commitment, runProps: OnRunProps) => ContainerChild);
            background?: string | ContainerChild | ((props: Commitment, runProps: OnRunProps) => ContainerChild);
            icon?: ReactElement | ((props: Commitment, runProps: OnRunProps) => ReactElement);
            onRun?: OnRunEvent<CommitmentInterface>;
            disabled?: boolean | (() => boolean);
            hidden?: boolean | (() => boolean);
        } & CommitmentStoredClassProps
    ) {
        characters = Array.isArray(characters) ? characters : [characters];
        super(id, characters, room, 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?: string | ContainerChild | ((props: Commitment, runProps: OnRunProps) => ContainerChild);
    get sprite(): string | ContainerChild | ((props: OnRunProps) => ContainerChild) | undefined {
        const image = this._image;
        if (typeof image === "function") {
            return (runProps: OnRunProps) => image(this, runProps);
        }
        return image;
    }
    private readonly _background?: string | ContainerChild | ((props: Commitment, runProps: OnRunProps) => ContainerChild);
    get background(): string | ContainerChild | ((props: OnRunProps) => ContainerChild) | undefined {
        const background = this._background;
        if (typeof background === "function") {
            return (runProps: OnRunProps) => background(this, runProps);
        }
        return background;
    }
    private readonly _icon?: ReactElement | ((props: Commitment, runProps: OnRunProps) => ReactElement);
    get icon(): ReactElement | ((props: OnRunProps) => ReactElement) | 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 get isActive(): boolean {
        if (this.hidden) {
            return false;
        }
        return super.isActive;
    }
}