Quick Start
Build your first story outline in 5 minutes: the classic Hello World, applied to StoryCADLib.
Prerequisites
- .NET 10.0 SDK
- StoryCADLib package installed (see Installation)
Step 1: Set Up Your Project
# Create a console project and add the package
dotnet new console -n HelloStoryCAD
cd HelloStoryCAD
dotnet add package StoryCADLib
# Create a folder for your script, then make sure the
# `storycad` module is importable in your environment
mkdir hello-storycad && cd hello-storycad
Step 2: Write the Code
Add the following code, in Program.cs for C#, or a file such as hello_world.py for Python:
using StoryCADLib.Services.IoC;
using StoryCADLib.Services.API;
using CommunityToolkit.Mvvm.DependencyInjection;
// 1. Initialize the service container (headless = no UI)
BootStrapper.Initialise(headless: true);
// 2. Get the API instance
var api = Ioc.Default.GetRequiredService<StoryCADApi>();
// 3. Create an empty outline
var outlineResult = await api.CreateEmptyOutline("Hello World", "Your Name", "0");
if (!outlineResult.IsSuccess)
{
Console.WriteLine($"Error: {outlineResult.ErrorMessage}");
return;
}
Console.WriteLine($"Outline created with {outlineResult.Payload.Count} elements.");
// 4. Add a protagonist
var characterResult = api.CreateNewElement("Character");
if (characterResult.IsSuccess)
{
var characterGuid = characterResult.Payload;
api.UpdateElementProperty(characterGuid, "Name", "Alex");
api.UpdateElementProperty(characterGuid, "Role", "Protagonist");
Console.WriteLine("Character added.");
}
// 5. Add an opening scene
var sceneResult = api.CreateNewElement("Scene");
if (sceneResult.IsSuccess)
{
var sceneGuid = sceneResult.Payload;
api.UpdateElementProperty(sceneGuid, "Name", "The Call to Adventure");
api.UpdateElementProperty(sceneGuid, "Setting", "A quiet village");
Console.WriteLine("Scene added.");
}
// 6. Save the outline
var saveResult = await api.WriteOutline("hello-world.stbx");
if (saveResult.IsSuccess)
{
Console.WriteLine("Saved to hello-world.stbx");
}
from storycad import StoryCAD
# 1. Initialize (headless = no UI). This object is the API entry point.
sc = StoryCAD(headless=True)
# 2. Create an empty outline; [0] is the story overview element.
overview = sc.create_empty_outline("Hello World", "Your Name", template_index="0")[0]
print(f"Outline created with {len(sc.get_all_elements())} elements.")
# 3. Add a protagonist
alex = sc.add_element(sc.item_type.Character, overview, "Alex")
sc.update_element_property(alex, "Role", "Protagonist")
print("Character added.")
# 4. Add an opening scene
sc.add_element(sc.item_type.Scene, overview, "The Call to Adventure")
print("Scene added.")
# 5. Save the outline
sc.write_outline("hello-world.stbx")
print("Saved to hello-world.stbx")
Step 3: Run It
dotnet run
python hello_world.py
Expected output:
Outline created with 3 elements.
Character added.
Scene added.
Saved to hello-world.stbx
A blank outline already contains three elements before you add anything: the Story Overview, the Trash can, and the Narrator-view folder.
Step 4: Open in StoryCAD
Open hello-world.stbx in the StoryCAD application to see your outline with the character and scene you just created.
Understanding the Code
Initialization
BootStrapper.Initialise(headless: true);
sc = StoryCAD(headless=True)
This prepares all StoryCADLib services. In C# it sets up the dependency injection container; in Python, constructing StoryCAD(headless=True) does the equivalent. The headless flag configures the library for non-UI use (console apps, web APIs, batch tools).
Getting the API
var api = Ioc.Default.GetRequiredService<StoryCADApi>();
# The StoryCAD object returned by the constructor *is* the API entry point.
sc = StoryCAD(headless=True)
StoryCADApi is the main entry point for all API operations. In C# it’s resolved from the DI container; in Python the StoryCAD(...) object you constructed is the API, so there’s no separate lookup step.
Creating an Outline
var result = await api.CreateEmptyOutline("Hello World", "Your Name", "0");
result = sc.create_empty_outline("Hello World", "Your Name", template_index="0")
Parameters:
title: the story title.author: the author name.templateIndex: the starter template, as a string from"0"to"5":"0": Blank (Story Overview only)"1": Overview and Story Problem (a Problem with a Protagonist and Antagonist)"2": Folders (Problems, Characters, Settings, Scenes)"3": External and Internal Problems"4": Protagonist and Antagonist"5": Problems and Characters
The OperationResult Pattern
In C#, every API method returns OperationResult<T>; always check IsSuccess before reading Payload. The Python wrapper takes the opposite approach: methods return their value directly and raise an exception on failure, so you use try/except instead:
if (result.IsSuccess)
{
// Access result.Payload for the returned data
var guids = result.Payload; // List<Guid> of created elements
}
else
{
// Access result.ErrorMessage for error details
Console.WriteLine(result.ErrorMessage);
}
try:
# The return value is the data directly (e.g. the list of created elements)
elements = sc.create_empty_outline("Hello World", "Your Name", template_index="0")
except Exception as error:
# The wrapper raises instead of returning an error result
print(error)
Saving
await api.WriteOutline("hello-world.stbx");
sc.write_outline("hello-world.stbx")
Saves the current outline to the specified path. The .stbx extension is the StoryCAD file format (JSON-based).
Next Steps
- API Reference: full method documentation.
- Samples: five working sample applications, starting with Story Graph Basics as the foundational walkthrough.