InMemoryVariableStorage
, which acts as a simple dictionary to store variable names with their current values.String
, Number
and Boolean
to be stored in memory, and then accessed by this wrapper class that converts them to the C# equivalents string
, float
and bool
, ready for use in your code.InMemoryVariableStorage
is flexible and extensible, and has utilities for things such as initialising with default variables declared, or serialising to and from JSON. But what if you want to add very custom behaviour to how variables are stored? To keep values somewhere other than in memory, or add side effects to certain operations in a way that wouldnβt work by just extending this default variable storage? Well, you can define your own.VariableStorageBehaviour
is an abstract class that can be inherited from. It specifies the methods which Yarn Spinner may call at runtime, which are expected to be dealt with in your implementation:TryGetValue(string variableName, out T result)
variableName
exists and can be cast to the given type and, if so, return its value.SetValue(string variableName, string stringValue)
stringValue
and somehow attribute it with the key variableName
.SetValue(string variableName, float floatValue)
floatValue
and somehow attribute it with the key variableName
.SetValue(string variableName, bool boolValue)
boolValue
and somehow attribute it with the key variableName
.Clear()
TryGetValue()
without first calling SetValue()
with the same key would now fail.Contains(string variableName)
variableName
exists as a key in the storage at this moment.VariableStorageBehaviour
works beyond that. It simply assumes that you are doing something sensible, and that your subclass will provide the functionality it expects. Some of those expectations cannot be constrained in code, like the required method declarations can, so there is a level of trust here that you (as the implementer of this black box subclass which Yarn Spinner has never seen) will:SetValue()
methods are empty or otherwise throw away the values they are given, but this will mean your TryGetValue()
methods will never be able to work.TryGetValue()
methods return random values from the aether, but this will make your use of these variables in your Yarn script effectively nonsensical. Likewise if you allow setting of multiple values with the same key.Clear()
method does nothing, but this means that Yarn script progress or state may never be reset correctly.Contains()
method always returns false, but this will lead to overwriting existing values the next time someone tries to SetValue()
a seemingly unused key that already had a value.SetValue()
method printed out the given key and value on a piece of paper, Contains()
and TryGetValue()
methods that took a snapshot with a camera placed above the printer and read the values back, and a Clear()
method that pushed the paper from the printer tray into a shredder. Yarn Spinner would not care, because it would still do those three things (though probably unreliably, and with some storage limitations).VariableStorageBehavour
abstract class.Start()
method:[PrimaryKey]
decorator.CreateTable()
method with the class we want to represent.Clear()
is just a matter of telling each table in the database to remove all its entries. The query for this is DELETE * FROM TableName
, where the *
means all entries. Executing a query on the database is as simple as calling Execute()
on the database connector with a string parameter of the desired query.TryGetValue()
is the method that needs to figure out whether a value exists for the given key and, if so, return it as the correct type. This requires a little bit of C# generics.Select ColumnName FROM TableName WHERE (conditions to match)
.T
is at compile time, results must be cast to object
and then back to T
(thanks, C#!).TryGetValue()
implementation:Contains()
method, by checking them all:SetValue()
methods, which would each look something like this:DialogueRunner
game object in your scene to put your custom implementation to work.InMemoryVariableStorage
does at runtime, even though the entire storage model and behaviour has changed.VariableStorageBehaviour
abstract class, you can make a custom Variable Storage backed by virtually anything to suit your needs!