Extending the System
The project is designed to be extended. You can add characters, relationships, and locations indefinitely without touching the file types. But when you want to add a new clan, a new discipline, a new field to the character sheet, or an entirely new file type, you are extending the system itself. This chapter covers the conventions, the pitfalls, and the philosophy.
Adding New Files (No Schema Changes)
Most expansion happens at the data layer. Adding a character, a location, a relationship — these are writes to existing types, not changes to the types themselves. Follow the conventions in the preceding chapters and the system absorbs your addition naturally.
The key rule: connect what you add. A new character should have at minimum a clan, a location, a coterie (or a reason not to have one), a sire relationship, and at least one peer relationship. A new location should have a parent. A new relationship should have both from and to characters. Files that float in isolation weaken the web the AI relies on.
Adding Fields to an Existing Type
Adding a field to a schema is lightweight. You add it to the schema's properties object with its type, constraints, and any reference annotation, and the field appears on every file of that type. Old files get the field as empty or its default. New files can populate it.
Before you add a field, ask:
- Does the AI actually need this to run better scenes? A field the AI never reads is noise.
- Can this be derived from existing fields? If
healthMaxis already Stamina + 3, you don't need a separatetoughnessRatingfield — use a computed field with an expression. - Does this belong on a different type? If you are adding
necklaceDescriptionto the character schema, it probably belongs on an equipment file in their inventory. - Will this break the existing layout? Adding a field doesn't automatically add it to the rendered sheet layout. If you want it visible, you need to update the layout.
Computed Fields
If the new field's value can be calculated from other fields, make it computed. Computed fields use the expression language and cannot be written directly — they derive at read time. For example, adding "frenzyThreshold": { "type": "number", "expression": "($self.hunger >= 4) ? 4 : 5" } gives you a derived value without asking anyone to maintain it. Read the reference and computed fields platform instructions for the full expression language, including load() for cross-file reads and sum() for aggregating arrays.
Reference Fields
If the new field should point at another file, annotate it with referencedFileTypeSlug. Adding "haven": { "type": "string", "referencedFileTypeSlug": "location" } to the character schema creates a reference picker that shows locations. The AI can then follow character → haven → parent → faction to determine whose territory the haven is in.
Adding Enum Values
Many fields use enums: type (Kindred, Mortal, Ghoul...), sect (Camarilla, Anarch, Independent...), status (Active, Dead, In Torpor...), nature on relationships (Sire, Ally, Enemy...), faction on locations (Camarilla Domain, Anarch Territory...).
Adding a value to an enum is just adding a string to the array. But before you do, check: does any GM instruction or piece of AI behavior depend on the existing values? The AI may have instructions keyed to specific enum values. Adding "Carthagian" to sect is safe — the AI will treat it as an unknown sect. Adding a new nature to relationships like "Blood Debt" means the AI won't have specific behavioral rules for it unless you add them.
Adding a New File Type
If you need to track something that doesn't fit any existing type — say, a Chronicle Tenets file, a Blood Hunt declaration, or a detailed Haven builder — create a new file type. Read the platform instructions for creating file types before you start. The process:
- Define the schema: what fields, what types, what constraints.
- Decide on a designation:
characterfor playable entities,locationfor mappable places,eventfor story beats, or nothing for pure reference data. - Create a layout if you want a rendered sheet. Omitting it gives you a generated layout.
- Create a root folder for files of the new type.
- Populate with initial files and connect them to existing data.
Keep the new type focused. A type that tries to be both a character and a location confuses the AI and complicates the reference web. One job per type.
Conventions for Any Addition
Match the existing tone. The World of Darkness is gothic, cynical, and immersive. A new clan called "Sparkle Vampires" with a description written like a Tumblr post breaks the entire chronicle's atmosphere. Read five existing files of the same type before you write your first one.
Use the existing patterns. Characters use dot ratings (● to ●●●●●) for Merits and Flaws. Relationships use the nature enum. Locations use the three-tier hierarchy. Follow the patterns already established — they exist because the AI has learned to read them.
Keep the reference web connected. Every file you add should have at least one inbound or outbound reference to an existing file. A completely isolated file is a wasted opportunity.
Test your additions. Create the file, then run a scene that should use it. Does the AI find it? Does it use the fields correctly? Does the tone hold up? Iterate based on what actually happens in play, not on what you expect to happen.
What Not to Change Lightly
- The character schema's core fields. The attribute, skill, and discipline fields are referenced by name in GM instructions, dice pool construction, and character creation. Renaming
strengthtomightbreaks those references. - The relationship nature enum. Adding values is safe. Removing or renaming existing values breaks every relationship file that uses them.
- The location category enum. The three-tier hierarchy depends on
city,district, andpoi. Changing these breaks the parent chain logic. - GM instructions. As covered in the Narrative Content chapter, these are interconnected and sensitive. Read them all, understand their interactions, then change sparingly.
The Philosophy
Extend with intention. Every field, every file, every reference should make the AI's job easier — giving it richer context, clearer connections, and more interesting material to draw on. Complexity that doesn't serve the story is just noise. The best extension is the one that makes the next scene better without anyone noticing it is there.