Resource API Workflows
This page provides step-by-step code examples for each multi-step resource workflow. For an overview of what each resource provides, see Resource Data and Writing Tools.
Conflict Builder (4 Steps)
Build a structured conflict description for a Problem’s protagonist or antagonist.
// Step 1: Get conflict categories
var categories = api.GetConflictCategories().Payload;
// ["Relationship", "Situational", "Inner Conflict", "Paranormal",
// "Criminal activities", "Mystery and suspense", "Social drama", "Romantic"]
// Step 2: Get subcategories for a category
var subcategories = api.GetConflictSubcategories("Relationship").Payload;
// ["Lovers", "Family", "Friends", "Rivals", ...]
// Step 3: Get example conflicts for the subcategory
var examples = api.GetConflictExamples("Relationship", "Lovers").Payload;
// ["Jealousy threatens to destroy a passionate affair",
// "A secret from the past resurfaces", ...]
// Step 4: Apply to a Problem element
var problemGuid = /* GUID of an existing Problem */;
// Apply to protagonist's conflict
api.ApplyConflictToProtagonist(problemGuid, examples.First());
// Or apply to antagonist's conflict
api.ApplyConflictToAntagonist(problemGuid, "Custom conflict text is also valid");
# Step 1: Get conflict categories
categories = sc.get_conflict_categories()
# ["Relationship", "Situational", "Inner Conflict", "Paranormal",
# "Criminal activities", "Mystery and suspense", "Social drama", "Romantic"]
# Step 2: Get subcategories for a category
subcategories = sc.get_conflict_subcategories("Relationship")
# ["Lovers", "Family", "Friends", "Rivals", ...]
# Step 3: Get example conflicts for the subcategory
examples = sc.get_conflict_examples("Relationship", "Lovers")
# ["Jealousy threatens to destroy a passionate affair",
# "A secret from the past resurfaces", ...]
# Step 4: Apply to a Problem element
problem = ... # an existing Problem element handle
# Apply to protagonist's conflict
sc.apply_conflict_to_protagonist(problem, examples[0])
# Or apply to antagonist's conflict
sc.apply_conflict_to_antagonist(problem, "Custom conflict text is also valid")
Presenting to Users or LLMs
For interactive applications, present each step as a choice:
// Show categories
Console.WriteLine("Choose a conflict category:");
var categories = api.GetConflictCategories().Payload.ToList();
for (int i = 0; i < categories.Count; i++)
Console.WriteLine($" {i + 1}. {categories[i]}");
// After user selects, show subcategories
var selected = categories[userChoice - 1];
var subcategories = api.GetConflictSubcategories(selected).Payload.ToList();
Console.WriteLine($"\nSubcategories for '{selected}':");
for (int i = 0; i < subcategories.Count; i++)
Console.WriteLine($" {i + 1}. {subcategories[i]}");
// After user selects subcategory, show examples
var selectedSub = subcategories[userChoice - 1];
var examples = api.GetConflictExamples(selected, selectedSub).Payload.ToList();
Console.WriteLine($"\nExamples for '{selected}' > '{selectedSub}':");
foreach (var example in examples)
Console.WriteLine($" - {example}");
# Show categories
print("Choose a conflict category:")
categories = sc.get_conflict_categories()
for i, category in enumerate(categories):
print(f" {i + 1}. {category}")
# After user selects, show subcategories
selected = categories[user_choice - 1]
subcategories = sc.get_conflict_subcategories(selected)
print(f"\nSubcategories for '{selected}':")
for i, subcategory in enumerate(subcategories):
print(f" {i + 1}. {subcategory}")
# After user selects subcategory, show examples
selected_sub = subcategories[user_choice - 1]
examples = sc.get_conflict_examples(selected, selected_sub)
print(f"\nExamples for '{selected}' > '{selected_sub}':")
for example in examples:
print(f" - {example}")
For an LLM agent, provide all categories in a single prompt and let it choose, or walk through the steps in a multi-turn conversation.
Key Questions (2 Steps)
Retrieve development prompts organized by element type and topic.
// Step 1: Discover which element types have key questions
var elementTypes = api.GetKeyQuestionElements().Payload;
// ["Character", "Problem", "Scene", "Setting", "Overview"]
// Step 2: Get questions for a specific type
var questions = api.GetKeyQuestions("Character").Payload;
foreach (var (topic, question) in questions)
{
Console.WriteLine($"[{topic}] {question}");
}
// [Motivation] What does this character want more than anything?
// [Backstory] What event from their past shaped who they are today?
// [Relationships] Who is the most important person in their life?
// ...
# Step 1: Discover which element types have key questions
element_types = sc.get_key_question_elements()
# ["Character", "Problem", "Scene", "Setting", "Overview"]
# Step 2: Get questions for a specific type
questions = sc.get_key_questions("Character")
for q in questions:
print(f"[{q.topic}] {q.question}")
# [Motivation] What does this character want more than anything?
# [Backstory] What event from their past shaped who they are today?
# [Relationships] Who is the most important person in their life?
# ...
Using Key Questions for Element Development
Key questions are ideal for guiding an author (or LLM) through element creation:
// Create a character, then use key questions to flesh it out
var charResult = api.AddElement(StoryItemType.Character, overviewGuid, "Detective Morgan");
var charGuid = charResult.Payload;
var questions = api.GetKeyQuestions("Character").Payload;
foreach (var (topic, question) in questions)
{
// Present question to user or LLM
Console.WriteLine($"\n{topic}: {question}");
var answer = GetUserInput(); // or LLM response
// Map topic to property (your application logic)
// e.g., "Motivation" → ProtGoal, "Backstory" → BackStory
if (topic == "Backstory" && !string.IsNullOrEmpty(answer))
api.UpdateElementProperty(charGuid, "BackStory", answer);
}
# Create a character, then use key questions to flesh it out
character = sc.add_element(sc.item_type.Character, overview, "Detective Morgan")
questions = sc.get_key_questions("Character")
for q in questions:
# Present question to user or LLM
print(f"\n{q.topic}: {q.question}")
answer = get_user_input() # or LLM response
# Map topic to property (your application logic)
# e.g., "Motivation" → ProtGoal, "Backstory" → BackStory
if q.topic == "Backstory" and answer:
sc.update_element_property(character, "BackStory", answer)
Master Plots (3 Steps)
Explore Tobias’s 20 Master Plots to find a structure for your story.
// Step 1: List all master plots
var plotNames = api.GetMasterPlotNames().Payload;
// ["Quest", "Adventure", "Pursuit", "Rescue", "Escape", "Revenge", ...]
// Step 2: Read the notes for a plot
var notes = api.GetMasterPlotNotes("Quest").Payload;
Console.WriteLine(notes);
// "The Quest plot sends the protagonist on a journey to find something..."
// Step 3: Get the scene breakdown
var scenes = api.GetMasterPlotScenes("Quest").Payload;
foreach (var (sceneTitle, sceneNotes) in scenes)
{
Console.WriteLine($"\n{sceneTitle}");
Console.WriteLine($" {sceneNotes}");
}
// Call to Adventure
// The hero receives a call to leave their ordinary world...
// Crossing the Threshold
// The hero commits to the journey and enters the special world...
// ...
# Step 1: List all master plots
plot_names = sc.get_master_plot_names()
# ["Quest", "Adventure", "Pursuit", "Rescue", "Escape", "Revenge", ...]
# Step 2: Read the notes for a plot
notes = sc.get_master_plot_notes("Quest")
print(notes)
# "The Quest plot sends the protagonist on a journey to find something..."
# Step 3: Get the scene breakdown
scenes = sc.get_master_plot_scenes("Quest")
for scene in scenes:
print(f"\n{scene.title}")
print(f" {scene.notes}")
# Call to Adventure
# The hero receives a call to leave their ordinary world...
# Crossing the Threshold
# The hero commits to the journey and enters the special world...
# ...
Creating Scenes from a Master Plot
Use the scene breakdown to populate an outline:
var plotScenes = api.GetMasterPlotScenes("Quest").Payload;
var overviewGuid = /* GUID of the StoryOverview */;
foreach (var (title, notes) in plotScenes)
{
var sceneResult = api.AddElement(
StoryItemType.Scene,
overviewGuid.ToString(),
title);
if (sceneResult.IsSuccess)
{
api.UpdateElementProperty(sceneResult.Payload, "Notes", notes);
}
}
plot_scenes = sc.get_master_plot_scenes("Quest")
overview = ... # the StoryOverview element handle
for plot_scene in plot_scenes:
# add_element raises on failure instead of returning a result object
scene = sc.add_element(sc.item_type.Scene, overview, plot_scene.title)
sc.update_element_property(scene, "Notes", plot_scene.notes)
Stock Scenes (2 Steps)
Browse scene templates organized by genre or purpose.
// Step 1: List categories
var categories = api.GetStockSceneCategories().Payload;
// ["Action", "Romance", "Mystery", "Horror", ...]
// Step 2: Get scenes for a category
var scenes = api.GetStockScenes("Mystery").Payload;
foreach (var scene in scenes)
{
Console.WriteLine($" - {scene}");
}
// - The detective discovers a vital clue at the crime scene
// - A witness reveals a contradictory account
// - The suspect's alibi falls apart under questioning
// ...
# Step 1: List categories
categories = sc.get_stock_scene_categories()
# ["Action", "Romance", "Mystery", "Horror", ...]
# Step 2: Get scenes for a category
scenes = sc.get_stock_scenes("Mystery")
for scene in scenes:
print(f" - {scene}")
# - The detective discovers a vital clue at the crime scene
# - A witness reveals a contradictory account
# - The suspect's alibi falls apart under questioning
# ...
Creating a Scene from Stock
var stockScenes = api.GetStockScenes("Mystery").Payload.ToList();
var selectedScene = stockScenes[0]; // or user's choice
var sceneResult = api.AddElement(
StoryItemType.Scene,
overviewGuid.ToString(),
"Crime Scene Discovery");
if (sceneResult.IsSuccess)
{
api.UpdateElementProperty(sceneResult.Payload, "Notes", selectedScene);
}
stock_scenes = sc.get_stock_scenes("Mystery")
selected_scene = stock_scenes[0] # or user's choice
# add_element raises on failure instead of returning a result object
scene = sc.add_element(sc.item_type.Scene, overview, "Crime Scene Discovery")
sc.update_element_property(scene, "Notes", selected_scene)
Combining Workflows
Resources work best when combined. Here’s an example that creates a Problem with conflict and structure:
// Create a problem
var problemResult = api.AddElement(
StoryItemType.Problem,
overviewGuid.ToString(),
"The Missing Artifact");
var problemGuid = problemResult.Payload;
// Use the Conflict Builder to set up protagonist conflict
var examples = api.GetConflictExamples("Mystery and suspense", "Whodunit").Payload;
api.ApplyConflictToProtagonist(problemGuid, examples.First());
// Apply a beat sheet for structure
api.ApplyBeatSheetToProblem(problemGuid, "Three Act Structure");
// Use master plot scenes to inspire the beat assignments
var plotScenes = api.GetMasterPlotScenes("Quest").Payload.ToList();
// Create scenes and assign them to beats: see Beat Sheet Operations
# Create a problem
problem = sc.add_element(sc.item_type.Problem, overview, "The Missing Artifact")
# Use the Conflict Builder to set up protagonist conflict
examples = sc.get_conflict_examples("Mystery and suspense", "Whodunit")
sc.apply_conflict_to_protagonist(problem, examples[0])
# Apply a beat sheet for structure
sc.apply_beat_sheet_to_problem(problem, "Three Act Structure")
# Use master plot scenes to inspire the beat assignments
plot_scenes = sc.get_master_plot_scenes("Quest")
# Create scenes and assign them to beats: see Beat Sheet Operations
See Beat Sheet Operations for the complete beat sheet workflow.