Skip to main content

Loading and Running Yarn Scripts

Welcome to the YarnRunner functionality tutorial. In this tutorial, we will guide you on how to load and run the Yarn narrative scripts you wrote in the previous tutorial.

1. Initializing YarnRunner

First, make sure you have correctly imported all the necessary modules. Here are the modules we need for the examples in this tutorial:

init.lua
local Content <const> = require("Content")
local Path <const> = require("Path")
local Node <const> = require("Node")
local Director <const> = require("Director")
local YarnRunner <const> = require("YarnRunner")

To ensure that we can locate the Yarn script, we need to set the correct search path. If the Yarn script and program modules are in the same directory, you can add the following code:

init.lua
local path = Path:getScriptPath(...)
Content:insertSearchPath(1, path)

Next, assuming we want to load a Yarn file named "tutorial.yarn" with a starting node titled "Start," you can write the following code:

init.lua
local runner = YarnRunner("tutorial.yarn", "Start")

2. Executing and Displaying Narrative Content

We have defined an advance function that can read and display text content or options from the Yarn script. Depending on the narrative content, it can also display character names:

init.lua
-- The `advance` function takes an optional integer parameter representing the player's choice index.
-- When calling this function for the first time or when no choice is needed, we pass nil.
local function advance(option)

-- The function first calls `runner:advance(option)` to fetch the next part of the Yarn script.
-- This returns two values: an action type and a result.
local action, result = runner:advance(option)

-- Based on the action type, we choose how to handle the result.
if action == "Text" then

-- If the action is "Text," the result will be a TextResult object,
-- which contains the text content and any associated marks (e.g., character names).
-- We check for marks, extract the character name (if present), and print the text content.
local characterName = ""
local marks = result.marks
if marks then
for i = 1, #marks do
local mark = marks[i]
if mark.name == "char" then
characterName = mark.attrs.name .. ": "
end
end
end
print(characterName .. result.text)

elseif action == "Option" then

-- If the action is "Option," the result will be an OptionResult object,
-- which contains one or more options. The function iterates through these options and prints them,
-- which the player can choose later.
for i, op in ipairs(result) do
if op then
print("[" .. tostring(i) .. "]: " .. op.text)
end
end

else

-- For other actions (e.g., errors), the function directly prints the result.
print(result)

end
end

3. Initiating the Narrative

To initiate the narrative, you simply call the advance function without any arguments:

init.lua
advance()

4. Responding to User Input

To allow player interaction with the narrative, we need a node to capture and respond to user input. We create a node and assign it a signal slot named "go." When this signal is triggered, it will call the advance function again and pass the player's choice:

init.lua
local node = Node()
node:gslot("go", function(option)
advance(option)
end)
node:addTo(Director.entry)

In this example, a global event listener has been registered for quick testing. In actual game development, you would need to implement UI interaction logic. With the "go" global event listener, you can continue the dialogue by entering emit 'go' in the Dora SSR console command line, and you can interactively test the conversation by entering emit 'go', 1 to select dialogue branches.

5. Conclusion

Now, you have set up all the necessary code to load and run Yarn narrative scripts. You can run the above scripts to start your interactive narrative, where players can interact by choosing options. Happy storytelling!