Design patterns and best practices
Description: Common patterns for Narratyr projects
Variables vs. Functions
There are two ways to share state between Narratyr and your Game -- either through variables or functions. Which should you use and when?
A common example: Inventory
Lets say you want to know about the player's inventory in a quest. A common idea here might be to check if the player has retrieved a requested item, or customize dialogue based on the presence or absence of an item. One way to represent this would be through a variable:

In this example, the inventory is a set of Item entities (a set is like a list,
but where duplicate entries are not allowed.)
entity_reference<Item> is used here to allow Narratyr to know as much about the items
as possible, but this isn't required. You could just as easily use a list<string>
if you wished for more flexibility (duplicates and arbitrary strings)
What are the advantages to this?
- Narratyr can handle save-game serialization for you.
- Narratyr also has engine debuggers to display variables, so you can see the state in an editor window when debugging.
- Quests and Dialogues always know what's happening
The disadvantages?
- Narratyr doesn't support storing structures (outside of entities) in variables, so if your inventory items require a lot of metadata, you likely don't want to use Narratyr as your inventory system.
- If your inventory is large and complex, you may need more complicated data structures than a list or set.
The alternate approach here would be to use functions:

In this example, there's: addInventoryItem(itemId, count),
removeInventoryItem(itemId, count) and hasInventoryItem(itemId).
What are the advantages of this?
- You can use any underlying data structure you want for your inventory, as long as you provide a set of functions to interact with it.
- If you already have systems setup before you decided to use Narratyr, this can create a natural bridge.
What are the disadvantages?
- More complex to build -- you need to write these functions in your game, then let Narratyr know about them. If the function changes in the game, you need to remember to update the definition in Narratyr.
- Debugging becomes more complex. Because a function can do anything and Narratyr has no way to look into it, debugging becomes more challenging.
- You need to let Narratyr know that you modified state, if you use functions in gates
or event listeners, so those nodes know to re-evaluate their conditions. On the other
hand, variables in Narratyr handle this automatically.
- For example, if you were to update the inventory in the game, you need to
let Narratyr know so it can rerun any pending
hasInventoryItemcalls. This is one function call so it's simple, but it's also easy to forget.
- For example, if you were to update the inventory in the game, you need to
let Narratyr know so it can rerun any pending
- You'll need to handle save games yourself
Recommendation
Use variables when you can, because they're much simpler to manage and debug. Use functions when the underlying system is more complicated than is representable in Narratyr.
Dialogue Routing
Often, a character may be revisited multiple times in a game, and the conversation with them will evolve over time as the game evolves. It may be temping to create a dialogue graph for each individual interaction. This is completely reasonable, but it does leave it up to your game to choose the correct dialogue graph based on the current game state, which may move logic outside the dialogue system which belongs in the dialogue system.
An alternative approach is to make Dialogue graphs which are character-centric instead of interaction-centric. In this model, you would use a Hub node in order to route to the correct sub-graph based on Narratyr state. Here's an example:

In the above example, the conversation with Sandra changes based off the status of
objectives and variables. This is admittedly a bit complicated looking though. One
additional pattern you can use here is to use Start Dialogue to divide into
sub-graphs.

Entity References can save you from bugs
Narratyr variables can store something called an Entity Reference, with a subtype
of either any or a defined entity type (Character, Item, etc.).
You can use these to reference an entity defined in the Narratyr project.
The underlying type for this is simply a string, which is what your game code will
see. The id string is something called a proquint, which is a random id that's
designed to be pronounceable. If you have a character named Sally, and a variable
that stores an entity reference, the value in the variable won't be the literal string
Sally, it will be a unique id like mufob-kogoh-hafal-jatun (you can see this id
in the entity editor page).
Why store an entity reference instead of a string containing the name? Both are valid approaches, the main advantage of an Entity Reference is that Narratyr understands it so it can survive renames and the validator will give you better checks (for instance, if you reference an entity that doesn't exist)