LogoPixi’VN

Navigation and map

How to define, organize, and navigate rooms, locations, and maps in Pixi’VN, including custom classes and usage examples.

Nomenclature

Usually in video games, navigation elements used to identify the position of characters are called room, location (e.g. restaurant, house, hospital, etc.), and map. For this reason, names that follow this logic are used.

This does not prevent you from using these elements to manage navigation with the same logic but with different terms. For example, in a game set in space where the player moves between planets, rooms can be the planets, locations can be the solar systems, and maps can be the galaxy.

The navigation system is composed of the following elements:

  • rooms: The core elements of navigation, from which the position of the mc and npc is deduced.
  • locations: A container of rooms.
  • maps: A container of locations.

The player can move between rooms. The location and the map are also determined based on the room in which the player is located.

Initialize

To initialize a room/location/map, create a new instance of the RoomBaseModel / LocationBaseModel / MapBaseModel class (or your custom class) and add it to the game room/location/map 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 RoomBaseModel, you need the following parameters:

  • id: A unique identifier (string). Used to reference the room in the game (must be unique).
  • location: The location where the room is.
  • props: An object with the room's properties:
    • name (Optional): The room's name.
    • image (Optional): The room's image URL.
    • activities (Optional): The activities available in this room.
    • disabled (Optional): Whether the room is disabled. You can also pass a Pixi’VN flag name.
    • hidden (Optional): Whether the room is hidden. You can also pass a Pixi’VN flag name.
    • icon (Optional): The room's icon image URL.

To create a new instance of LocationBaseModel, you need the following parameters:

  • id: A unique identifier (string). Used to reference the location in the game (must be unique).
  • map: The map where the location is.
  • props: An object with the location's properties:
    • name (Optional): The location's name.
    • icon (Optional): The location's icon image URL.
    • activities (Optional): The activities available in this location.
    • disabled (Optional): Whether the location is disabled. You can also pass a Pixi’VN flag name.
    • hidden (Optional): Whether the location is hidden. You can also pass a Pixi’VN flag name.

To create a new instance of MapBaseModel, you need the following parameters:

  • id: A unique identifier (string). Used to reference the map in the game (must be unique).
  • props: An object with the map's properties:
    • name (Optional): The map's name.
    • image (Optional): The map's image URL.
    • activities (Optional): The activities available in this map.
import { RegisteredRooms, RoomBaseModel } from "@drincs/nqtr";
import { bed } from "./activity";
import { mcHome } from "./locations";

export const mcRoom = new RoomBaseModel("mc_room", mcHome, {
    name: "MC room",
    image: "location_myroom",
    activities: [bed],
});

export const aliceRoom = new RoomBaseModel("alice_room", mcHome, {
    name: "Alice room",
    image: "location_aliceroom",
});

export const annRoom = new RoomBaseModel("ann_room", mcHome, {
    name: "Ann room",
    image: "location_annroom",
});

export const bathroom = new RoomBaseModel("bathroom", mcHome, {
    name: "Bathroom",
    image: "location_bathroom",
});

export const lounge = new RoomBaseModel("lounge", mcHome, {
    name: "Lounge",
    image: "location_lounge",
});

export const terrace = new RoomBaseModel("terrace", mcHome, {
    name: "Terrace",
    image: "location_terrace",
});

RegisteredRooms.add([mcRoom, aliceRoom, annRoom, bathroom, lounge, terrace]);

RegisteredRooms.add / RegisteredLocations.add / RegisteredMaps.add is required to save the rooms/locations/maps in the game.

You can also create a function to load rooms/locations/maps. The important thing is that it is called at least once before the rooms/locations/maps are used in the game, otherwise they will not be available.

It is also recommended to set the current room during the start of the game.

labels/startLabel.ts
import { navigator } from "@drincs/nqtr";
import { newLabel } from "@drincs/pixi-vn";
import { mcRoom } from "../values/rooms";

const startLabel = newLabel("start", [
    async () => {
        navigator.currentRoom = mcRoom;
        // ... other initialization logic
    },
]);
export default startLabel;

Get

To get a room/location/map by its id, use the RegisteredRooms.get / RegisteredLocations.get / RegisteredMaps.get function.

import { RegisteredRooms } from "@drincs/nqtr";

const mcRoom = RegisteredRooms.get('mc_room');

Get all

To get all rooms/locations/maps, use the RegisteredRooms.values / RegisteredLocations.values / RegisteredMaps.values function.

import { RegisteredRooms } from "@drincs/nqtr";

const rooms = RegisteredRooms.values();

As explained above, the player can navigate between rooms, and the current room determines the current location and map.

To navigate to a room, set the navigator.currentRoom property to the desired room instance. This will automatically update the current location and map based on the room's location and map.

import { navigator } from "@drincs/nqtr";
import { mcRoom } from "../values/rooms";

navigator.currentRoom = mcRoom;

Custom class

Templates

In all templates, the Room / Location / Map class is already defined in the file models/nqtr/Room.ts / models/nqtr/Location.ts / models/nqtr/Map.ts. You can use it directly or modify it to suit your needs.

It is recommended to create your own class Room / Location / Map that extends RoomStoredClass / LocationStoredClass / MapStoredClass and "override" the interface RoomInterface / LocationInterface / MapInterface to add, edit, or remove properties or methods.

For example, if you want to create a class Room / Location / Map, you must "override" the interface RoomInterface / LocationInterface / MapInterface to use your properties or methods. (See the file nqtr.d.ts)

Now you can create a class Room / Location / Map that extends RoomStoredClass / LocationStoredClass / MapStoredClass and implements the RoomInterface / LocationInterface / MapInterface. (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 Room.ts / Location.ts / Map.ts)

import { ActivityInterface, LocationInterface, RoomInterface, RoomStoredClass } from "@drincs/nqtr";
import ImageTimeSlots from "../ImageTimeSlots";

export default class Room extends RoomStoredClass implements RoomInterface {
    constructor(
        id: string,
        location: LocationInterface,
        props: {
            name: string;
            disabled?: boolean | (() => boolean);
            hidden?: boolean | (() => boolean);
            image: ImageTimeSlots;
            activities?: ActivityInterface[];
            isEntrance?: boolean;
        }
    ) {
        super(id, location, props.activities);
        this.name = props.name;
        this._defaultdisabled = props.disabled || false;
        this._defaulthidden = props.hidden || false;
        this.image = props.image;
        this.isEntrance = props.isEntrance || false;
    }
    readonly name: string;
    readonly image: ImageTimeSlots;
    readonly isEntrance: boolean;
    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);
    }
}

FAQ