Using Loreline with C#
Loreline provides a C# library compatible with any C# environment that supports .NET Standard 2.1 (including Unity). This guide shows how to set up a project, load a .lor script, and handle dialogue, choices, and script completion.
Setup for .NET projects
Download loreline-csharp.zip from the GitHub releases page. The archive contains:
Loreline.dll: pre-built library targetingnetstandard2.1(compatible with .NET Core 3.0+, .NET 5+, and .NET Framework 4.7+)Loreline.sln,Loreline.csproj, and the full C# source code
You can either reference the DLL directly in your .csproj:
<Reference Include="Loreline">
<HintPath>path/to/Loreline.dll</HintPath>
</Reference>
Or add the included Loreline.csproj to your solution if you prefer to compile from source:
<ProjectReference Include="path/to/Loreline.csproj" />
Setup for Unity
Download loreline-unity.zip from the GitHub releases page. It contains a complete Unity project with the Loreline plugin that you can use as a starting point, or as a reference for integrating Loreline into your own project.
To add Loreline to an existing Unity project:
- From the archive, copy the
Assets/Plugins/Loreline/folder intoAssets/Plugins/Loreline/in your own Unity project - Store your
.lorfiles inAssets/Resources/with a.lor.txtextension (Unity requires the.txtsuffix forTextAssetloading)
Loading a script
Use Engine.Parse() to parse a .lor string. The third argument is a file handler for resolving import statements:
using Loreline;
using System.IO;
string content = File.ReadAllText("story/CoffeeShop.lor");
void HandleFile(string path, Engine.ImportsFileCallback callback)
{
string text = File.ReadAllText("story/" + path);
callback(text);
}
Script script = Engine.Parse(content, "CoffeeShop.lor", HandleFile);
Engine.Play(script, OnDialogue, OnChoice, OnFinish);
In Unity, use Resources.Load<TextAsset>() instead of file I/O:
using Loreline;
using UnityEngine;
TextAsset mainAsset = Resources.Load<TextAsset>("CoffeeShop.lor");
void HandleFile(string path, Engine.ImportsFileCallback callback)
{
string name = Path.GetFileNameWithoutExtension(path) + ".lor";
TextAsset asset = Resources.Load<TextAsset>(name);
callback(asset != null ? asset.text : null);
}
Script script = Engine.Parse(mainAsset.text, "CoffeeShop.lor", HandleFile);
Engine.Play(script, OnDialogue, OnChoice, OnFinish);
If your script has no import statements, you can omit the file handler:
Script script = Engine.Parse(content);
Handling dialogue
The dialogue handler receives an Interpreter.Dialogue struct with properties for the character, text, tags, interpreter, and a callback to advance the script:
void OnDialogue(Interpreter.Dialogue dialogue)
{
string character = dialogue.Character;
if (character != null)
{
// Resolve display name from character definition
string displayName = (string)dialogue.Interpreter.GetCharacterField(character, "name");
if (displayName != null) character = displayName;
Console.WriteLine(character + ": " + dialogue.Text);
}
else
{
// Narrative text (no character)
Console.WriteLine(dialogue.Text);
}
dialogue.Callback();
}
Handling choices
The choice handler receives an Interpreter.Choice struct with an array of ChoiceOption items. Each option has a Text field and an Enabled field. Call the callback with the index of the selected choice:
void OnChoice(Interpreter.Choice choice)
{
for (int i = 0; i < choice.Options.Length; i++)
{
if (choice.Options[i].Enabled)
{
Console.WriteLine(" [" + (i + 1) + "] " + choice.Options[i].Text);
}
}
// Read player input
string input = Console.ReadLine();
if (int.TryParse(input, out int selected) && selected >= 1 && selected <= choice.Options.Length)
{
choice.Callback(selected - 1);
}
}
Handling script completion
The finish handler is called when the script reaches its end:
void OnFinish(Interpreter.Finish finish)
{
Console.WriteLine("--- The End ---");
}
Complete example
Here is a complete .NET console application that loads and plays a Loreline script:
using System;
using System.IO;
using Loreline;
class Program
{
static string storyDir = "story/";
static void Main(string[] args)
{
string content = File.ReadAllText(storyDir + "CoffeeShop.lor");
Script script = Engine.Parse(content, "CoffeeShop.lor", HandleFile);
if (script != null)
{
Engine.Play(script, OnDialogue, OnChoice, OnFinish);
}
}
static void HandleFile(string path, Engine.ImportsFileCallback callback)
{
try
{
callback(File.ReadAllText(storyDir + path));
}
catch
{
callback(null);
}
}
static void OnDialogue(Interpreter.Dialogue dialogue)
{
string character = dialogue.Character;
if (character != null)
{
string name = (string)dialogue.Interpreter.GetCharacterField(character, "name");
if (name != null) character = name;
Console.WriteLine(character + ": " + dialogue.Text);
}
else
{
Console.WriteLine(dialogue.Text);
}
Console.WriteLine();
dialogue.Callback();
}
static void OnChoice(Interpreter.Choice choice)
{
for (int i = 0; i < choice.Options.Length; i++)
{
if (choice.Options[i].Enabled)
{
Console.WriteLine(" [" + (i + 1) + "] " + choice.Options[i].Text);
}
}
Console.Write("> ");
string input = Console.ReadLine();
if (int.TryParse(input, out int selected) && selected >= 1 && selected <= choice.Options.Length)
{
choice.Callback(selected - 1);
}
}
static void OnFinish(Interpreter.Finish finish)
{
Console.WriteLine("--- The End ---");
}
}
Going further
For a full Unity project with UI Toolkit, animations, and styled output, the loreline-unity.zip download from the GitHub releases includes a complete working sample.