Using ZodiacsTextEngine in a custom Application

The ZodiacsTextEngine provides a simple .NET API that lets you implement your own text interface to capture user inputs and render the output.

Installation

Depending on the type of application you're creating, there are various ways to install the ZodiacsTextEngine:

NuGet Package

To start using the Text Engine, install the ZodiacsTextEngine NuGet package.
Refer to the installation instructions to add the package to your project.

Unity Package

In case of a Unity game project, the ZodiacsTextEngine can be installed using the separate Unity Package.

Manual Installation

If both options are unavailable, you can still download the repository and copy the files from the ZodiacsTextEngine/source directory directly into your project.

Initializing the Text Engine

To initialize and start the ZodiacsTextEngine, simply call:

ITextInterface textInterface = new (Your ITextInterface implementation); ContentLoader loader = new StandardContentLoader(); //Or your own content loader bool debug = false; TextEngine.Initialize(textInterface, loader, debug); TextEngine.StartGame();

Implementing ITextInterface

To provide your own text interface, create a class that implements ZodiacsTextEngine.ITextInterface, then pass it as a parameter to the engine during initialization as mentioned above.

Members of ITextInterface

The ITextInterface requires an implementation of the following members:

Asynchronous Methods

Some methods in the ZodiacsTextEngine are asynchronous and return a Task that can be awaited. Asynchronous implementations can be used to wait for user input, a specific event, or a certain duration. If an implementation does not require asynchronous behavior, it should return a completed task using Task.CompletedTask. When using a normal console window, the use of async/await when requesting input is not strictly necessary, however, in GUI applications or game engines, asynchronous methods are often required to avoid blocking the main thread.

//Example of an asynchronous method implementation public async Task<ReadInput>() { //Wait until the user provides input //PlayerInput.Read() here has the return type Task<string> string input = await PlayerInput.Read(); return input; } //Example of a synchronous method implementation public Task<string> ReadInput() { //Always return "house" immediately return Task.FromResult("house"); }

Using a custom ContentLoader

The standard content loader is capable of loading story files from either a directory or a zip file from a given path. In the event that you need to load content from a different source (e.g. from an URL, game asset, etc.), you can create a custom content loader that supplies story files to the engine in a different way.

To register the custom content loader, it needs to be passed during engine initialization as mentioned above.

Example

using ZodiacsTextEngine; public class MyContentLoader : ContentLoader { private string rootDirectory; public MyContentLoader(string rootDirectory) { //Example constructor this.rootDirectory = rootDirectory; } protected override IEnumerable<Room> LoadRooms() { // Implement your own room file loading logic here // Each yield should return a new room yield return Room.Parse(story, "room1", Load(rootDirectory + "/room1")); yield return Room.Parse(story, "room2", Load(rootDirectory + "/room2")); yield return Room.Parse(story, "room3", Load(rootDirectory + "/room3")); SetStartRoom("room1"); } protected override IEnumerable<(string, FunctionDelegate)> LoadFunctions() { // Implement your own function loading logic or hardcode them here yield return ("MyFunction", async args => { // Your function logic here return "Function Result"; }); yield return ("AnotherFunction", async args => { // Another function logic here return "Another Result"; }); } }