Loading...
Loading...
Use when defining visual novel characters for a @drincs/pixi-vn game — creating a character with a name, color, icon and other props, registering it so it can be looked up by id, and referencing it from dialogue/narration. Load this before writing any `CharacterBaseModel` or `RegisteredCharacters` code.
npx skill4agent add drincs-productions/pixi-vn pixi-vn-charactersnarration.dialogueimport { CharacterBaseModel, RegisteredCharacters } from "@drincs/pixi-vn";@drincs/pixi-vn/characterspixi-vn-getting-startedCharacterBaseModelidnamesurnameageiconcolorimport { CharacterBaseModel } from "@drincs/pixi-vn";
export const liam = new CharacterBaseModel("liam", {
name: "Liam",
surname: "Smith",
age: 25,
icon: "https://example.com/liam.png",
color: "#9e2e12",
});
export const emma = new CharacterBaseModel("emma", {
name: "Emma",
surname: "Johnson",
age: 23,
icon: "https://example.com/emma.png",
color: "#c23b7f",
});idnamesurnameageCharacterStoredClassCharacterBaseModelliam.name = "..."iconcolorimport { liam } from "@/content/characters";
console.log(liam.name); // "Liam"
liam.name = "Liam Smith";
console.log(liam.name); // "Liam Smith" — now persisted in game storageidnamesurnameageiconcolorspritemodels/Character.tsCharacter extends CharacterStoredClass implements CharacterInterfaceCharacterInterfacepixi-vn.d.tsdeclare module "@drincs/pixi-vn"CharacterInterfaceRegisteredCharacters.get()this.getStorageProperty()this.setStorageProperty()CharacterStoredClassCharacterBaseModelnamesurnameagepixi-vn-react-templatenpm create pixi-vn@latestsrc/models/Character.tsnamesurnameageiconcolor// models/Character.ts
import { type CharacterInterface, CharacterStoredClass } from "@drincs/pixi-vn";
export default class Character
extends CharacterStoredClass
implements CharacterInterface
{
constructor(
id: string | { id: string; emotion: string },
props: CharacterProps,
) {
super(
typeof id === "string" ? id : id.id,
typeof id === "string" ? "" : id.emotion,
);
this.defaultName = props.name;
this.defaultSurname = props.surname;
this.defaultAge = props.age;
this.icon = props.icon;
this.color = props.color;
}
// stored — persists across save/load, same pattern as CharacterBaseModel
private defaultName?: string;
get name(): string {
return (
this.getStorageProperty<string>("name") || this.defaultName || this.id
);
}
set name(value: string | undefined) {
this.setStorageProperty<string>("name", value);
}
private defaultSurname?: string;
get surname(): string | undefined {
return this.getStorageProperty<string>("surname") || this.defaultSurname;
}
set surname(value: string | undefined) {
this.setStorageProperty<string>("surname", value);
}
private defaultAge?: number;
get age(): number | undefined {
return this.getStorageProperty<number>("age") || this.defaultAge;
}
set age(value: number | undefined) {
this.setStorageProperty<number>("age", value);
}
// not stored
readonly icon?: string;
readonly color?: string;
}
interface CharacterProps {
name?: string;
surname?: string;
age?: number;
icon?: string;
color?: string;
}// pixi-vn.d.ts
declare module "@drincs/pixi-vn" {
interface CharacterInterface {
name: string;
surname?: string;
age?: number;
readonly icon?: string;
readonly color?: string;
}
}RegisteredCharactersRegisteredCharacters.add(...)CharacterBaseModeladdimport { RegisteredCharacters } from "@drincs/pixi-vn";
RegisteredCharacters.add(liam, emma);
// or with arrays:
RegisteredCharacters.add([liam, emma]);RegisteredCharactersRegisteredCharacters.get(id)undefinedRegisteredCharacters.has(id)RegisteredCharacters.values()RegisteredCharacters.keys()RegisteredCharacters.clear()const liam = RegisteredCharacters.get("liam");pixi-vn-react-templatenpm create pixi-vn@latestexport constsrc/content/characters.tsRegisteredCharacters.add([...])// src/content/characters.ts
import Character from "@/models/Character";
import { RegisteredCharacters } from "@drincs/pixi-vn";
export const mc = new Character("mc", { name: "Me" });
export const james = new Character("james", {
name: "James",
color: "#0084ac",
});
export const steph = new Character("steph", {
name: "Steph",
color: "#ac5900",
});
export const sly = new Character("sly", { name: "Sly", color: "#6d00ac" });
RegisteredCharacters.add([mc, james, steph, sly]);src/content/index.tsimport.meta.globcontent/RegisteredCharacters.add(...)content/.addcontent/addRegisteredCharacters.addcontent/index.tsCharacterIdTypestringPixivnCharacterIdsvitePluginPixivntypeFilePathCharacterIdTypepixi-vn.gen.d.tsexport const alice = new CharacterBaseModel("alice", {
name: "Alice",
icon: "https://example.com/alice.png",
color: "#9e2e12",
});
export const angryAlice = new CharacterBaseModel(
{ id: "alice", emotion: "angry" },
{ icon: "https://example.com/angryAlice.png" },
);
RegisteredCharacters.add([alice, angryAlice]);namesurnameage"<id>@<emotion>"console.log(alice.name); // "Alice"
alice.name = "Eleonora";
console.log(alice.name); // "Eleonora"
console.log(angryAlice.name); // "Eleonora" — falls back to the base id's value
angryAlice.name = "Angry Eleonora";
console.log(alice.name); // "Eleonora" — unaffected
console.log(angryAlice.name); // "Angry Eleonora" — its own override now setcharacternarration.dialogue = {
character: liam,
text: "Which test do you want to perform?",
};
// or by id:
narration.dialogue = { character: "liam", text: "..." };@drincs/pixi-vn/vitetypeFilePathpixi-vn-getting-startedCharacterIdTypestringcharacter: liamcharacter: "liam""liem"CharacterIdTypeDialogueInterface.characterCharacterInterface | stringRegisteredCharacters.get