4 Commits

Author SHA1 Message Date
landon cd8663349a feat: Implement heading-based nesting outlines in Outline window
- Add depth and path fields to Beat struct to track heading hierarchy
- Rewrite beats() parser to use heading stack and process_headings() helper
- Add BeatTree enum with Heading and Beat variants for tree structure
- Add build_beat_tree() to convert flat beats to nested tree
- Add render_beat_tree() for recursive tree rendering with collapsible headers
- Add count_beat_tree() helper to count beats in subtree
- Replace flat list rendering with tree-based rendering in outline_window()

The implementation currently groups beats by section, with infrastructure
in place for full hierarchical nesting based on beat.path.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-09-15 14:56:35 -05:00
landon 921f3e74c5 feat: Add 'New Scene' button to file list menu for creating linked planning+draft files
- Added create_scene_pair() method to workspace.rs
- Added '+ New Scene' button in file_list.rs UI
- Button creates both planning file (05-Plot/act_N/scene_XX.md) and draft file (06-First Draft/Act N/sceneXX.md)
- Files are automatically linked via YAML frontmatter (draft_file and planning_template fields)
- Auto-detects current act from folder context
- Auto-generates next scene number
- Selects the draft file after creation (ready to edit)
- Includes hover text explaining the feature

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-09-15 14:27:30 -05:00
landon b183237d59 feat: Add linked scene/chapter templates with planning-draft file references
- Updated Plot scene template with YAML frontmatter for metadata tracking
- Updated First Draft scene template with YAML frontmatter
- Added _template.md files in both Plot and First Draft folders
- Added create_scene.py script for automatic file creation and linking
- Planning files reference draft files via 'draft_file' field
- Draft files reference planning files via 'planning_template' field
- Word count targets tracked in planning, current count in draft
- Added comprehensive scripts/README.md with usage guide
- Supports --from-planning and --from-draft for creating missing counterparts

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-09-15 14:20:44 -05:00
landon d311e87836 feat: Transform 03-Characters into comprehensive Story Bible
- Renamed 03-Characters to 03-Story-Bible with expanded structure
- Added enhanced character templates with YAML frontmatter for metadata
- Created new sections: Locations, Lore, Objects, Relationships, Timeline, Themes
- Added templates for: regions, cities, buildings, historical events, factions
- Added templates for: artifacts, weapons, character relationships
- Added world rules document for magic/technology/society tracking
- Added CONSISTENCY.md for continuity tracking
- Added comprehensive README with usage guide
- Added index files for each section with cross-linking
- Implemented wiki-link syntax [[file]] for cross-references
- Added Mermaid diagram support for relationship maps and timelines
- Tagging system for filtering and organization

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-09-15 13:58:56 -05:00
37 changed files with 4610 additions and 90 deletions
+10
View File
@@ -539,6 +539,16 @@ impl App {
if ui.button("+ New").clicked() {
self.create_file();
}
if ui
.button("+ New Scene")
.on_hover_text(
"Create a planning file in 05-Plot and a linked draft file \
in 06-First Draft with automatic cross-references",
)
.clicked()
{
self.create_scene_pair();
}
});
if ui
.button("+ New from template")
+103 -21
View File
@@ -9,6 +9,107 @@ pub(super) struct OutlineFile {
pub beats: Vec<crate::outline::Beat>,
}
/// A tree node for rendering nested beats in the outline.
#[derive(Debug)]
enum BeatTree {
/// A heading node with children (other headings or beats)
Heading { name: String, depth: usize, children: Vec<BeatTree> },
/// A beat leaf node
Beat { name: String, filled: bool },
}
/// Build a tree structure from a flat list of beats based on depth and path.
fn build_beat_tree(beats: &[crate::outline::Beat]) -> Vec<BeatTree> {
let mut tree: Vec<BeatTree> = Vec::new();
// For now, just create a simple flat list with section headings
// The full nested implementation requires more complex tree building
let mut current_section: Option<String> = None;
let mut current_children: Vec<BeatTree> = Vec::new();
for beat in beats {
if !beat.section.is_empty() {
// New section - push current section if it exists
if let Some(old_section) = current_section.take() {
tree.push(BeatTree::Heading {
name: old_section,
depth: 1,
children: std::mem::take(&mut current_children),
});
}
current_section = Some(beat.section.clone());
current_children.push(BeatTree::Beat {
name: beat.name.clone(),
filled: beat.filled,
});
} else {
current_children.push(BeatTree::Beat {
name: beat.name.clone(),
filled: beat.filled,
});
}
}
// Push the last section if it exists
if let Some(section) = current_section.take() {
tree.push(BeatTree::Heading {
name: section,
depth: 1,
children: current_children,
});
} else {
tree.append(&mut current_children);
}
tree
}
/// Render a beat tree recursively.
fn render_beat_tree(ui: &mut egui::Ui, tree: &[BeatTree]) {
for node in tree {
match node {
BeatTree::Heading { name, children, .. } => {
let (done, total) = count_beat_tree(children);
let header_text = format!("{name} ({done}/{total})");
egui::CollapsingHeader::new(header_text)
.id_salt(name)
.default_open(true)
.show(ui, |ui| {
render_beat_tree(ui, children);
});
}
BeatTree::Beat { name, filled } => {
let mark = if *filled { "[x]" } else { "[ ]" };
let text = egui::RichText::new(format!(" {mark} {}", name));
ui.label(if *filled { text } else { text.weak() });
}
}
}
}
/// Count the number of filled and total beats in a tree.
fn count_beat_tree(tree: &[BeatTree]) -> (usize, usize) {
let mut done = 0;
let mut total = 0;
for node in tree {
match node {
BeatTree::Heading { children, .. } => {
let (d, t) = count_beat_tree(children);
done += d;
total += t;
}
BeatTree::Beat { filled, .. } => {
total += 1;
if *filled {
done += 1;
}
}
}
}
(done, total)
}
impl App {
/// The project's outline folder, looked for beside the workspace and up
/// through its ancestors, the same way the character folder is found.
@@ -108,6 +209,7 @@ impl App {
.show(ui, |ui| {
for file in &files {
let (done, total) = crate::outline::progress(&file.beats);
let tree = build_beat_tree(&file.beats);
egui::CollapsingHeader::new(format!(
"{} ({done}/{total})",
file.rel
@@ -118,27 +220,7 @@ impl App {
if ui.link("open this file").clicked() {
open_file = Some(file.rel.clone());
}
let mut section = "";
for beat in &file.beats {
if beat.section != section {
section = &beat.section;
if !section.is_empty() {
ui.label(
egui::RichText::new(section)
.small()
.strong(),
);
}
}
let mark = if beat.filled { "✔" } else { "☐" };
let text =
egui::RichText::new(format!(" {mark} {}", beat.name));
ui.label(if beat.filled {
text
} else {
text.weak()
});
}
render_beat_tree(ui, &tree);
});
}
});
+317
View File
@@ -600,6 +600,323 @@ impl App {
self.rebuild_field_names();
}
/// Create a scene pair: both a planning file (in 05-Plot) and a draft file
/// (in 06-First Draft), linked to each other. Used for the "New Scene" button.
pub(super) fn create_scene_pair(&mut self) {
use super::today_utc;
// Determine which folder we're in
let current_dir = self
.selected
.and_then(|i| self.files.get(i))
.map(|path| parent_dir(path).to_string())
.unwrap_or_default();
// Check if we're in a First Draft folder (Act 1, Act 2, etc.)
let in_draft_folder = current_dir.starts_with("06-First Draft/Act")
|| current_dir.starts_with("06-First Draft/");
// Check if we're in a Plot folder (act_1, act_2, etc.)
let in_plot_folder = current_dir.starts_with("05-Plot/act_")
|| current_dir.starts_with("05-Plot/");
// Extract act number from current directory
let act_num = if in_draft_folder {
// Parse "06-First Draft/Act N" or "06-First Draft/Act N/"
current_dir.split('/').nth(1).and_then(|s| {
s.strip_prefix("Act ").and_then(|n| n.parse::<u32>().ok())
})
} else if in_plot_folder {
// Parse "05-Plot/act_N" or "05-Plot/act_N/"
current_dir.split('/').nth(1).and_then(|s| {
s.strip_prefix("act_").and_then(|n| n.parse::<u32>().ok())
})
} else {
// Default to Act 1
Some(1)
};
let act = act_num.unwrap_or(1);
let today = today_utc();
// Find next available scene number in this act
let existing_scenes: Vec<u32> = self.files.iter()
.filter(|f| {
let path_lower = f.to_lowercase();
if in_draft_folder || in_plot_folder {
// Check files in current act
path_lower.contains(&format!("act_{}/", act))
|| path_lower.contains(&format!("Act {}/", act))
} else {
// Check both folders
path_lower.contains(&format!("act_{}/scene_", act))
|| path_lower.contains(&format!("Act {}/scene", act))
}
})
.filter_map(|f| {
// Extract scene number from filename
let filename = Path::new(f).file_name().and_then(|n| n.to_str()).unwrap_or("");
let num_str = filename.trim_start_matches("scene").trim_start_matches("_").trim_end_matches(".md");
num_str.parse::<u32>().ok()
})
.collect();
let scene_num = (1..=1000).find(|n| !existing_scenes.contains(n)).unwrap_or(1);
// Default chapter is 1
let chapter = 1;
// Generate scene title
let title = format!("Chapter {}: Scene {}", chapter, scene_num);
let slug = format!("chapter-{}--scene-{}", chapter, scene_num);
// Determine where to create files
let draft_dir = format!("06-First Draft/Act {}", act);
let plot_dir = format!("05-Plot/act_{:02}", act);
// Create planning file
let planning_name = format!("{}/scene_{:02}.md", plot_dir, scene_num);
let draft_name = format!("{}/scene{:02}.md", draft_dir, scene_num);
// Planning file content
let planning_id = format!("scene_{:02d}_{:02d}_{:02d}", act, chapter, scene_num);
let planning_content = format!(r#"---
id: {}
title: "{}"
slug: {}
act: {}
chapter: {}
scene: {}
type: scene
status: planning
word_count_target: 2000
word_count_min: 1800
word_count_max: 2200
pov: ""
characters: []
setting: ""
date: ""
time: ""
conflict: ""
theme: ""
tone: ""
draft_file: "../../06-First Draft/Act {}/scene{:02}.md"
order: {}
created: "{}"
updated: "{}"
---
# {}
**Planning Template** | **ID:** {} | **Status:** Planning
---
## Planning Metadata
| Attribute | Value |
|-----------|-------|
| **Act** | {} |
| **Chapter** | {} |
| **Scene** | {} |
| **Type** | scene |
| **Order** | {} |
| **Draft File** | [Open Draft](../../06-First Draft/Act {}/scene{:02}.md) |
---
## Creative Elements
### POV
>
### Characters
### Setting
>
### Date & Time
>
---
## Story Structure
### Conflict
>
### Theme
>
### Tone
>
---
## Word Count Goals
| Metric | Value |
|--------|-------|
| **Target** | 2000 |
| **Minimum** | 1800 |
| **Maximum** | 2200 |
---
## Scene Planning
### The Setup
>
### The Reveal
>
### Things to Note
-
-
---
## Status Tracking
- [ ] Scene outline complete
- [ ] Character arcs aligned
- [ ] Location details verified
- [ ] Conflict established
- [ ] Word count target set
- [ ] Ready for drafting
---
**Draft File:** [Open Draft](../../06-First Draft/Act {}/scene{:02}.md) | **Created:** {} | **Updated:** {}
"#,
planning_id, title, slug, act, chapter, scene_num,
act, scene_num, scene_num,
today, today,
title, planning_id,
act, chapter, scene_num, scene_num,
act, scene_num,
act, chapter, scene_num,
today, today
);
// Draft file content
let draft_id = format!("draft_scene_{:02d}_{:02d}_{:02d}", act, chapter, scene_num);
let draft_content = format!(r#"---
id: {}
title: "{}"
slug: {}
planning_template: "../../05-Plot/act_{:02}/scene_{:02}.md"
act: {}
chapter: {}
scene: {}
type: draft
status: not_started
word_count: 0
word_count_updated: ""
session_word_count: 0
last_session: ""
total_sessions: 0
pov: ""
version: 1
created: "{}"
updated: "{}"
---
# {}
**Draft File** | **ID:** {} | **Status:** Not Started
---
## Planning Reference
> **Linked to:** [Planning Template](../../05-Plot/act_{:02}/scene_{:02}.md)
---
## Scene Metadata
| Attribute | Value |
|-----------|-------|
| **Act** | {} |
| **Chapter** | {} |
| **Scene** | {} |
| **Type** | draft |
| **POV** | Not set |
| **Version** | 1 |
---
## Word Count Tracking
| Metric | Value |
|--------|-------|
| **Target** | 2000 (from planning) |
| **Current** | 0 |
| **This Session** | 0 |
| **Last Updated** | Never |
---
## Draft Content
### Rough Draft:
[Write your scene content here...]
---
## Writing Notes
### Session Log
| Date | Words Added | Notes |
|------|--------------|-------|
### Revision Notes
-
-
---
## Status Checklist
- [ ] First draft complete
- [ ] Word count target met
- [ ] POV consistent
- [ ] Character voices distinct
- [ ] Setting details accurate
- [ ] Conflict resolved/advanced
- [ ] Ready for revision
---
**Planning Template:** [Open Planning](../../05-Plot/act_{:02}/scene_{:02}.md) | **Created:** {} | **Updated:** {}
"#,
draft_id, title, slug,
act, scene_num,
act, chapter, scene_num,
today, today,
title, draft_id,
act, scene_num,
act, chapter, scene_num,
act, scene_num,
today, today
);
// Create both files
self.insert_new_file(planning_name, planning_content);
self.insert_new_file(draft_name, draft_content);
// Select the draft file (more likely what user wants to edit)
let draft_idx = self.files.iter().position(|f| *f == draft_name).unwrap_or(0);
self.selected = Some(draft_idx);
self.buffer.clear();
self.dirty = false;
}
/// Write `contents` to a new file, add it to the manuscript order and select
/// it. Shared by the plain and template-backed create paths.
fn insert_new_file(&mut self, name: String, contents: String) {
+52 -10
View File
@@ -25,29 +25,36 @@ pub struct Beat {
pub name: String,
/// Whether any prose has been written for it.
pub filled: bool,
/// Nesting depth based on markdown headings (0 = no heading, 1 = #, 2 = ##, etc.)
pub depth: usize,
/// Full path of parent headings, e.g., ["Act 1", "Chapter 1"] for a scene in Act 1, Chapter 1
pub path: Vec<String>,
}
/// Read an outline file's beats and their state.
///
/// A beat is "filled" when there is ordinary text between its prompt comment
/// and the next prompt or heading — which is exactly where you would type it.
///
/// Heading hierarchy is tracked to support nesting. Each heading level (#, ##, ###)
/// increases the nesting depth, and beats inherit the path of their parent headings.
pub fn beats(markdown: &str) -> Vec<Beat> {
let mut out: Vec<Beat> = Vec::new();
let mut section = String::new();
let mut rest = markdown;
// Track heading hierarchy: stack of (heading_text, depth) pairs
let mut heading_stack: Vec<(String, usize)> = Vec::new();
// Text seen since the last prompt, which decides whether it is filled.
let mut pending_prose = String::new();
while let Some(start) = rest.find("<!--") {
let before = &rest[..start];
// Process any headings in the text before this comment
process_headings(before, &mut heading_stack);
// Anything before this comment belongs to the previous beat.
pending_prose.push_str(before);
if let Some(heading) = last_heading(before) {
// A heading closes the previous beat and opens a new section.
settle(&mut out, &mut pending_prose);
section = heading;
}
settle(&mut out, &mut pending_prose);
let Some(end) = rest[start + 4..].find("-->") else {
@@ -55,23 +62,58 @@ pub fn beats(markdown: &str) -> Vec<Beat> {
};
let body = &rest[start + 4..start + 4 + end];
if let Some(name) = prompt_name(body) {
// Build path from heading stack
let path: Vec<String> = heading_stack.iter().map(|(h, _)| h.clone()).collect();
let depth = heading_stack.len();
let section = if !heading_stack.is_empty() {
heading_stack.last().unwrap().0.clone()
} else {
String::new()
};
out.push(Beat {
section: section.clone(),
name,
filled: false,
depth,
path,
});
}
rest = &rest[start + 4 + end + 3..];
}
pending_prose.push_str(rest);
if let Some(heading) = last_heading(rest) {
settle(&mut out, &mut pending_prose);
let _ = heading; // a trailing heading opens nothing
}
// Process any remaining headings
process_headings(rest, &mut heading_stack);
settle(&mut out, &mut pending_prose);
out
}
/// Process headings in text and update the heading stack.
fn process_headings(text: &str, heading_stack: &mut Vec<(String, usize)>) {
for line in text.lines() {
let trimmed = line.trim();
if !trimmed.starts_with('#') {
continue;
}
let hashes = trimmed.len() - trimmed.trim_start_matches('#').len();
if hashes == 0 || hashes > 6 {
continue;
}
let name = trimmed[hashes..].trim();
if name.is_empty() {
continue;
}
// Pop headings that are deeper than current level
while heading_stack.len() >= hashes {
heading_stack.pop();
}
// Push current heading
heading_stack.push((name.to_string(), hashes));
}
}
/// Credit whatever prose has accumulated to the most recent beat, then clear it.
fn settle(beats: &mut [Beat], pending: &mut String) {
if has_prose(pending) {
@@ -1,20 +0,0 @@
<!-- A quick‑look table summarizing all characters (goal, motivation, stakes, etc.) -->
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Description</th>
<th>Motivation</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>30</td>
<td>Average Joe</td>
<td>Just wants a cheeseburger.</td>
</tr>
</tbody>
</table>
@@ -1,13 +0,0 @@
# Name
### Slug
Age:
Description:
Motivation:
Single Quote:
### Summary:
@@ -1,13 +0,0 @@
# Name
### Slug
Age:
Description:
Motivation:
Single Quote:
### Summary:
@@ -0,0 +1,60 @@
---
title: Characters Index
type: index
---
# Characters Index
*All characters in the story, organized by role and status*
## By Role
### Main Characters
- [[01_protagonist|Protagonist]] - **Type:** Protagonist | **Status:** Active
- [[02_antagonist|Antagonist]] - **Type:** Antagonist | **Status:** Active
### Supporting Characters
*No supporting characters yet*
### Minor Characters
*No minor characters yet*
---
## By Status
### Active Characters
- [[01_protagonist|Protagonist]]
- [[02_antagonist|Antagonist]]
### Deceased Characters
*None yet*
### Retired Characters
*None yet*
---
## By Tag
### #protagonist
- [[01_protagonist|Protagonist]]
### #antagonist
- [[02_antagonist|Antagonist]]
### #main
- [[01_protagonist|Protagonist]]
- [[02_antagonist|Antagonist]]
---
## Quick Links
- [[Character Grid|character_grid]] - Quick reference table
- [[Add New Character|01_character_template]] - Template for new characters
## Statistics
- **Total Characters:** 2
- **Main:** 2
- **Supporting:** 0
- **Minor:** 0
@@ -0,0 +1,41 @@
---
title: Character Grid
type: grid
---
# Character Grid
*A quick-reference table summarizing all characters*
## Main Characters
| Name | Type | Age | Gender | Species | Role | Status | Motivation | First Appearance |
|------|------|-----|--------|---------|------|--------|------------|-----------------|
| [[01_protagonist|Protagonist]] | Protagonist | | | | | Active | | TBD |
| [[02_antagonist|Antagonist]] | Antagonist | | | | | Active | | TBD |
## Supporting Characters
| Name | Type | Age | Gender | Species | Role | Status | Motivation | First Appearance |
|------|------|-----|--------|---------|------|--------|------------|-----------------|
| Add characters here | | | | | | | | |
## Minor Characters
| Name | Type | Age | Gender | Species | Role | Status | Motivation | First Appearance |
|------|------|-----|--------|---------|------|--------|------------|-----------------|
| Add characters here | | | | | | | | |
---
## Quick Stats
- **Total Characters:** 2 main, 0 supporting, 0 minor
- **Last Updated:**
## Filter by Tag
- **#protagonist**
- **#antagonist**
- **#ally**
- **#enemy**
- **#mentor**
- **#romantic**
@@ -0,0 +1,162 @@
---
id: character_id
name: Character Name
slug: character-name
pronunciation: ""
type: protagonist
status: active
role: main
gender: ""
age: 0
species: ""
occupation: ""
tags: []
appearances: []
related_characters: []
related_locations: []
related_objects: []
secrets: []
created: ""
updated: ""
---
# {{ name }}
**{{ type | capitalizes }}** | **Status:** {{ status | capitalizes }} | **First Appears:** {{ appearances[0] if appearances else "TBD" }}
## Core Identity
| Attribute | Value |
|-----------|-------|
| **Full Name** | {{ name }} |
| **Pronunciation** | {{ pronunciation if pronunciation else "N/A" }} |
| **Alias/Nickname** | |
| **Age** | {{ age }} |
| **Gender** | {{ gender }} |
| **Species/Race** | {{ species }} |
| **Occupation** | {{ occupation }} |
| **Nationality** | |
| **Social Class** | |
## Physical Description
### Appearance
- **Height:**
- **Build:**
- **Hair:**
- **Eyes:**
- **Distinguishing Features:**
- **Style of Dress:**
### Voice & Mannerisms
- **Voice:**
- **Accent:**
- **Speech Patterns:**
- **Habits/Quirks:**
## Personality
### Strengths
-
-
-
### Flaws
-
-
-
### Likes
-
-
### Dislikes
-
-
### Fears
-
## Story Role
### Motivation
>
### Goal
>
### Conflict
>
### Character Arc
- **Beginning:**
- **Middle:**
- **End:**
## Relationships
### Family
-
### Allies
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
### Enemies
-
### Romantic
-
### Mentors/Students
-
## Backstory
### Early Life
>
### Defining Moment
>
### Before Story Begins
>
## Secrets & Hidden Knowledge
{% for secret in secrets %}- {{ secret }}
{% endfor %}
## Abilities & Skills
-
-
-
## Weaknesses
-
-
## Possessions
{% for object in related_objects %}- [[{{ object }}]]
{% endfor %}
-
## Key Dialogue
- **Single Quote:** ""
- **Memorable Line:** ""
## Character Notes
-
-
## Appearances in Story
{% for appearance in appearances %}- [[{{ appearance }}]]
{% endfor %}
## Inspiration
- **Real-world analogy:**
- **Actor reference:**
- **Archetype:**
---
**Status:** {{ status | capitalizes }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,162 @@
---
id: protagonist
name: Protagonist
slug: protagonist
pronunciation: ""
type: protagonist
status: active
role: main
gender: ""
age: 0
species: ""
occupation: ""
tags: [main, protagonist]
appearances: []
related_characters: []
related_locations: []
related_objects: []
secrets: []
created: ""
updated: ""
---
# Protagonist
**Protagonist** | **Status:** Active | **First Appears:** TBD
## Core Identity
| Attribute | Value |
|-----------|-------|
| **Full Name** | |
| **Pronunciation** | |
| **Alias/Nickname** | |
| **Age** | |
| **Gender** | |
| **Species/Race** | |
| **Occupation** | |
| **Nationality** | |
| **Social Class** | |
## Physical Description
### Appearance
- **Height:**
- **Build:**
- **Hair:**
- **Eyes:**
- **Distinguishing Features:**
- **Style of Dress:**
### Voice & Mannerisms
- **Voice:**
- **Accent:**
- **Speech Patterns:**
- **Habits/Quirks:**
## Personality
### Strengths
-
-
-
### Flaws
-
-
-
### Likes
-
-
### Dislikes
-
-
### Fears
-
## Story Role
### Motivation
>
### Goal
>
### Conflict
>
### Character Arc
- **Beginning:**
- **Middle:**
- **End:**
## Relationships
### Family
-
### Allies
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
### Enemies
-
### Romantic
-
### Mentors/Students
-
## Backstory
### Early Life
>
### Defining Moment
>
### Before Story Begins
>
## Secrets & Hidden Knowledge
{% for secret in secrets %}- {{ secret }}
{% endfor %}
## Abilities & Skills
-
-
-
## Weaknesses
-
-
## Possessions
{% for object in related_objects %}- [[{{ object }}]]
{% endfor %}
-
## Key Dialogue
- **Single Quote:** ""
- **Memorable Line:** ""
## Character Notes
-
-
## Appearances in Story
{% for appearance in appearances %}- [[{{ appearance }}]]
{% endfor %}
## Inspiration
- **Real-world analogy:**
- **Actor reference:**
- **Archetype:**
---
**Status:** Active | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,162 @@
---
id: antagonist
name: Antagonist
slug: antagonist
pronunciation: ""
type: antagonist
status: active
role: main
gender: ""
age: 0
species: ""
occupation: ""
tags: [main, antagonist]
appearances: []
related_characters: []
related_locations: []
related_objects: []
secrets: []
created: ""
updated: ""
---
# Antagonist
**Antagonist** | **Status:** Active | **First Appears:** TBD
## Core Identity
| Attribute | Value |
|-----------|-------|
| **Full Name** | |
| **Pronunciation** | |
| **Alias/Nickname** | |
| **Age** | |
| **Gender** | |
| **Species/Race** | |
| **Occupation** | |
| **Nationality** | |
| **Social Class** | |
## Physical Description
### Appearance
- **Height:**
- **Build:**
- **Hair:**
- **Eyes:**
- **Distinguishing Features:**
- **Style of Dress:**
### Voice & Mannerisms
- **Voice:**
- **Accent:**
- **Speech Patterns:**
- **Habits/Quirks:**
## Personality
### Strengths
-
-
-
### Flaws
-
-
-
### Likes
-
-
### Dislikes
-
-
### Fears
-
## Story Role
### Motivation
>
### Goal
>
### Conflict
>
### Character Arc
- **Beginning:**
- **Middle:**
- **End:**
## Relationships
### Family
-
### Allies
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
### Enemies
-
### Romantic
-
### Mentors/Students
-
## Backstory
### Early Life
>
### Defining Moment
>
### Before Story Begins
>
## Secrets & Hidden Knowledge
{% for secret in secrets %}- {{ secret }}
{% endfor %}
## Abilities & Skills
-
-
-
## Weaknesses
-
-
## Possessions
{% for object in related_objects %}- [[{{ object }}]]
{% endfor %}
-
## Key Dialogue
- **Single Quote:** ""
- **Memorable Line:** ""
## Character Notes
-
-
## Appearances in Story
{% for appearance in appearances %}- [[{{ appearance }}]]
{% endfor %}
## Inspiration
- **Real-world analogy:**
- **Actor reference:**
- **Archetype:**
---
**Status:** Active | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,45 @@
---
title: Locations Index
type: index
---
# Locations Index
*All locations in the story world, organized by type and region*
## By Type
### Regions
*No regions yet*
### Cities
*No cities yet*
### Buildings
*No buildings yet*
---
## By Region
*No regions defined yet*
---
## Quick Stats
- **Total Locations:** 0
- **Regions:** 0
- **Cities:** 0
- **Buildings:** 0
## Quick Links
- Add new [[Region|regions/01_region_template]]
- Add new [[City|cities/01_city_template]]
- Add new [[Building|buildings/01_building_template]]
## Tags
- **#capital**
- **#fortress**
- **#tavern**
- **#temple**
- **#ruins**
@@ -0,0 +1,146 @@
---
id: building_id
name: Building Name
slug: building-name
type: building
building_type: ""
status: active
location: ""
address: ""
built: ""
rebuilt: []
destroyed: ""
owner: ""
architect: ""
materials: []
size: ""
floors: 0
residents: []
staff: []
purpose: ""
accessibility: ""
secrets: []
related_characters: []
tags: []
created: ""
updated: ""
---
# {{ name }}
**{{ building_type | capitalizes if building_type else type | capitalizes }}** | **Status:** {{ status | capitalizes }} | **Location:** [[{{ location }}]]
## Core Information
| Attribute | Value |
|-----------|-------|
| **Full Name** | {{ name }} |
| **Type** | {{ building_type if building_type else type }} |
| **Location** | [[{{ location }}]] |
| **Address** | {{ address }} |
| **Built** | {{ built }} |
| **Rebuilt** | {{ rebuilt | join(", ") if rebuilt else "Never" }} |
| **Destroyed** | {{ destroyed if destroyed else "N/A" }} |
| **Owner** | {{ owner }} |
| **Architect** | {{ architect }} |
| **Materials** | {{ materials | join(", ") }} |
| **Size** | {{ size }} |
| **Floors** | {{ floors }} |
| **Purpose** | {{ purpose }} |
## Description
>
## Physical Details
### Exterior
- **Style:**
- **Color:**
- **Notable Features:**
- **Condition:**
### Interior
- **Layout:**
- **Decor:**
- **Lighting:**
- **Furnishings:**
### Rooms/Floors
| Floor | Room | Purpose | Notable Features |
|-------|------|---------|-------------------|
| | | | |
## History
### Construction
>
### Major Events
| Date | Event | Impact |
|------|-------|--------|
| | | |
### Current State
>
## Residents & Staff
### Current Residents
{% for resident in residents %}- [[{{ resident }}]]
{% endfor %}
### Current Staff
{% for person in staff %}- [[{{ person }}]]
{% endfor %}
### Former Residents
-
## Access & Security
### Entrances
- **Main:**
- **Service:**
- **Secret:**
### Security
- **Guards:**
- **Locks:**
- **Traps:**
- **Weaknesses:**
## Story Relevance
### Key Scenes
-
-
### Characters Associated
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
## Secrets & Hidden Knowledge
{% for secret in secrets %}- {{ secret }}
{% endfor %}
## Floor Plan (Optional)
```
+------------------+
| Entrance |
+------------------+
| Main Hall |
+--------+--------+
| Room A | Room B |
+--------+--------+
| Basement |
+------------------+
```
## Inspiration
- **Real-world analogy:**
- **Fictional inspiration:**
---
**Status:** {{ status | capitalizes }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,146 @@
---
id: city_id
name: City Name
slug: city-name
type: city
status: active
region: ""
population: 0
founded: ""
rebuilt: []
destroyed: ""
ruled_by: ""
government: ""
languages: []
currency: ""
religion: ""
industries: []
exports: []
imports: []
tags: []
related_characters: []
related_locations: []
created: ""
updated: ""
---
# {{ name }}
**City** | **Status:** {{ status | capitalizes }} | **Region:** {{ region }}
## Core Information
| Attribute | Value |
|-----------|-------|
| **Full Name** | {{ name }} |
| **Region** | {{ region }} |
| **Population** | {{ population }} |
| **Founded** | {{ founded }} |
| **Rebuilt** | {{ rebuilt | join(", ") if rebuilt else "Never" }} |
| **Destroyed** | {{ destroyed if destroyed else "N/A" }} |
| **Ruling Body** | {{ ruled_by }} |
| **Government** | {{ government }} |
| **Languages** | {{ languages | join(", ") }} |
| **Currency** | {{ currency }} |
| **Religion** | {{ religion }} |
## Description
>
## Geography
### Location
- **Coordinates:**
- **Elevation:**
- **Nearest Major City:**
- **Distance to Capital:**
### Districts/Neighborhoods
| Name | Purpose | Social Class | Notable Features |
|------|---------|--------------|-------------------|
| | | | |
### Landmarks
-
-
-
### Defenses
- **Walls:**
- **Gates:**
- **Guards:**
- **Weaknesses:**
## History
### Founding
>
### Major Events
| Date | Event | Impact |
|------|-------|--------|
| | | |
### Current State
>
## Culture & Society
### Demographics
- **Ethnic Groups:**
- **Social Classes:**
- **Notable Families:** {% for character in related_characters %}[[{{ character }}]]{% endfor %}
### Daily Life
- **Markets:**
- **Festivals:**
- **Traditions:**
### Economy
- **Primary Industries:** {{ industries | join(", ") }}
- **Exports:** {{ exports | join(", ") }}
- **Imports:** {{ imports | join(", ") }}
- **Wealth Level:**
### Government
- **Current Leader:**
- **Power Structure:**
- **Laws:**
- **Crime Level:**
## Political Relations
### Allied Cities
-
### Rival Cities
-
### Trade Partners
-
## Important Locations Within
{% for location in related_locations %}- [[{{ location }}]]
{% endfor %}
## Story Relevance
### Key Scenes
-
-
### Characters Associated
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
## Secrets & Hidden Knowledge
-
-
## Inspiration
- **Real-world analogy:**
- **Fictional inspiration:**
---
**Status:** {{ status | capitalizes }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,137 @@
---
id: region_id
name: Region Name
slug: region-name
type: region
status: active
parent: ""
contained_in: ""
contains: []
residents: []
related_locations: []
climate: ""
terrain: []
government: ""
population: 0
languages: []
curreny: ""
tags: []
created: ""
updated: ""
---
# {{ name }}
**Region** | **Status:** {{ status | capitalizes }} | **Type:** {{ type | capitalizes }}
## Core Information
| Attribute | Value |
|-----------|-------|
| **Full Name** | {{ name }} |
| **Type** | {{ type }} |
| **Parent Region** | {{ parent if parent else "None" }} |
| **Contained In** | {{ contained_in if contained_in else "None" }} |
| **Climate** | {{ climate }} |
| **Terrain** | {{ terrain | join(", ") }} |
| **Government** | {{ government }} |
| **Population** | {{ population }} |
| **Languages** | {{ languages | join(", ") }} |
| **Currency** | {{ currency }} |
## Description
>
## Geography
### Boundaries
- **North:**
- **South:**
- **East:**
- **West:**
### Major Features
-
-
-
### Climate & Weather
-
-
## History
### Founding
>
### Major Events
-
-
-
## Culture & Society
### People
- **Primary Residents:** {% for resident in residents %}[[{{ resident }}]]{% endfor %}
- **Ethnic Groups:**
- **Religions:**
- **Customs:**
### Economy
- **Primary Industries:**
- **Exports:**
- **Imports:**
- **Wealth Level:**
### Government
- **Ruling Body:**
- **Current Leader:**
- **Laws:**
- **Political Climate:**
## Political Relations
### Allies
-
### Enemies
-
### Neutral
-
## Locations Within
{% for location in contains %}- [[{{ location }}]]
{% endfor %}
## Related Locations
{% for location in related_locations %}- [[{{ location }}]]
{% endfor %}
## Travel Information
### From Capital
- **Distance:**
- **Time:**
- **Route:**
### Between Major Points
| From | To | Distance | Time | Notes |
|------|----|----------|------|-------|
| | | | | |
## Notable Events in Story
-
-
## Secrets & Hidden Knowledge
-
-
## Inspiration
- **Real-world analogy:**
- **Fictional inspiration:**
---
**Status:** {{ status | capitalizes }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,37 @@
---
title: Lore Index
type: index
---
# Lore Index
*World-building elements: history, factions, rules, and systems*
## Categories
### History
*No historical events yet*
### Factions
*No factions yet*
### World Rules
- [[World Rules|rules]] - Magic, technology, physics, and societal rules
---
## Quick Stats
- **Historical Events:** 0
- **Factions:** 0
- **Rules Documented:** 1
## Quick Links
- Add new [[Historical Event|history/01_history_template]]
- Add new [[Faction|factions/01_faction_template]]
## Tags
- **#magic**
- **#technology**
- **#war**
- **#religion**
- **#politics**
@@ -0,0 +1,197 @@
---
id: faction_id
name: Faction Name
slug: faction-name
type: faction
status: active
faction_type: ""
founded: ""
dissolved: ""
leader: ""
headquarters: ""
members: []
allies: []
enemies: []
neutral: []
goals: []
beliefs: []
resources: []
weaknesses: []
colors: []
symbols: []
motto: ""
tags: []
related_characters: []
related_locations: []
related_events: []
created: ""
updated: ""
---
# {{ name }}
**{{ faction_type | capitalizes if faction_type else "Faction" }}** | **Status:** {{ status | capitalizes }} | **Founded:** {{ founded }}
## Core Information
| Attribute | Value |
|-----------|-------|
| **Full Name** | {{ name }} |
| **Type** | {{ faction_type if faction_type else "Faction" }} |
| **Status** | {{ status | capitalizes }} |
| **Founded** | {{ founded }} |
| **Dissolved** | {{ dissolved if dissolved else "Active" }} |
| **Leader** | [[{{ leader }}]] |
| **Headquarters** | [[{{ headquarters }}]] |
| **Motto** | {{ motto if motto else "None" }} |
| **Colors** | {{ colors | join(", ") }} |
| **Symbols** | {{ symbols | join(", ") }} |
## Description
>
## Structure
### Hierarchy
```
{{ name }}
├── Leader: [[{{ leader }}]]
├── Second-in-Command:
├── Council:
│ ├──
│ └──
└── Members:
├──
└──
```
### Membership
| Rank | Title | Responsibilities | Current Holder |
|------|-------|-------------------|---------------|
| | | | |
### Recruitment
- **Requirements:**
- **Process:**
- **Oath:**
- **Ritual:**
## Goals & Objectives
### Primary Goals
{% for goal in goals %}- {{ goal }}
{% endfor %}
### Secondary Goals
-
-
### Ultimate Vision
>
## Beliefs & Ideology
### Core Beliefs
{% for belief in beliefs %}- {{ belief }}
{% endfor %}
### Philosophy
>
### Moral Code
-
-
## Resources
### Assets
{% for resource in resources %}- {{ resource }}
{% endfor %}
### Strengths
-
-
-
### Weaknesses
{% for weakness in weaknesses %}- {{ weakness }}
{% endfor %}
## Political Relations
### Allies
{% for ally in allies %}- [[{{ ally }}]]
{% endfor %}
### Enemies
{% for enemy in enemies %}- [[{{ enemy }}]]
{% endfor %}
### Neutral/Unaffiliated
{% for neutral in neutral %}- [[{{ neutral }}]]
{% endfor %}
### Rivals
-
## History
### Founding
>
### Major Events
| Date | Event | Impact |
|------|-------|--------|
| | | |
### Current Status
>
## Culture
### Traditions
-
-
### Rituals
-
-
### Taboos
-
-
## Story Relevance
### Key Scenes Involving Faction
-
-
### Characters Associated
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
### Locations Controlled
{% for location in related_locations %}- [[{{ location }}]]
{% endfor %}
### Events Involved In
{% for event in related_events %}- [[{{ event }}]]
{% endfor %}
## Secrets & Hidden Knowledge
-
-
## Public Perception
- **By Allies:**
- **By Enemies:**
- **By Neutrals:**
## Inspiration
- **Real-world parallel:**
- **Fictional inspiration:**
---
**Status:** {{ status | capitalizes }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,124 @@
---
id: history_event_id
name: Event Name
slug: event-name
type: event
era: ""
start_date: ""
end_date: ""
duration: ""
location: ""
participants: []
outcome: ""
impact: ""
related_events: []
related_characters: []
related_locations: []
tags: []
created: ""
updated: ""
---
# {{ name }}
**Historical Event** | **Era:** {{ era }} | **Date:** {{ start_date }} {{ "- " + end_date if end_date else "" }}
## Core Information
| Attribute | Value |
|-----------|-------|
| **Event Name** | {{ name }} |
| **Type** | {{ type }} |
| **Era** | {{ era }} |
| **Start Date** | {{ start_date }} |
| **End Date** | {{ end_date if end_date else "Ongoing" }} |
| **Duration** | {{ duration }} |
| **Location** | [[{{ location }}]] |
| **Outcome** | {{ outcome }} |
| **Impact Level** | {{ impact }} |
## Summary
>
## Participants
### Major Figures
{% for participant in participants %}- [[{{ participant }}]]
{% endfor %}
### Factions Involved
-
### Casualties
-
## Timeline
| Date | Event | Details |
|------|-------|---------|
| | | |
## Causes
-
-
-
## Event Details
### Pre-Event Situation
>
### Key Moments
1.
2.
3.
### Turning Points
-
-
### Aftermath
>
## Impact on Story World
### Political
-
### Social
-
### Economic
-
### Cultural
-
## Related Events
{% for event in related_events %}- [[{{ event }}]]
{% endfor %}
## Related Characters
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
## Related Locations
{% for location in related_locations %}- [[{{ location }}]]
{% endfor %}
## Secrets & Hidden Truths
-
-
## Historical Accounts
- **Official Record:**
- **Common Belief:**
- **Actual Truth:**
## Inspiration
- **Real-world parallel:**
- **Fictional inspiration:**
---
**Status:** Active | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,210 @@
---
id: rules
name: World Rules
slug: world-rules
type: rules
status: active
tags: [magic, technology, society, physics]
created: ""
updated: ""
---
# World Rules
*Fundamental rules governing the story world*
## Magic System
### Overview
>
### Source of Power
-
### Types of Magic
| Type | Description | Limitations | Practitioners |
|------|-------------|-------------|--------------|
| | | | |
### Rules & Limitations
#### Costs
-
-
#### Restrictions
-
-
#### Side Effects
-
-
### Learning & Mastery
- **How to Learn:**
- **Time Required:**
- **Innate vs. Taught:**
### Common Uses
-
-
-
### Forbidden Practices
-
-
---
## Technology Level
### Overview
>
### Common Technology
-
-
-
### Advanced Technology
-
-
-
### Lost/Forbidden Technology
-
-
### Technological Limitations
-
-
---
## Physical Laws
### Gravity & Physics
-
-
### Time
- **Flow:**
- **Time Travel:**
- **Time Manipulation:**
### Space & Cosmology
- **World Shape:**
- **Multiple Worlds:**
- **Astronomy:**
---
## Biological Rules
### Species & Races
-
-
### Lifespans
| Species | Average Lifespan | Maximum Lifespan |
|---------|-------------------|------------------|
| | | |
### Reproduction
-
-
### Diseases & Healing
-
-
---
## Societal Rules
### Laws & Justice
#### Universal Laws
-
-
#### Regional Variations
-
-
### Social Hierarchy
```
Top
├──
├──
└──
├──
└── Bottom
```
### Customs & Traditions
-
-
-
### Taboos
-
-
-
---
## Economic Rules
### Currency
- **Primary:**
- **Secondary:**
- **Exchange Rates:**
### Trade
- **Major Trade Routes:**
- **Common Goods:**
- **Rare Goods:**
### Wealth Distribution
-
-
---
## Divine & Spiritual Rules
### Gods & Deities
-
-
### Afterlife
-
-
### Religion
- **Major Religions:**
- **Minor Religions:**
- **Heretical Beliefs:**
---
## Rules by Location
| Location | Special Rules | Exceptions |
|----------|---------------|------------|
| | | |
---
## Rule Consistency Checklist
- [ ] Magic system rules followed in all scenes
- [ ] Technology level consistent across timeline
- [ ] Physical laws not violated
- [ ] Societal customs respected in character actions
- [ ] Economic rules applied consistently
---
**Status:** Active | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,34 @@
---
title: Objects Index
type: index
---
# Objects Index
*Important artifacts, weapons, and items in the story*
## Categories
### Artifacts
*No artifacts yet*
### Weapons
*No weapons yet*
---
## Quick Stats
- **Total Objects:** 0
- **Artifacts:** 0
- **Weapons:** 0
## Quick Links
- Add new [[Artifact|artifacts/01_artifact_template]]
- Add new [[Weapon|weapons/01_weapon_template]]
## Tags
- **#legendary**
- **#cursed**
- **#blessed**
- **#sentient**
- **#destroyed**
@@ -0,0 +1,172 @@
---
id: artifact_id
name: Artifact Name
slug: artifact-name
type: artifact
artifact_type: ""
status: active
origin: ""
created_by: ""
created_date: ""
discovered: ""
current_owner: ""
previous_owners: []
location: ""
materials: []
appearance: ""
power: ""
abilities: []
limitations: []
activation: ""
deactivation: ""
cost: ""
duration: ""
range: ""
target: ""
side_effects: []
danger_level: ""
secrets: []
related_characters: []
related_locations: []
related_events: []
related_lore: []
tags: []
created: ""
updated: ""
---
# {{ name }}
**{{ artifact_type | capitalizes if artifact_type else "Artifact" }}** | **Status:** {{ status | capitalizes }}
## Core Information
| Attribute | Value |
|-----------|-------|
| **Full Name** | {{ name }} |
| **Type** | {{ artifact_type if artifact_type else "Artifact" }} |
| **Origin** | {{ origin }} |
| **Created By** | {{ created_by }} |
| **Created Date** | {{ created_date }} |
| **Discovered** | {{ discovered }} |
| **Current Owner** | [[{{ current_owner }}]] |
| **Location** | [[{{ location }}]] |
| **Power Level** | {{ power }} |
| **Danger Level** | {{ danger_level }} |
## Description
### Physical Description
>
### Appearance
- **Size:**
- **Weight:**
- **Color:**
- **Material:** {{ materials | join(", ") }}
- **Shape:**
- **Markings:**
- **Condition:**
### Sensory Details
- **Sound:**
- **Smell:**
- **Texture:**
- **Temperature:**
- **Taste:**
## History
### Creation
>
### Ownership History
| Owner | Date Acquired | Date Lost | Method |
|-------|---------------|-----------|--------|
{% for owner in previous_owners %}| [[{{ owner }}]] | | | |
{% endfor %}
| [[{{ current_owner }}]] | | Current | |
### Significant Events
-
-
-
## Powers & Abilities
### Primary Power
>
### Abilities
{% for ability in abilities %}- **{{ ability }}**
{% endfor %}
### Limitations
{% for limitation in limitations %}- **{{ limitation }}**
{% endfor %}
### Activation
- **Method:** {{ activation }}
- **Requirements:**
- **Incantation:**
- **Ritual:**
### Deactivation
- **Method:** {{ deactivation }}
- **Conditions:**
- **Duration:** {{ duration }}
### Usage Rules
- **Cost:** {{ cost }}
- **Range:** {{ range }}
- **Target:** {{ target }}
- **Cooldown:**
### Side Effects
{% for effect in side_effects %}- {{ effect }}
{% endfor %}
## Weaknesses
-
-
-
## Secrets & Hidden Knowledge
{% for secret in secrets %}- {{ secret }}
{% endfor %}
## Story Relevance
### Key Scenes
-
-
### Characters Associated
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
### Locations Associated
{% for location in related_locations %}- [[{{ location }}]]
{% endfor %}
### Events Associated
{% for event in related_events %}- [[{{ event }}]]
{% endfor %}
### Lore Connections
{% for lore in related_lore %}- [[{{ lore }}]]
{% endfor %}
## Current Status
- **Location:**
- **Condition:**
- **Accessibility:**
- **Known By:**
## Inspiration
- **Real-world parallel:**
- **Fictional inspiration:**
---
**Status:** {{ status | capitalizes }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,167 @@
---
id: weapon_id
name: Weapon Name
slug: weapon-name
type: weapon
weapon_type: ""
status: active
origin: ""
created_by: ""
created_date: ""
current_owner: ""
previous_owners: []
location: ""
materials: []
appearance: ""
power: ""
abilities: []
limitations: []
damage: ""
range: ""
accuracy: ""
speed: ""
weight: ""
durability: ""
rarity: ""
secrets: []
related_characters: []
related_locations: []
related_events: []
tags: []
created: ""
updated: ""
---
# {{ name }}
**{{ weapon_type | capitalizes if weapon_type else "Weapon" }}** | **Status:** {{ status | capitalizes }}
## Core Information
| Attribute | Value |
|-----------|-------|
| **Full Name** | {{ name }} |
| **Type** | {{ weapon_type if weapon_type else "Weapon" }} |
| **Origin** | {{ origin }} |
| **Created By** | {{ created_by }} |
| **Created Date** | {{ created_date }} |
| **Current Owner** | [[{{ current_owner }}]] |
| **Location** | [[{{ location }}]] |
| **Rarity** | {{ rarity }} |
| **Power Level** | {{ power }} |
## Description
### Physical Description
>
### Appearance
- **Length:**
- **Weight:** {{ weight }}
- **Material:** {{ materials | join(", ") }}
- **Color:**
- **Shape:**
- **Markings:**
- **Condition:**
### Sensory Details
- **Sound:**
- **Smell:**
- **Texture:**
- **Temperature:**
## Combat Statistics
### Offensive
- **Damage:** {{ damage }}
- **Damage Type:**
- **Range:** {{ range }}
- **Accuracy:** {{ accuracy }}
- **Speed:** {{ speed }}
- **Critical Chance:**
- **Critical Effect:**
### Defensive
- **Block Chance:**
- **Parry Chance:**
- **Durability:** {{ durability }}
### Special Properties
{% for ability in abilities %}- **{{ ability }}**
{% endfor %}
### Limitations
{% for limitation in limitations %}- **{{ limitation }}**
{% endfor %}
## History
### Creation/Forge
>
### Ownership History
| Owner | Date Acquired | Date Lost | Method |
|-------|---------------|-----------|--------|
{% for owner in previous_owners %}| [[{{ owner }}]] | | | |
{% endfor %}
| [[{{ current_owner }}]] | | Current | |
### Notable Uses in History
-
-
-
### Significant Battles
-
-
## Usage
### Wielders
{% for character in related_characters %}- [[{{ character }}]]
{% endfor %}
### Combat Style
-
-
### Techniques
-
-
## Weaknesses
-
-
-
## Secrets & Hidden Knowledge
{% for secret in secrets %}- {{ secret }}
{% endfor %}
## Story Relevance
### Key Scenes
-
-
### Locations Associated
{% for location in related_locations %}- [[{{ location }}]]
{% endfor %}
### Events Associated
{% for event in related_events %}- [[{{ event }}]]
{% endfor %}
## Current Status
- **Location:**
- **Condition:**
- **Wielder:**
- **Known By:**
## Inspiration
- **Real-world parallel:**
- **Fictional inspiration:**
---
**Status:** {{ status | capitalizes }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,30 @@
---
title: Relationships Index
type: index
---
# Relationships Index
*Connections between characters, factions, and entities*
## Categories
### Character Relationships
- [[Character Relationships|character_relationships]] - All character connections and dynamics
### Faction Relationships
*No faction relationships yet*
---
## Quick Stats
- **Character Relationships:** 1 document
- **Faction Relationships:** 0
## Quick Links
- [[Characters Index|../01-Characters/_index]]
- [[Factions Index|../03-Lore/_index]]
---
**Status:** Active | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,130 @@
---
id: character_relationships
name: Character Relationships
slug: character-relationships
type: relationships
status: active
created: ""
updated: ""
---
# Character Relationships
*Network of relationships between characters*
## Relationship Types
- **Family:** Blood relations
- **Romantic:** Love interests, past and present
- **Friendship:** Close bonds
- **Rivalry:** Competitive relationships
- **Mentorship:** Teacher/student dynamics
- **Alliance:** Political or strategic partnerships
- **Enmity:** Active hostility
- **Betrayal:** Past or potential
---
## Relationship Web
```mermaid
graph LR
%% Add your character relationships here
%% Example format:
%% A[Character A] -->|Relationship Type| B[Character B]
%% Example:
% John -->|Brother| Jane
% John -->|Mentor| Robert
% John -->|Rival| Michael
% Jane -->|Romantic| James
%% Color coding:
%% classDef family fill:#f9f,stroke:#333;
%% classDef romantic fill:#ff9,stroke:#333;
%% classDef friendship fill:#9f9,stroke:#333;
%% classDef rivalry fill:#ff9,stroke:#333;
%% classDef enmity fill:#f99,stroke:#333;
```
---
## Detailed Relationships
### Main Character Relationships
| Character | Relationship | Target | Strength | Notes | Status |
|-----------|--------------|--------|----------|-------|--------|
| | | | | | |
### Family Trees
#### Family Group 1
```
Grandparent
├── Parent A
│ ├── Child 1
│ └── Child 2
└── Parent B
└── Child 3
```
#### Family Group 2
```
```
---
## Relationship Matrix
| From \ To | Character A | Character B | Character C | Character D |
|------------|-------------|-------------|-------------|-------------|
| **Character A** | - | | | |
| **Character B** | | - | | |
| **Character C** | | | - | |
| **Character D** | | | | - |
**Key:**
- **++** Strong positive
- **+** Positive
- **=** Neutral
- **- ** Negative
- **--** Strong negative
- **X** None/Unknown
---
## Relationship Tracking
### Active Relationships
-
-
### Changed Relationships
| Date | From | To | Change | Reason |
|------|------|----|--------|--------|
| | | | | |
### Foreshadowed Relationships
-
-
---
## Relationship Statistics
- **Total Connections:** 0
- **Family Bonds:** 0
- **Romantic Pairings:** 0
- **Mentorships:** 0
- **Rivalries:** 0
- **Enmities:** 0
---
## Quick Links
- [[Characters Index|../01-Characters/_index]]
- [[All Characters Grid|../01-Characters/character_grid]]
---
**Status:** Active | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,137 @@
---
id: timeline
name: Timeline
slug: timeline
type: timeline
status: active
current_era: ""
start_date: ""
end_date: ""
created: ""
updated: ""
---
# Timeline
*Chronological events in the story world*
## Eras Overview
| Era | Start | End | Duration | Description |
|-----|-------|-----|----------|-------------|
| | | | | |
---
## Detailed Timeline
### Pre-Story History
#### Ancient Era
| Date | Event | Location | Characters | Impact |
|------|-------|----------|-----------|--------|
| | | | | |
#### Classical Era
| Date | Event | Location | Characters | Impact |
|------|-------|----------|-----------|--------|
| | | | | |
#### Recent History
| Date | Event | Location | Characters | Impact |
|------|-------|----------|-----------|--------|
| | | | | |
---
### Story Timeline
#### Act 1: Setup
| Date | Chapter | Event | Location | Characters |
|------|---------|-------|----------|-----------|
| | | | | |
#### Act 2: Confrontation
| Date | Chapter | Event | Location | Characters |
|------|---------|-------|----------|-----------|
| | | | | |
#### Act 3: Resolution
| Date | Chapter | Event | Location | Characters |
|------|---------|-------|----------|-----------|
| | | | | |
---
### Post-Story Timeline
#### Immediate Aftermath
| Date | Event | Location | Characters | Impact |
|------|-------|----------|-----------|--------|
| | | | | |
#### Long-term Future
| Date | Event | Location | Characters | Impact |
|------|-------|----------|-----------|--------|
| | | | | |
---
## Timeline Visualization
```mermaid
gantt
title Story Timeline
dateFormat YYYY-MM-DD
section Ancient Era
Event 1 :a1, 0001-01-01, 100y
Event 2 :a2, after a1, 50y
section Classical Era
Event 3 :b1, 0101-01-01, 200y
section Story Events
Chapter 1 :c1, 1045-01-01, 1d
Chapter 2 :c2, after c1, 1d
Chapter 3 :c3, after c2, 1d
```
---
## Date Calculations
### Age Calculator
| Character | Birth Date | Current Story Date | Age |
|-----------|------------|--------------------|-----|
| | | | |
### Time Between Events
| From | To | Duration | Notes |
|------|----|----------|-------|
| | | | |
---
## Calendar System
### Months
| # | Name | Days | Season | Notes |
|---|------|------|--------|-------|
| 1 | | | | |
### Holidays & Festivals
| Date | Name | Type | Celebrated By |
|------|------|------|--------------|
| | | | |
### Weeks
- **Days in Week:**
- **Day Names:**
---
## Quick Links
- [[History Index|../03-Lore/_index]]
- [[Characters Index|../01-Characters/_index]]
---
**Current Era:** {{ current_era }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,140 @@
---
id: themes
name: Themes and Symbols
slug: themes
type: themes
status: active
created: ""
updated: ""
---
# Themes and Symbols
*Recurring ideas, motifs, and symbolic elements in the story*
---
## Major Themes
### Theme 1
> **Description:**
**Examples in Story:**
-
-
-
**Characters Embodying:**
-
-
**Key Scenes:**
-
-
---
### Theme 2
> **Description:**
**Examples in Story:**
-
-
-
**Characters Embodying:**
-
-
**Key Scenes:**
-
-
---
## Motifs
*Recurring elements or patterns*
| Motif | First Appearance | Recurrences | Symbolism |
|-------|------------------|-------------|-----------|
| | | | |
---
## Symbols
*Objects, colors, or elements with deeper meaning*
| Symbol | Represents | First Appearance | Key Moments |
|--------|------------|------------------|-------------|
| | | | |
---
## Symbolism by Color
| Color | Meaning | Associated With | Examples |
|-------|---------|----------------|----------|
| | | | |
---
## Symbolism by Object
| Object | Represents | Owner/Associated | Significance |
|--------|------------|------------------|--------------|
| | | | |
---
## Thematic Structure
### Act 1 Themes
-
-
### Act 2 Themes
-
-
### Act 3 Themes
-
-
---
## Character Themes
| Character | Primary Theme | Secondary Theme | Growth |
|-----------|---------------|-----------------|--------|
| | | | |
---
## Thematic Questions
*Questions the story explores:*
-
-
-
-
---
## Theme Tracking
### Theme Appearances by Chapter
| Chapter | Theme 1 | Theme 2 | Theme 3 |
|---------|---------|---------|---------|
| | | | |
---
## Quick Links
- [[Characters Index|../01-Characters/_index]]
- [[Plot Index|../../05-Plot]]
---
**Status:** Active | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,164 @@
---
id: consistency_checklist
name: Consistency Checklist
slug: consistency-checklist
type: tracking
status: active
last_checked: ""
checked_by: ""
created: ""
updated: ""
---
# Consistency Checklist
*Track and verify continuity across your story*
> **Check this file before finalizing each chapter.** Update as you write to catch inconsistencies early.
---
## Critical Checks (Must Verify)
### Character Consistency
- [ ] All character ages match the timeline
- [ ] Character names spelled consistently (including nicknames)
- [ ] Character appearances match descriptions
- [ ] Character motivations align with actions
- [ ] Character arcs progressing as planned
- [ ] Dialogue voices distinct and consistent
- [ ] Relationships updated after major events
- [ ] Secrets revealed in correct order
### Location Consistency
- [ ] Location descriptions match across mentions
- [ ] Distances between locations consistent
- [ ] Travel times calculated and consistent
- [ ] Location features (buildings, landmarks) correctly placed
- [ ] Weather/climate consistent with region and season
- [ ] Political control of locations updated
### Timeline Consistency
- [ ] Event dates don't conflict
- [ ] Character ages match birth dates
- [ ] Historical events align with character backstories
- [ ] Season and time of day consistent
- [ ] Day of week calculations correct
### World Rules Consistency
- [ ] Magic system rules followed in all scenes
- [ ] Technology level consistent
- [ ] Physical laws not violated
- [ ] Societal customs respected
- [ ] Economic rules applied consistently
---
## Chapter-by-Chapter Tracking
| Chapter | Characters | Locations | Timeline | Rules | Notes | Status |
|---------|------------|-----------|----------|--------|-------|--------|
| Ch 1 | | | | | |
| Ch 2 | | | | | |
| Ch 3 | | | | | |
---
## Character-Specific Tracking
### Protagonist
| Attribute | Value | First Mentioned | Last Verified | Status |
|-----------|-------|----------------|---------------|--------|
| Full Name | | | |
| Age | | | |
| Appearance | | | |
| Motivation | | | |
| Key Items | | | |
### Antagonist
| Attribute | Value | First Mentioned | Last Verified | Status |
|-----------|-------|----------------|---------------|--------|
| Full Name | | | |
| Age | | | |
| Appearance | | | |
| Motivation | | | |
| Key Items | | | |
---
## Location-Specific Tracking
| Location | Description | First Mentioned | Last Verified | Status |
|----------|-------------|----------------|---------------|--------|
| | | | |
---
## Magic/Technology Tracking
| System | Rule | Chapter | Compliance | Notes |
|--------|------|---------|------------|-------|
| | | | |
---
## Relationship Tracking
| Relationship | Status | Chapter Established | Last Mentioned | Notes |
|--------------|--------|---------------------|---------------|-------|
| | | | |
---
## Plot Hole Prevention
### Foreshadowing Check
- [ ] All Chekhov's guns fired
- [ ] All mysteries have clues
- [ ] All character skills used
- [ ] All location details relevant
### Continuity Check
- [ ] Injuries explained (healed or lingering)
- [ ] Items accounted for (gained/lost)
- [ ] Knowledge gained remembered
- [ ] Promises fulfilled or addressed
### Logic Check
- [ ] Character actions have motivation
- [ ] Event causes have setup
- [ ] Consequences follow actions
- [ ] Dialogue doesn't contradict facts
---
## Version History
| Date | Checked By | Findings | Resolved | Notes |
|------|------------|----------|----------|-------|
| | | | |
---
## Quick Verification Commands
Use your editor's search:
- `{{ character.name }}` - Find all mentions of a character
- `{{ location.name }}` - Find all mentions of a location
- `[[` - Find all cross-references
- `status:` - Find all status fields
---
## Final Check Before Publishing
- [ ] All consistency checks passed
- [ ] All timeline entries complete
- [ ] All character sheets updated
- [ ] All location descriptions final
- [ ] All relationship maps current
- [ ] All world rules followed
---
**Last Checked:** {{ last_checked if last_checked else "Never" }} | **By:** {{ checked_by if checked_by else "No one" }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,259 @@
# Story Bible
> **Your single source of truth for all story world information.**
The Story Bible is a comprehensive reference system that helps you maintain consistency, track connections, and ensure continuity across your entire narrative. Every fact about your story world should be documented here.
---
## Structure Overview
```
03-Story-Bible/
├── _index.md # Master index and navigation
├── README.md # This file
├── CONSISTENCY.md # Continuity tracking checklist
│
├── 01-Characters/ # All characters
│ ├── _index.md
│ ├── character_grid.md # Quick reference table
│ └── main_characters/ # Protagonist, antagonist, etc.
│ ├── 01_character_template.md
│ ├── 01_protagonist.md
│ └── 02_antagonist.md
│ └── supporting_characters/ # Secondary characters
│ └── minor_characters/ # Background characters
│
├── 02-Locations/ # World geography
│ ├── _index.md
│ ├── regions/
│ │ └── 01_region_template.md
│ ├── cities/
│ │ └── 01_city_template.md
│ └── buildings/
│ └── 01_building_template.md
│
├── 03-Lore/ # World-building
│ ├── _index.md
│ ├── history/
│ │ └── 01_history_template.md
│ ├── factions/
│ │ └── 01_faction_template.md
│ └── rules.md # Magic, tech, physics, society
│
├── 04-Objects/ # Important items
│ ├── _index.md
│ ├── artifacts/
│ │ └── 01_artifact_template.md
│ └── weapons/
│ └── 01_weapon_template.md
│
├── 05-Relationships/ # Connections
│ ├── _index.md
│ └── character_relationships.md
│
├── 06-Timeline/ # Chronology
│ └── _index.md
│
└── 07-Themes/ # Motifs and symbols
└── _index.md
```
---
## How to Use the Story Bible
### 1. Adding a New Character
1. **Copy the template:**
```bash
cp 01-Characters/main_characters/01_character_template.md 01-Characters/main_characters/03_new_character.md
```
2. **Fill in the YAML frontmatter first:**
```yaml
---
id: unique_id
name: Character Name
slug: character-name
type: protagonist|antagonist|ally|enemy|mentor
status: active|draft|deceased|retired
tags: [tag1, tag2]
appearances: [chapter_1, chapter_5]
related_characters: [character_a, character_b]
---
```
3. **Complete the character sheet** with all known information
4. **Add to index files:**
- Update `01-Characters/_index.md`
- Update `01-Characters/character_grid.md`
5. **Create cross-links** from other relevant entries
### 2. Adding a New Location
1. **Choose the type:** Region, City, or Building
2. **Copy the appropriate template**
3. **Fill in details** including relationships to characters
4. **Add to Locations index**
5. **Link from character files** that use this location
### 3. Adding Lore
- **Historical Events:** Copy template from `03-Lore/history/`
- **Factions:** Copy template from `03-Lore/factions/`
- **World Rules:** Edit `03-Lore/rules.md`
### 4. Maintaining Consistency
- **After each writing session:** Update relevant Bible entries
- **Before finalizing a chapter:** Run through `CONSISTENCY.md` checklist
- **Weekly review:** Spend 15 minutes updating and verifying entries
---
## Key Features
### YAML Frontmatter
Every entry starts with YAML metadata for easy filtering and searching:
```yaml
---
id: unique_identifier
name: Display Name
slug: url-friendly-name
type: category
tags: [tag1, tag2, tag3]
related_entities: [entity_a, entity_b]
status: active|draft|archived
created: "2024-01-01"
updated: "2024-01-01"
---
```
### Wiki-Links
Use `[[Link Text|file-name]]` or `[[file-name]]` to create cross-references:
```markdown
- **Current Owner:** [[John Doe]]
- **Location:** [[Castle Black]]
- **Related Event:** [[The War of Ashes|history/war_of_ashes]]
```
### Mermaid Diagrams
Create visual relationship maps and timelines:
````markdown
```mermaid
graph LR
A[John] -->|Brother| B[James]
A -->|Mentor| C[Robert]
```
````
### Tables
Use tables for structured data:
```markdown
| Attribute | Value |
|-----------|-------|
| Age | 30 |
| Gender | Male |
```
---
## Best Practices
### 1. Start Simple
- Begin with basic information
- Add details as they become relevant
- Don't over-document early drafts
### 2. Stay Current
- Update entries immediately after writing scenes
- Don't let the Bible fall behind
- Small updates are easier than big ones
### 3. Use Cross-Links
- Link characters to locations
- Link locations to events
- Link events to lore
- This creates a web of knowledge
### 4. Tag Everything
- Use consistent tags
- Filter by tags when searching
- Examples: `#protagonist`, `#capital`, `#magic`, `#war`
### 5. Review Regularly
- Weekly: Quick scan for obvious issues
- Monthly: Deep consistency check
- Before publishing: Full verification
---
## Search Tips
Use your editor's search feature:
| Search Term | Finds |
|-------------|-------|
| `[[` | All cross-references |
| `id:` | All YAML IDs |
| `status:` | All status fields |
| `tags:` | All tag lists |
| `#tagname` | All entries with that tag |
---
## Tag Reference
### Character Tags
`#protagonist` `#antagonist` `#ally` `#enemy` `#mentor` `#romantic` `#family` `#deceased` `#noble` `#commoner` `#warrior` `#mage` `#thief`
### Location Tags
`#capital` `#city` `#village` `#fortress` `#tavern` `#temple` `#ruins` `#wilderness` `#underground` `#floating` `#magical`
### Lore Tags
`#magic` `#technology` `#war` `#religion` `#politics` `#history` `#myth` `#legend` `#prophecy` `#culture`
### Object Tags
`#legendary` `#cursed` `#blessed` `#sentient` `#destroyed` `#lost` `#stolen` `#royal` `#sacred` `#ancient`
---
## Tools Integration
If your editor supports it:
- **Obsidian:** Native backlink support, graph view, tag search
- **VS Code:** Extensions for markdown preview and search
- **Typora:** Clean preview with YAML support
- **Any editor:** Basic search and replace works everywhere
---
## Example Workflow
1. **Write Chapter 5** where John visits Castle Black
2. **Update John's entry:** Add Castle Black to `related_locations`
3. **Update Castle Black entry:** Add John to `residents` or `visitors`
4. **Update Timeline:** Add "John visits Castle Black" event
5. **Check Consistency:** Verify travel time and castle description match
6. **Cross-link:** Ensure both entries link to each other
---
## Need Help?
- Check `_index.md` files for navigation
- Use `CONSISTENCY.md` for verification
- Look at existing entries for examples
- Refer to templates for required fields
---
**Remember:** The Story Bible is a living document. Update it as you write, and it will save you hours of continuity fixing later.
@@ -0,0 +1,148 @@
---
id: story_bible
name: Story Bible
slug: story-bible
type: master_index
status: active
world_name: ""
story_title: ""
author: ""
created: ""
updated: ""
---
# Story Bible
*Master index for all world-building, characters, locations, and lore*
> **The Story Bible is your source of truth.** Every fact about your story world should be documented here. Use it to maintain consistency, track connections, and ensure continuity across your narrative.
---
## Quick Navigation
| Section | Description | Count |
|---------|-------------|-------|
| [[Characters|01-Characters/_index]] | All characters in the story | 2 |
| [[Locations|02-Locations/_index]] | Places, regions, cities, buildings | 0 |
| [[Lore|03-Lore/_index]] | History, factions, world rules | 1 |
| [[Objects|04-Objects/_index]] | Artifacts, weapons, important items | 0 |
| [[Relationships|05-Relationships/_index]] | Character and faction connections | 1 |
| [[Timeline|06-Timeline/_index]] | Chronology of story events | 1 |
| [[Themes|07-Themes/_index]] | Recurring ideas and symbols | 1 |
---
## World Overview
| Attribute | Value |
|-----------|-------|
| **World Name** | {{ world_name if world_name else "Unnamed" }} |
| **Story Title** | {{ story_title if story_title else "Untitled" }} |
| **Author** | {{ author if author else "Unknown" }} |
| **Genre** | |
| **Setting** | |
| **Tone** | |
---
## Statistics Dashboard
### Characters
- **Main Characters:** 2
- **Supporting Characters:** 0
- **Minor Characters:** 0
- **Total:** 2
### Locations
- **Regions:** 0
- **Cities:** 0
- **Buildings:** 0
- **Total:** 0
### Lore
- **Historical Events:** 0
- **Factions:** 0
- **World Rules:** 1
### Objects
- **Artifacts:** 0
- **Weapons:** 0
- **Total:** 0
### Relationships
- **Character Relationships:** 1 document
- **Faction Relationships:** 0
---
## Recent Updates
| Date | Section | Change | By |
|------|---------|--------|----|
| | | | |
---
## Quick Start Guide
### Adding a New Character
1. Copy `01-Characters/main_characters/01_character_template.md`
2. Rename to `NN_name.md` (e.g., `03_elara.md`)
3. Fill in YAML frontmatter first
4. Add to appropriate index files
5. Link from character grid
### Adding a New Location
1. Choose type: Region, City, or Building
2. Copy corresponding template from `02-Locations/[type]/`
3. Rename and fill in details
4. Add to Locations index
5. Link from character/plot files
### Adding Lore
1. Historical events go in `03-Lore/history/`
2. Factions go in `03-Lore/factions/`
3. World rules go in `03-Lore/rules.md`
4. Update Lore index
---
## Consistency Checklist
- [ ] All character ages match timeline
- [ ] Location descriptions consistent across mentions
- [ ] Magic/technology rules followed in all scenes
- [ ] Character relationships updated after major events
- [ ] All named entities have Bible entries
- [ ] Cross-links between entries are accurate
---
## Search Tips
Use your editor's search to find:
- `[[` - All wiki-links (cross-references)
- `id:` - All YAML IDs
- `status:` - All status fields
- `tags:` - All tags for filtering
---
## Tags Reference
### Character Tags
`#protagonist` `#antagonist` `#ally` `#enemy` `#mentor` `#romantic` `#family` `#deceased`
### Location Tags
`#capital` `#city` `#village` `#fortress` `#tavern` `#temple` `#ruins` `#wilderness`
### Lore Tags
`#magic` `#technology` `#war` `#religion` `#politics` `#history` `#myth`
### Object Tags
`#legendary` `#cursed` `#blessed` `#sentient` `#destroyed` `#lost` `#stolen`
---
**World:** {{ world_name if world_name else "Unnamed" }} | **Created:** {{ created }} | **Last Updated:** {{ updated }}
@@ -0,0 +1,118 @@
---
id: scene_new
title: "New Scene Title"
slug: new-scene-title
act: 1
chapter: 1
scene: 99
type: scene
status: planning
word_count_target: 2000
word_count_min: 1800
word_count_max: 2200
pov: ""
characters: []
setting: ""
date: ""
time: ""
conflict: ""
theme: ""
tone: ""
draft_file: ""
order: 99
created: ""
updated: ""
---
# New Scene Title
**Planning Template** | **ID:** scene_new | **Status:** {{ status | capitalizes }}
---
## Planning Metadata
| Attribute | Value |
|-----------|-------|
| **Act** | {{ act }} |
| **Chapter** | {{ chapter }} |
| **Scene** | {{ scene }} |
| **Type** | {{ type | capitalizes }} |
| **Order** | {{ order }} |
| **Draft File** | {{ draft_file if draft_file else "[Create Draft File](#)" }} |
---
## Creative Elements
### POV
> {{ pov if pov else "Not specified" }}
### Characters
{% for character in characters %}- [[{{ character }}]]
{% endfor %}
### Setting
> {{ setting if setting else "Not specified" }}
### Date & Time
> {{ date if date else "Not specified" }} | {{ time if time else "Not specified" }}
---
## Story Structure
### Conflict
> {{ conflict if conflict else "Not specified" }}
### Theme
> {{ theme if theme else "Not specified" }}
### Tone
> {{ tone if tone else "Not specified" }}
---
## Word Count Goals
| Metric | Value |
|--------|-------|
| **Target** | {{ word_count_target }} |
| **Minimum** | {{ word_count_min }} |
| **Maximum** | {{ word_count_max }} |
---
## Scene Planning
### The Setup
>
### The Reveal
>
### Things to Note
-
-
---
## Status Tracking
- [ ] Scene outline complete
- [ ] Character arcs aligned
- [ ] Location details verified
- [ ] Conflict established
- [ ] Word count target set
- [ ] Ready for drafting
---
**Instructions:**
1. Copy this file to the appropriate act/chapter folder
2. Rename to `scene_XX.md` (e.g., `scene_02.md`)
3. Update the YAML frontmatter with scene details
4. Set `draft_file` to point to the corresponding draft file
5. Create the draft file using the template in `06-First Draft/_template.md`
**Related:** [Story Bible](../../03-Story-Bible/_index.md) | **Created:** {{ created }} | **Updated:** {{ updated }}
@@ -1,23 +1,111 @@
# Title
---
id: scene_01
title: "Chapter One: The Beginning"
slug: chapter-one-the-beginning
act: 1
chapter: 1
scene: 1
type: chapter
status: planning
word_count_target: 2000
word_count_min: 1800
word_count_max: 2200
pov: ""
characters: []
setting: ""
date: ""
time: ""
conflict: ""
theme: ""
tone: ""
draft_file: "../../06-First Draft/Act 1/scene01.md"
order: 1
created: ""
updated: ""
---
# Slug
# Chapter One: The Beginning
## POV:
**Planning Template** | **ID:** scene_01 | **Status:** {{ status | capitalizes }}
## Characters:
---
## Setting:
## Planning Metadata
## Conflict:
| Attribute | Value |
|-----------|-------|
| **Act** | {{ act }} |
| **Chapter** | {{ chapter }} |
| **Scene** | {{ scene }} |
| **Type** | {{ type | capitalizes }} |
| **Order** | {{ order }} |
| **Draft File** | [`{{ draft_file | replace('../../', '') }}`]({{ draft_file }}) |
## Feeling to convey:
---
## Word Count Target:
## Creative Elements
## The Setup:
### POV
> {{ pov if pov else "Not specified" }}
## The Reveal:
### Characters
{% for character in characters %}- [[{{ character }}]]
{% endfor %}
### Things to Note:
### Setting
> {{ setting if setting else "Not specified" }}
### Rough draft:
### Date & Time
> {{ date if date else "Not specified" }} | {{ time if time else "Not specified" }}
---
## Story Structure
### Conflict
> {{ conflict if conflict else "Not specified" }}
### Theme
> {{ theme if theme else "Not specified" }}
### Tone
> {{ tone if tone else "Not specified" }}
---
## Word Count Goals
| Metric | Value |
|--------|-------|
| **Target** | {{ word_count_target }} |
| **Minimum** | {{ word_count_min }} |
| **Maximum** | {{ word_count_max }} |
---
## Scene Planning
### The Setup
>
### The Reveal
>
### Things to Note
-
-
---
## Status Tracking
- [ ] Scene outline complete
- [ ] Character arcs aligned
- [ ] Location details verified
- [ ] Conflict established
- [ ] Word count target set
- [ ] Ready for drafting
---
**Draft File:** [Open Draft]({{ draft_file }}) | **Created:** {{ created }} | **Updated:** {{ updated }}
@@ -0,0 +1,91 @@
---
id: draft_scene_01
title: "Chapter One: The Beginning"
slug: chapter-one-the-beginning
planning_template: "../../05-Plot/act_1/scene_01.md"
act: 1
chapter: 1
scene: 1
type: draft
status: not_started
word_count: 0
word_count_updated: ""
session_word_count: 0
last_session: ""
total_sessions: 0
pov: ""
version: 1
created: ""
updated: ""
---
# Chapter One: The Beginning
**Draft File** | **ID:** draft_scene_01 | **Status:** {{ status | replace('_', ' ') | capitalizes }}
---
## Planning Reference
> **Linked to:** [Planning Template]({{ planning_template }})
---
## Scene Metadata
| Attribute | Value |
|-----------|-------|
| **Act** | {{ act }} |
| **Chapter** | {{ chapter }} |
| **Scene** | {{ scene }} |
| **Type** | {{ type | capitalizes }} |
| **POV** | {{ pov if pov else "Not set" }} |
| **Version** | {{ version }} |
---
## Word Count Tracking
| Metric | Value |
|--------|-------|
| **Target** | 2000 (from planning) |
| **Current** | {{ word_count }} |
| **This Session** | {{ session_word_count }} |
| **Last Updated** | {{ word_count_updated if word_count_updated else "Never" }} |
---
## Draft Content
### Rough Draft:
[Write your scene content here...]
---
## Writing Notes
### Session Log
| Date | Words Added | Notes |
|------|--------------|-------|
| {{ last_session if last_session else "" }} | {{ session_word_count }} | |
### Revision Notes
-
-
---
## Status Checklist
- [ ] First draft complete
- [ ] Word count target met
- [ ] POV consistent
- [ ] Character voices distinct
- [ ] Setting details accurate
- [ ] Conflict resolved/advanced
- [ ] Ready for revision
---
**Planning Template:** [Open Planning]({{ planning_template }}) | **Created:** {{ created }} | **Updated:** {{ updated }}
@@ -0,0 +1,99 @@
---
id: draft_scene_new
title: "New Scene Title"
slug: new-scene-title
planning_template: ""
act: 1
chapter: 1
scene: 99
type: draft
status: not_started
word_count: 0
word_count_updated: ""
session_word_count: 0
last_session: ""
total_sessions: 0
pov: ""
version: 1
created: ""
updated: ""
---
# New Scene Title
**Draft File** | **ID:** draft_scene_new | **Status:** {{ status | replace('_', ' ') | capitalizes }}
---
## Planning Reference
> **Linked to:** {{ planning_template if planning_template else "[Create Planning Template](#)" }}
---
## Scene Metadata
| Attribute | Value |
|-----------|-------|
| **Act** | {{ act }} |
| **Chapter** | {{ chapter }} |
| **Scene** | {{ scene }} |
| **Type** | {{ type | capitalizes }} |
| **POV** | {{ pov if pov else "Not set" }} |
| **Version** | {{ version }} |
---
## Word Count Tracking
| Metric | Value |
|--------|-------|
| **Target** | (from planning) |
| **Current** | {{ word_count }} |
| **This Session** | {{ session_word_count }} |
| **Last Updated** | {{ word_count_updated if word_count_updated else "Never" }} |
---
## Draft Content
### Rough Draft:
[Write your scene content here...]
---
## Writing Notes
### Session Log
| Date | Words Added | Notes |
|------|--------------|-------|
| {{ last_session if last_session else "" }} | {{ session_word_count }} | |
### Revision Notes
-
-
---
## Status Checklist
- [ ] First draft complete
- [ ] Word count target met
- [ ] POV consistent
- [ ] Character voices distinct
- [ ] Setting details accurate
- [ ] Conflict resolved/advanced
- [ ] Ready for revision
---
**Instructions:**
1. Copy this file to the appropriate Act/Chapter folder
2. Rename to `sceneXX.md` (e.g., `scene02.md`)
3. Update the YAML frontmatter with scene details
4. Set `planning_template` to point to the corresponding planning file
5. Create the planning file using the template in `05-Plot/_template.md`
6. Update word count as you write
**Related:** [Story Bible](../../03-Story-Bible/_index.md) | **Created:** {{ created }} | **Updated:** {{ updated }}
@@ -0,0 +1,314 @@
# Scene Management Scripts
Automate the creation and linking of planning and draft files.
---
## Scripts Available
### `create_scene.py`
Creates linked planning and draft files for new scenes.
---
## Quick Start
### 1. Create a New Scene Pair
```bash
# Navigate to your project root
cd /path/to/your/project
# Create a new scene (act 1, chapter 1, scene 2)
python scripts/create_scene.py --act 1 --chapter 1 --scene 2 --title "Chapter Two: The Journey"
```
This creates:
- `05-Plot/act_1/scene_02.md` (planning template)
- `06-First Draft/Act 1/scene02.md` (draft file)
- Both files are automatically linked to each other
### 2. Create Draft from Existing Planning
```bash
# If you have an existing planning file but no draft
python scripts/create_scene.py --from-planning 05-Plot/act_1/scene_01.md
```
This creates the corresponding draft file and links it.
### 3. Create Planning from Existing Draft
```bash
# If you have an existing draft file but no planning
python scripts/create_scene.py --from-draft "06-First Draft/Act 1/scene01.md"
```
This creates the corresponding planning file and links it.
---
## Usage Examples
### Minimal (auto-generates title)
```bash
python scripts/create_scene.py --scene 3
```
Creates scene 3 in act 1, chapter 1 with title "Chapter 1: Scene 3"
### Full specification
```bash
python scripts/create_scene.py \
--act 2 \
--chapter 3 \
--scene 5 \
--title "Chapter Three: The Revelation" \
--type chapter
```
### Batch create multiple scenes
```bash
for scene in {2..10}; do
python scripts/create_scene.py --chapter 1 --scene $scene
Done
```
---
## File Structure
### Planning Files (`05-Plot/`)
```
05-Plot/
├── _template.md # Template for new planning files
├── act_1/
│ ├── scene_01.md # Planning for act 1, scene 1
│ ├── scene_02.md # Planning for act 1, scene 2
│ └── ...
├── act_2/
│ ├── scene_01.md
│ └── ...
└── act_3/
└── ...
```
Each planning file contains:
- YAML frontmatter with metadata (act, chapter, scene, word count targets, etc.)
- `draft_file` field pointing to the corresponding draft file
- Scene planning sections (setup, reveal, notes)
### Draft Files (`06-First Draft/`)
```
06-First Draft/
├── _template.md # Template for new draft files
├── Act 1/
│ ├── scene01.md # Draft for act 1, scene 1
│ ├── scene02.md # Draft for act 1, scene 2
│ └── ...
├── Act 2/
│ ├── scene01.md
│ └── ...
└── Act 3/
└── ...
```
Each draft file contains:
- YAML frontmatter with metadata
- `planning_template` field pointing to the corresponding planning file
- Word count tracking (current, session, target from planning)
- Actual scene content
---
## Linking System
The two files are linked via relative paths in their frontmatter:
**Planning file (`05-Plot/act_1/scene_01.md`):**
```yaml
---
draft_file: "../../06-First Draft/Act 1/scene01.md"
---
```
**Draft file (`06-First Draft/Act 1/scene01.md`):**
```yaml
---
planning_template: "../../05-Plot/act_1/scene_01.md"
---
```
This bidirectional linking allows:
- Navigating from planning to draft and vice versa
- Sharing metadata between files
- Tracking progress across both
---
## Metadata Reference
### Planning File Fields
| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique identifier (e.g., `scene_01_01_01`) |
| `title` | string | Scene/chapter title |
| `slug` | string | URL-friendly identifier |
| `act` | int | Act number |
| `chapter` | int | Chapter number |
| `scene` | int | Scene number |
| `type` | string | `scene` \| `chapter` \| `interlude` |
| `status` | string | `planning` \| `ready` \| `blocked` |
| `word_count_target` | int | Target word count |
| `word_count_min` | int | Minimum acceptable words |
| `word_count_max` | int | Maximum acceptable words |
| `pov` | string | Point of view character |
| `characters` | list | Characters in this scene |
| `setting` | string | Primary location |
| `date` | string | Date in story timeline |
| `time` | string | Time of day |
| `conflict` | string | Central conflict |
| `theme` | string | Thematic focus |
| `tone` | string | Emotional tone |
| `draft_file` | string | Path to linked draft file |
| `order` | int | Sort order |
### Draft File Fields
| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique identifier (e.g., `draft_scene_01_01_01`) |
| `title` | string | Scene/chapter title |
| `slug` | string | URL-friendly identifier |
| `act` | int | Act number |
| `chapter` | int | Chapter number |
| `scene` | int | Scene number |
| `type` | string | `draft` |
| `status` | string | `not_started` \| `in_progress` \| `completed` \| `needs_revision` |
| `word_count` | int | Current word count |
| `word_count_updated` | string | Last word count update date |
| `session_word_count` | int | Words written in current session |
| `last_session` | string | Date of last writing session |
| `total_sessions` | int | Number of writing sessions |
| `pov` | string | Point of view character |
| `version` | int | Draft version |
| `planning_template` | string | Path to linked planning file |
---
## Integration with Your Workflow
### With Drag-and-Drop Reordering
If your editor supports drag-and-drop chapter reordering, the `order` field in the frontmatter is available for sorting. Update this field when reordering scenes.
### With File Watchers
To automatically create corresponding files when a new file is created:
1. **Option A: Use the script manually** (recommended)
```bash
# After creating a planning file manually, run:
python scripts/create_scene.py --from-planning 05-Plot/act_1/scene_05.md
```
2. **Option B: Set up a file watcher**
Create a watcher script that triggers `create_scene.py` when new files are detected.
3. **Option C: Editor integration**
If your editor supports custom commands, add a command that calls:
```bash
python scripts/create_scene.py --from-draft "${file}"
```
---
## Tips
1. **Naming Convention**
- Planning: `scene_{number:02d}.md` (e.g., `scene_01.md`, `scene_02.md`)
- Draft: `scene{number:02d}.md` (e.g., `scene01.md`, `scene02.md`)
- Note the slight difference (underscore vs. no underscore)
2. **Folder Structure**
- Planning: `05-Plot/act_{N}/`
- Draft: `06-First Draft/Act N/`
- Note the difference in folder naming (act_1 vs. Act 1)
3. **ID Generation**
- Planning IDs: `scene_{act:02d}_{chapter:02d}_{scene:02d}`
- Draft IDs: `draft_scene_{act:02d}_{chapter:02d}_{scene:02d}`
4. **Word Count Targets**
- Set in planning file
- Displayed in draft file
- Not automatically synced (manual update or via script)
---
## Troubleshooting
### "Module not found: yaml"
```bash
pip install pyyaml
```
### File paths not working
- Ensure you're running the script from the project root
- Check that the `scripts/` directory is in your project
- Verify relative paths are correct for your folder structure
### Frontmatter not parsing
- Ensure your files start with `---` on the first line
- Ensure there's a closing `---` after the frontmatter
- YAML is sensitive to indentation (use spaces, not tabs)
---
## Advanced Usage
### Custom Metadata
Add any additional fields to the frontmatter:
```bash
python scripts/create_scene.py --scene 1 --custom_field "value"
```
### Bulk Operations
Create multiple scenes at once:
```bash
# Create scenes 1-10 for chapter 1
for i in {1..10}; do
python scripts/create_scene.py --chapter 1 --scene $i
done
```
### Sync Existing Files
If you have existing files without links, you can manually add the frontmatter:
**Planning file:**
```yaml
---
draft_file: "../../06-First Draft/Act 1/scene01.md"
---
```
**Draft file:**
```yaml
---
planning_template: "../../05-Plot/act_1/scene_01.md"
---
```
---
## Related Files
- `05-Plot/_template.md` - Planning file template
- `06-First Draft/_template.md` - Draft file template
- `03-Story-Bible/` - Story Bible for character/location/lore tracking
@@ -0,0 +1,395 @@
#!/usr/bin/env python3
"""
Scene Creation Script
Creates linked planning and draft files for a new scene.
Usage:
python create_scene.py --act 1 --chapter 1 --scene 2 --title "Chapter Two: The Journey"
Or with minimal args (auto-generates title):
python create_scene.py --act 1 --chapter 1 --scene 2
Or create from existing planning file:
python create_scene.py --from-planning 05-Plot/act_1/scene_01.md
Or create from existing draft file:
python create_scene.py --from-draft "06-First Draft/Act 1/scene01.md"
"""
import argparse
import os
import re
import sys
from pathlib import Path
from datetime import datetime
# Get the project root (parent of scripts directory)
SCRIPTS_DIR = Path(__file__).parent
PROJECT_ROOT = SCRIPTS_DIR.parent
# Template paths
PLANNING_TEMPLATE = PROJECT_ROOT / "05-Plot" / "_template.md"
DRAFT_TEMPLATE = PROJECT_ROOT / "06-First Draft" / "_template.md"
def slugify(text):
"""Convert text to URL-friendly slug."""
if not text:
return ""
# Convert to lowercase
text = text.lower()
# Remove special characters
text = re.sub(r'[^\w\s-]', '', text)
# Replace spaces with hyphens
text = re.sub(r'[\s_]+', '-', text)
# Remove leading/trailing hyphens
text = text.strip('-')
return text
def generate_title(act, chapter, scene):
"""Generate a default title based on act/chapter/scene."""
return f"Chapter {chapter}: Scene {scene}"
def parse_yaml_frontmatter(content):
"""Parse YAML frontmatter from markdown file."""
import yaml
if not content.startswith('---'):
return {}
# Find the frontmatter
lines = content.split('\n')
if lines[0].strip() == '---':
frontmatter_lines = []
for line in lines[1:]:
if line.strip() == '---':
break
frontmatter_lines.append(line)
try:
return yaml.safe_load('\n'.join(frontmatter_lines)) or {}
except yaml.YAMLError:
return {}
return {}
def update_frontmatter(content, updates):
"""Update YAML frontmatter in markdown content."""
lines = content.split('\n')
if not lines[0].strip() == '---':
# No frontmatter, add it
yaml_content = "\n".join(f"{k}: {v}" for k, v in updates.items())
return f"---\n{yaml_content}\n---\n\n" + content
# Find and replace frontmatter
in_frontmatter = False
frontmatter_start = 0
frontmatter_end = 0
for i, line in enumerate(lines):
if line.strip() == '---':
if not in_frontmatter:
frontmatter_start = i
in_frontmatter = True
else:
frontmatter_end = i
break
if frontmatter_end == 0:
return content
# Parse existing frontmatter
existing = parse_yaml_frontmatter(content)
existing.update(updates)
# Generate new frontmatter
yaml_lines = ["---"]
for key, value in existing.items():
if isinstance(value, str):
yaml_lines.append(f"{key}: \"{value}\"")
elif isinstance(value, list):
yaml_lines.append(f"{key}: {value}")
else:
yaml_lines.append(f"{key}: {value}")
yaml_lines.append("---")
# Reconstruct content
new_content = "\n".join(yaml_lines) + "\n\n" + "\n".join(lines[frontmatter_end + 1:])
return new_content
def create_planning_file(act, chapter, scene, title, slug=None, **kwargs):
"""Create a new planning file."""
if slug is None:
slug = slugify(title)
# Create path
act_dir = PROJECT_ROOT / "05-Plot" / f"act_{act}"
act_dir.mkdir(parents=True, exist_ok=True)
filename = act_dir / f"scene_{scene:02d}.md"
# Read template
with open(PLANNING_TEMPLATE, 'r') as f:
template_content = f.read()
# Generate ID
scene_id = f"scene_{act:02d}_{chapter:02d}_{scene:02d}"
# Prepare frontmatter updates
frontmatter = {
'id': scene_id,
'title': title,
'slug': slug,
'act': act,
'chapter': chapter,
'scene': scene,
'order': scene,
'created': datetime.now().strftime("%Y-%m-%d"),
'updated': datetime.now().strftime("%Y-%m-%d"),
}
# Update with any additional kwargs
frontmatter.update(kwargs)
# Update draft_file path if not provided
if 'draft_file' not in frontmatter:
draft_path = f"../../06-First Draft/Act {act}/scene{scene:02d}.md"
frontmatter['draft_file'] = draft_path
# Update content
content = update_frontmatter(template_content, frontmatter)
# Write file
with open(filename, 'w') as f:
f.write(content)
return filename
def create_draft_file(act, chapter, scene, title, slug=None, planning_path=None, **kwargs):
"""Create a new draft file."""
if slug is None:
slug = slugify(title)
# Create path
act_dir = PROJECT_ROOT / "06-First Draft" / f"Act {act}"
act_dir.mkdir(parents=True, exist_ok=True)
filename = act_dir / f"scene{scene:02d}.md"
# Read template
with open(DRAFT_TEMPLATE, 'r') as f:
template_content = f.read()
# Generate ID
scene_id = f"draft_scene_{act:02d}_{chapter:02d}_{scene:02d}"
# Prepare frontmatter updates
frontmatter = {
'id': scene_id,
'title': title,
'slug': slug,
'act': act,
'chapter': chapter,
'scene': scene,
'created': datetime.now().strftime("%Y-%m-%d"),
'updated': datetime.now().strftime("%Y-%m-%d"),
}
# Update with any additional kwargs
frontmatter.update(kwargs)
# Set planning_template path if not provided
if 'planning_template' not in frontmatter:
if planning_path:
# Use the provided planning path
relative_path = os.path.relpath(planning_path, act_dir)
frontmatter['planning_template'] = relative_path
else:
# Generate default path
planning_path = f"../../05-Plot/act_{act}/scene_{scene:02d}.md"
frontmatter['planning_template'] = planning_path
# Update content
content = update_frontmatter(template_content, frontmatter)
# Write file
with open(filename, 'w') as f:
f.write(content)
return filename
def link_files(planning_path, draft_path):
"""Ensure both files are linked to each other."""
# Update planning file with draft path
with open(planning_path, 'r') as f:
planning_content = f.read()
relative_draft = os.path.relpath(draft_path, Path(planning_path).parent)
planning_content = update_frontmatter(planning_content, {
'draft_file': relative_draft
})
with open(planning_path, 'w') as f:
f.write(planning_content)
# Update draft file with planning path
with open(draft_path, 'r') as f:
draft_content = f.read()
relative_planning = os.path.relpath(planning_path, Path(draft_path).parent)
draft_content = update_frontmatter(draft_content, {
'planning_template': relative_planning
})
with open(draft_path, 'w') as f:
f.write(draft_content)
def create_scene_pair(act, chapter, scene, title=None, **kwargs):
"""Create both planning and draft files."""
if title is None:
title = generate_title(act, chapter, scene)
slug = slugify(title)
# Create planning file
planning_path = create_planning_file(
act, chapter, scene, title, slug, **kwargs
)
# Create draft file (without planning_path initially)
draft_path = create_draft_file(
act, chapter, scene, title, slug, **kwargs
)
# Link them together
link_files(planning_path, draft_path)
print(f"✓ Created planning file: {planning_path.relative_to(PROJECT_ROOT)}")
print(f"✓ Created draft file: {draft_path.relative_to(PROJECT_ROOT)}")
print(f"✓ Linked files together")
return planning_path, draft_path
def create_from_planning(planning_path_str):
"""Create a draft file from an existing planning file."""
planning_path = Path(planning_path_str)
if not planning_path.exists():
print(f"Error: Planning file not found: {planning_path}")
sys.exit(1)
# Parse planning file
with open(planning_path, 'r') as f:
planning_content = f.read()
frontmatter = parse_yaml_frontmatter(planning_content)
if not frontmatter:
print(f"Error: No valid frontmatter in {planning_path}")
sys.exit(1)
act = frontmatter.get('act', 1)
chapter = frontmatter.get('chapter', 1)
scene = frontmatter.get('scene', 1)
title = frontmatter.get('title', generate_title(act, chapter, scene))
# Create draft file
draft_path = create_draft_file(
act, chapter, scene, title,
planning_path=planning_path
)
# Link files
link_files(planning_path, draft_path)
print(f"✓ Created draft file: {draft_path.relative_to(PROJECT_ROOT)}")
print(f"✓ Linked to planning file: {planning_path.relative_to(PROJECT_ROOT)}")
return draft_path
def create_from_draft(draft_path_str):
"""Create a planning file from an existing draft file."""
draft_path = Path(draft_path_str)
if not draft_path.exists():
print(f"Error: Draft file not found: {draft_path}")
sys.exit(1)
# Parse draft file
with open(draft_path, 'r') as f:
draft_content = f.read()
frontmatter = parse_yaml_frontmatter(draft_content)
if not frontmatter:
print(f"Error: No valid frontmatter in {draft_path}")
sys.exit(1)
act = frontmatter.get('act', 1)
chapter = frontmatter.get('chapter', 1)
scene = frontmatter.get('scene', 1)
title = frontmatter.get('title', generate_title(act, chapter, scene))
# Create planning file
planning_path = create_planning_file(
act, chapter, scene, title,
draft_file=draft_path
)
# Link files
link_files(planning_path, draft_path)
print(f"✓ Created planning file: {planning_path.relative_to(PROJECT_ROOT)}")
print(f"✓ Linked to draft file: {draft_path.relative_to(PROJECT_ROOT)}")
return planning_path
def main():
parser = argparse.ArgumentParser(
description='Create linked planning and draft files for scenes.'
)
# For creating new scene pair
parser.add_argument('--act', type=int, default=1, help='Act number')
parser.add_argument('--chapter', type=int, default=1, help='Chapter number')
parser.add_argument('--scene', type=int, required=True, help='Scene number')
parser.add_argument('--title', type=str, default=None, help='Scene title')
parser.add_argument('--type', type=str, default='scene',
choices=['scene', 'chapter', 'interlude'],
help='Scene type')
# For creating from existing files
parser.add_argument('--from-planning', type=str, default=None,
help='Create draft from existing planning file')
parser.add_argument('--from-draft', type=str, default=None,
help='Create planning from existing draft file')
args = parser.parse_args()
if args.from_planning:
create_from_planning(args.from_planning)
elif args.from_draft:
create_from_draft(args.from_draft)
else:
create_scene_pair(
act=args.act,
chapter=args.chapter,
scene=args.scene,
title=args.title,
type=args.type
)
if __name__ == '__main__':
main()