Prompting Terminology
Key terminology for the prompting system.
Did you know that when you interact with AI, the prompts behind those actions are actually fully customizable? This includes your own prompts, as well as the built-in versions.
To allow this, the prompting system in Novelcrafter is quite powerful and lets you to combine all your Codex entries, additional context and more into something the AI can work with.
Don’t worry if this sounds very technical! You’re not doing actual programming. Think of it more like putting in placeholders for the system to fill out later (also known as a “template language”).
Terminology
Let’s go over some key terminology you’ll encounter when writing custom prompts. You can take a look at all of them in the following example as a quick overview:
Expressions
In Novelcrafter prompting, expressions are marking the boundaries of “placeholders” for the system to fill out. To open and close an expression, use curly braces ({and }), like so
{expression}
Expressions can be put anywhere you want, either on their own line, or directly within text:
Some text before {inline} and some text after
{standalone}
If you’re seeing an error with your prompt, look out for expressions that might be missing a closing curly brace!
Functions
In order to access any kind of information, we need to use a function inside our expression. Each function performs only one specific task, and comes back with a result (also known as its “return value”).
For example, we can access the current scene point-of-view (POV) with pov:
{pov}
<pointOfView>Write in third person omniscient.<pointOfView>
Some functions might return nothing, or fall back to a default value instead (e.g. if you have no POV set, this would return a regular 3rd person view here).
As you write your prompts, you will encounter functions that contain a period in their name:
{novel.title}
My Novel Title
As you may have guessed, when we use novel.title, we get back the title of the novel we’re currently in.
Since there’s more than one element inside of Novelcrafter that can have a ‘title’ (e.g. acts, chapters, and more), the function starts with the prefix of “novel” to differentiate itself (and avoid ambiguity to its behavior).
Parameters
There are cases where we want to access information from a different chapter, or may want to look up a specific Codex entry by name. To allow this flexibility, functions can have parameters.
To do so, we simply use some parentheses (( to open and ) to close) after our function name, and use another function inside:
{codex.get(pov)}
<character name="Alice">...</character>
In this example, we ask the Codex to return the character entry associated with the current POV. If we don’t have a character set for our POV, we would get nothing back instead. The parentheses here basically say “get the point of view first, and then pass it on to the codex”.
This means functions are evaluated from the inside out, similar to mathematical equations.
Some functions also accept more than one parameter. In those cases, they are delimited by a comma (,). For example, if we want to ask the codex to return the “Appearance” custom detail, provided our entry we ask for has this detail, it would look like this:
{codex.detail(pov, "Appearance")}
<character name="Alice">
<appearance>25-year old, shoulder-length dark hair...</appearance>
</character>
Automatic conversion
If you’re wondering why we don’t need to use codex.get in the above case (and keep on just using pov), or how we even got the character entry from a point-of-view in the first place, that’s because functions automatically convert what you give them into something they can understand.
For example, we can also access the appearance of our character “Alice” by just providing their name, like so:
{codex.detail("Alice", "Appearance")}
In this case, the codex.detail function will first look up if we have an entry for “Alice” in the Codex, and then return the “Appearance” detail if she has one. If your Codex does not have an entry named “Alice”, nothing will be returned (like before).
Take note that this does make our prompt quite reliant on an entry named “Alice” being there, but there are use-cases where this is quite useful, like checking for a “Genre” entry, or general style guidelines.
Nesting parameters and functions
Using one function as a parameter for another function is called “nesting”. To learn more about what’s possible, learn more on nesting in prompts.
Text
As shown in prior examples, if you need to pass on static values for names, prefixes and more, you can use regular quotation marks:
{codex.get("Story Genre")}
Some names might have already quotation marks in them. For this reason, single and double quotes (' and ") can be used interchangeably. Think of them as one escaping the text from the other. This means that you can say both "Odysseus' Bow" and 'Vampire "food"' within your prompts.
Operators
Inside of expressions (as well as function parameters), you can use certain operators.
Add
The add operator combines things together using the plus symbol (+). For example, this allows you to look for certain codex entries with a specific prefix/suffix, or combine different names:
{codex.get("Chapter " + chapter.number + " Notes")}
<other name="Chapter 3 Notes">...</other>
Is Equal
To see if two things are equal you can use the “is equal” operator, indicated by is with text on its left and right hand side:
{#if pov.character is "Alice"}
...
{#endif}
This operator mostly gets used in logic branches which you can learn more about here.
Includes
If you want to see if a certain value (A) is included in another value (B) you can use the “includes” operator, indicated by in:
{#if "Time: Morning" in scene.labels}
The scene takes place in the morning...
{#endif}
Comments
There might be a point where a prompt gets too big to understand at a glance and you want to leave some comments on what does what, or you want to turn off certain instructions for a bit. For this, Novelcrafter allows comments, which start with {! and end with !} (note the use of exclamation marks here):
{! Let's make sure the AI writes in a more natural tone !}
While writing, avoid the following AI-isms: {codex.get("AI-isms")}
The text inside your comment will not be sent to the AI (since that’s just for you), and only the last line will be sent instead.
Frequently Asked Questions
Can I use this in my presets or personas?
No, this custom prompting syntax is only available when you write your own prompts, inside the custom instructions. Trying to use any expressions/functions inside chat messages, your persona description, etc. will not be read and interpreted by the system.
I can’t seem to use JSON, and I get errors if I try?
The prompt instructions of Novelcrafter indeed do not support JSON. You can use double-curly quotes (which will be kept), however we recommend using XML over anything else—LLMs perform much better with that style of prompting anyways.