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 themcandnpcis deduced.locations: A container ofrooms.maps: A container oflocations.
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 theroomin the game (must be unique).location: Thelocationwhere theroomis.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 thelocationin the game (must be unique).map: Themapwhere thelocationis.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 themapin 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.
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();Navigate
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, OnRunProps, RoomInterface, RoomStoredClass } from "@drincs/nqtr";
export default class Room extends RoomStoredClass implements RoomInterface {
constructor(
id: string,
location: LocationInterface,
props: {
name: string;
disabled?: boolean | (() => boolean);
hidden?: boolean | (() => boolean);
background: string | ContainerChild | ((props: Room, runProps: OnRunProps) => ContainerChild);
activities?: ActivityInterface[];
isEntrance?: boolean;
}
) {
super(id, location, props.activities);
this.name = props.name;
this._defaultDisabled = props.disabled || false;
this._defaultHidden = props.hidden || false;
this._background = props.background;
this.isEntrance = props.isEntrance || false;
}
readonly name: string;
private readonly _background: string | ContainerChild | ((props: Room, runProps: OnRunProps) => ContainerChild);
get background(): string | ContainerChild | ((props: OnRunProps) => ContainerChild) {
const background = this._background;
if (typeof background === "function") {
return (runProps: OnRunProps) => background(this, runProps);
}
return background;
}
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);
}
}