https://github.com/ippclub/yarnflow
A lightweight compiler that converts Yarn Spinner scripts into Lua code, enabling seamless integration of interactive storytelling into Lua-based projects.
https://github.com/ippclub/yarnflow
cpp lua yarn-spinner yuescript
Last synced: 12 months ago
JSON representation
A lightweight compiler that converts Yarn Spinner scripts into Lua code, enabling seamless integration of interactive storytelling into Lua-based projects.
- Host: GitHub
- URL: https://github.com/ippclub/yarnflow
- Owner: IppClub
- License: mit
- Created: 2025-02-26T09:01:00.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-09T03:13:04.000Z (about 1 year ago)
- Last Synced: 2025-03-27T17:51:50.985Z (about 1 year ago)
- Topics: cpp, lua, yarn-spinner, yuescript
- Language: C++
- Homepage:
- Size: 45.9 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# YarnFlow: Yarn Spinner to Lua Compiler
[](https://ippclub.org)
## Description
YarnFlow is a compiler that translates Yarn Spinner scripts into Lua code and uses Lua as the script runtime, allowing you to seamlessly integrate interactive story elements from Yarn Spinner into Lua-based projects. Whether you're developing a game, an interactive app, or any Lua-powered project, YarnFlow simplifies the process of leveraging Yarn Spinner’s intuitive story-based scripting language with the power and flexibility of Lua.
## About YarnFlow
YarnFlow is a sub-project developed and maintained as part of the Dora SSR open-source game engine project. It provides a seamless way to integrate Yarn Spinner's narrative capabilities into Lua-based games and applications built with Dora SSR.
For more information about the Dora SSR game engine project, please visit [Dora SSR on GitHub](https://github.com/ippclub/dora-ssr).
And there is a visual novel framework built on top of Dora SSR showing the power of YarnFlow, you can visit [Dora Story](https://github.com/ippclub/dora-story) for more information.
## Key Features
- **Simple Integration:** Easily integrate interactive narratives into your Lua projects.
- **Easy Yarn Spinner to Lua Conversion:** Take your Yarn Spinner scripts and compiles them into clean, executable Lua code.
- **Compact & Extensible:** Designed to be compact and easy to extend with Lua functions.
- **Open-Source:** YarnFlow is an open-source project, welcoming contributions and improvements from the community.
## Installation
To install YarnFlow via LuaRocks:
```
luarocks install yarnflow
```
Or you can build `yarnflow.so` file with
```bash
make LUAI=/your-path/lua/include LUAL=/your-path/lua/lib
```
Then get the binary file from path `lib/yarnflow.so`.
## Usage
1. Write your story using Yarn Spinner syntax.
2. Use YarnFlow to load your Yarn script in Lua.
3. Execute the loaded script with the yarnflow runner.
Example:
```lua
local yarnCode = [[
title: Start
---
<>
Narrator: Hi, I'm the narrator for this beginner's guide!
Narrator: I'm talking to you with Yarn Spinner!
Narrator: What do you think of all this, then?
-> It's alright, I guess.
<>
<>
-> It's great. I love it.
<>
<>
===
title: Alright
---
<>
Narrator: Well, that's not very nice.
Narrator: I'm trying my best here.
-> Are you really? I don't think so.
<>
<>
-> Oh, OK. I'm sorry.
<>
<>
===
title: Love
---
<>
Narrator: Oh, you're too kind.
Narrator: I'm just doing my job.
-> You're doing a great job.
<>
Narrator: Oh, stop it, you.
Narrator: You're making me blush.
-> You're a natural.
<>
Narrator: Oh, you.
Narrator: I'm but a humble narrator.
===
]]
local yarnflow = require("yarnflow")
local variables = {
heart = 0,
}
local commands = {
dot = function(count)
print(("."):rep(count))
end,
}
local runner = yarnflow(yarnCode, "Start", variables, commands)
local function printHeart()
print("Heart: " .. variables.heart)
end
-- The advance function takes an optional integer representing the player's choice index.
-- For the first call or when no choice is needed, we pass nil.
local function advance(option)
-- First, we call runner:advance(option) to get the next part of the Yarn script.
-- This returns two values: an action type and a result.
local action, result = runner:advance(option)
-- Handle the result based on the action type.
if action == "Text" then
-- If the action is "Text", the result will be a TextResult object,
-- containing the text and any associated markers (e.g., character names).
-- Check the markers, extract the character's name (if present), and print the text.
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,
-- containing one or more options. Iterate over the options and print them,
-- allowing the player to select them later.
for i, op in ipairs(result) do
if op then
print("[" .. tostring(i) .. "]: " .. op.text)
end
end
else
-- For other actions (like errors), print the result directly.
print(result)
-- If the action is nil, it means the story is finished.
if action == nil then
printHeart()
os.exit(0)
end
end
end
-- Start the story
advance()
repeat
local input = io.read()
if input then
advance(tonumber(input))
end
until input == "exit"
```
## License
YarnFlow is released under the [MIT License](LICENSE).