Documentation
Persistent

Persistent<T extends PersistentContent>

In the past, we could only modify the state of Storable through Script, but Persistent provides a set of useful methods to easily control the flow.

Persistent requires the name and initial state of a namespace. Persistent with the same name will share the same state.

⚠️

The namespace cannot be an existing built-in namespace (built-in namespaces include: "game")

type PersisData = {
    flag: boolean;
    coin: number;
    name: string;
    // ...
};
const persis = new Persistent<PersisData>("persis", {
    flag: false,
    coin: 0,
    name: "John Smith",
    // ...
});

Note: The stored content must be serializable, the serializable values supported by NarraLeaf-React include:

  • string
  • number
  • boolean
  • object: key is string, value is the above serializable value
  • array: elements are the above serializable value
  • undefined
  • null
  • Date: standard JavaScript date object
⚠️

If the script content contains Persistent, it must be registered with Story.

story.registerPersistent(persis);

Public Methods

constructor

  • namespace: string - the name of the namespace
  • defaultContent: T - initial state

equals<K extends StringKeyOf<T>>

Determine whether the values are equal, can be used in Condition

  • key: K - the key of the state
  • value: T[K] | Lambda<T[K]> | LambdaHandler<T[K]> - the value to compare, a lambda function, or a lambda handler
  • Returns: Lambda<boolean>
scene.action([
    Condition
        .If(persis.equals("id", persis.get("player_id")), [
            character1.say("ID matches!")
        ])
]);
 
// or with a lambda handler
scene.action([
    Condition
        .If(persis.equals("id", (ctx) => ctx.$("player").get("player_id")), [
            character1.say("Player ID matches!")
        ])
]);

notEquals<K extends StringKeyOf<T>>

Determine whether the values aren't equal, can be used in Condition

  • key: K - the key of the state
  • value: T[K] | Lambda<T[K]> | LambdaHandler<T[K]> - the value to compare, a lambda function, or a lambda handler
  • Returns: Lambda<boolean>
scene.action([
    Condition
        .If(persis.notEquals("id", persis.get("player_id")), [
            character1.say("ID doesn't match!")
        ])
]);
 
// or with a lambda handler
scene.action([
    Condition
        .If(persis.notEquals("id", (ctx) => ctx.$("player").get("player_id")), [
            character1.say("Player ID doesn't match!")
        ])
]);

isTrue<K extends Extract<keyof T, BooleanValueKeyOf<T>>>

Determine whether the value is true, can be used in Condition

  • key: K - the key of the state
  • Returns: Lambda<boolean>
scene.action([
    Condition
        .If(persis.isTrue("flag"), [
            character1.say("Flag is true")
        ])
]);

isFalse<K extends Extract<keyof T, BooleanValueKeyOf<T>>>

Determine whether the value is false, can be used in Condition

  • key: K - the key of the state
  • Returns: Lambda<boolean>

isNotNull<K extends StringKeyOf<T>>

Determine whether the value isn't null or undefined, can be used in Condition

  • key: K - the key of the state
  • Returns: Lambda<boolean>

toWord<K extends StringKeyOf<T>>

Convert to a dynamic word

  • key: K - the key of the state
  • Returns: Word<DynamicWord>
character.say(["You have ", persis.toWord("gold"), " gold"]);
 
// or
 
character.say`You have ${persis.toWord("gold")} gold`;

get<K extends StringKeyOf<T>>

Alias of toWord

  • key: K - the key of the state
  • Returns: Word<DynamicWord>
character.say`You have ${persis.get("coin")} coins`;

conditional

Create a conditional word

  • condition: Lambda<boolean> | LambdaHandler<boolean> - the condition to check
  • ifTrue: DynamicWordResult - the word to return if condition is true
  • ifFalse: DynamicWordResult - the word to return if condition is false
  • Returns: Word
character.say([
  "Your flag is ",
  persis.conditional(
    persis.isTrue("flag"),
    "on",
    "off"
  )
]);

evaluate<K extends StringKeyOf<T>>

Evaluate the JavaScript function and determine whether the result is true

  • key: K - the key of the state
  • fn: (value: T[K]) => boolean - a JavaScript function to evaluate the state
  • Returns: Lambda<boolean>
scene.action([
    Condition
        .If(persis.evaluate("coin", (coin) => coin < 10), [
            character1.say`You don't have enough coins!`
        ])
]);

Chainable Methods

set<K extends StringKeyOf<T>>

Create an action to set a value in the persistent storage for the given key

Overload 1 of 2

  • key: K - the key to set the value for
  • value: T[K] - the value to set
  • Returns: ChainedPersistent<T>
scene.action([
    persis.set("coin", 10)
]);

Overload 2 of 2

  • key: K - the key to set the value for
  • handler: (value: T[K]) => T[K] - the handler to modify the value
  • Returns: ChainedPersistent<T>
scene.action([
    persis.set("coin", (coin) => coin + 10) // coin will increase by 10
]);

assign

Create an action to assign a value to the persistent storage

  • value: Partial<T> | ((value: T) => Partial<T>) - the value to assign to the state
  • Returns: ChainedPersistent<T>
scene.action([
    persis.assign({ coin: 10 })
]);
 
// or with a function
scene.action([
    persis.assign((state) => ({ coin: state.coin + 10 }))
]);