Markus Michalski FAQ

StoryForge Character Anatomy

Structure of a StoryForge character file: frontmatter schema, roles, status, recommended sections, behavior of the character hook, alias resolution, series trackers and the series lifecycle.

StoryForge Character Anatomy

Deutsche Version

Back to StoryForge Main Page


Overview

Every character file of a book is checked after saving by the PostToolUse hook validate_character.py. This page describes:

The template is in the plugin at templates/character.md and contains hints for every section.


Location

Book category Directory Example
fiction {book}/characters/{slug}.md characters/arne-kruse.md
memoir {book}/people/{slug}.md people/grandfather.md
Series series/{series}/characters/{tracker-slug}.md characters/king-caelan.md

One file per character. INDEX.md is skipped by the hook. For memoir the person files follow a different schema, see Memoir Support.


Frontmatter

The hook requires at least:

---
name: "Display name"
role: protagonist
status: Concept
---

For fiction characters, name, role and status are required. If one is missing, the hook reports it back to the model with exit code 2 after the write, and the model has to add it. For memoir person files role does not apply, see "Memoir person files" below. Further fields such as age, job, description, archetype or pov are free metadata the hook ignores. The template additionally carries gender (pre-filled empty) and aliases (commented out).

These optional blocks are evaluated by checking tools:

State of the POV character

The chapter writing brief reads inventory, clothing, injuries, altered states and perception limiters of the POV character in this order:

  1. the frontmatter fields current_inventory, current_clothing, current_injuries, altered_states and environmental_limiters of the character file, if present
  2. the snapshot in the series database that chapter-writer writes with update_character_snapshot when closing a chapter (the character file stays unchanged)
  3. heuristics over the chapter timeline and the drafts

A frontmatter field as_of_chapter may sit in the file, but the brief does not read it.

If no source delivers anything, the brief carries a warning and the skill asks instead of inventing. Frontmatter values arise, for example, from bootstrapping from a previous volume or by your own hand.

Provenance marker series_evolution_imported_from

When /storyforge:bootstrap-book-from-series fills a character file, it carries the field series_evolution_imported_from: B1. It is informational and says which volume the start values came from. After that you can change any field freely.

Alias resolution

scan_for_named_characters fills characters_present in the brief by searching the outline for the name field and all aliases. Two sources are combined:

Matching uses word boundaries, so Lin does not hit in Linguistics, and dotted initials work.


Valid Roles

Role When
protagonist main POV character
deuteragonist second most important character, equal rank
antagonist main opponent
love-interest romantic anchor
mentor guides the protagonist
foil contrast character
herald brings the call to action
confidant trusted counterpart for the inner voice
supporting named, recurring characters
minor one-off or subplot-only characters, the hook skips the section recommendations

An unknown role produces a warning with the list of valid values.


Status Levels

Concept → Profile → Backstory → Arc Defined → Final
Status Meaning Content
Concept idea sketched, role known name, role, short description
Profile profile worked out plus appearance, personality, rough voice
Backstory wound and lie identified plus ghost, want vs. need, fatal flaw
Arc Defined arc mapped end to end plus character arc with beats
Final production-ready plus voice with sample dialogue, all relationships

The status is a signal to you about how mature the file is. It does not control any tool.


The hook warns if these are missing for a character who is not minor. It accepts level-2 and level-3 headings.

Section Alternatives that suffice
## Want vs. Need
## Fatal Flaw
## The Ghost ## Backstory / The Wound or ## Backstory
## Motivation Chain ## GMC or ## GMC (Goal / Motivation / Conflict)

Want vs. Need

The external goal against the inner truth. This includes the lie the character believes, which keeps them from the need.

Example: Want: prove he is more than others see. Need: accept that he is enough. Lie: "I am not enough."

The Ghost

The single formative event or lasting condition that shaped the character. It is the root of the lie. The template creates it as ### The Ghost under ## Backstory.

Fatal Flaw

Not a mere weakness, but a flaw that actively causes problems, ties into the theme and is rooted in the ghost.

Motivation Chain

Ask "why?" three times: first the stated goal, then the emotional engine, then the wound-driven core need.

Character Arc

Arc type (positive, negative, flat) plus beats: setup, challenge, midpoint, crisis, resolution. Required for the status Arc Defined.

Relationships

The template lists the section as ## Key Relationships, and that is exactly the heading the harvest reader of /storyforge:harvest-character-evolution accepts too — along with ## Relationships, ## Relationship and ## Beziehungen (with or without the "über die Bände" suffix). No renaming is needed. Bullets with a bold name are the usual format:

## Relationships

- **Theo:** partner, the relationship that pulls him back into the family.
- **Caelan:** father, his longest-running unresolved conflict.

When Characters Need Less

Not every named character needs Arc Defined. The hook is only a signal here, the yardstick depends on the role:

Character Typical status Expected
Protagonist (POV) Arc Defined or Final all recommended sections and voice with a sample
Deuteragonist Arc Defined all recommended sections
Antagonist at least Backstory want vs. need, fatal flaw, ghost; villains have inner logic too
Love interest Backstory, with their own arc Arc Defined want vs. need and ghost
Mentor, herald, foil, confidant Profile to Backstory voice and the slice of psychology that carries their function
Supporting with own arc Backstory ghost and arc
Supporting (recurring) Profile personality, voice, appearance
Minor Profile or Concept just enough to render them

Behavior of the Hook

The hook runs as PostToolUse after Write, Edit and MultiEdit on .md files in characters/ and people/. The file is already written at that point. Exit code 2 returns the message to the model, which has to fix the finding.

What is reported with exit code 2

Condition Message
no YAML frontmatter Missing YAML frontmatter
invalid YAML Invalid YAML frontmatter: ...
frontmatter is not a mapping Frontmatter is not a YAML mapping
missing required field Missing frontmatter field: 'status'

What warns (exit code 0)

Condition Message
unknown role Unknown role 'wizard'. Valid: ...
missing recommended section Missing recommended section '## Want vs. Need'

What is skipped

Memoir person files

Files recognizable as memoir person files by person_category, consent_status or real_name in the frontmatter get a reduced check: the value of role is not compared against the role list, and the recommended sections of fiction characters do not apply. role is also not a required field for them — only name and status are. The tool create_person writes status but no role, and passes the check right away. Details: Memoir Support.


Series Trackers

Series projects have, per character, an additional tracker file under series/{series}/characters/{tracker-slug}.md. It is a thin series layer: it records what is constant across all volumes and keeps the development per volume.

File type Path Purpose
Character file in the book projects/{book}/characters/{slug}.md full profile: psychology, arc, voice. Source of truth for one book.
Series tracker series/{series}/characters/{tracker-slug}.md development across volumes, relationships across volumes

The two are linked through the optional field book_slug in the tracker. If it is missing, the tracker's slug counts as the slug of the book file:

---
name: "King Caelan"
slug: king-caelan          # slug of the tracker
book_slug: caelan          # optional: book file is caelan.md
role: protagonist
species: vampire
status: "Profile"
recurs_in: ["B1", "B2"]
tracker_type: "thin"
---

You only need the field when the tracker carries a role or title slug but the book file the bare name. Without the link, the brief returns series_evolution: null for that character.

tracker_type is thin (default, the book file stays the source of truth) or full (the tracker itself, rare).

Structure of a tracker

## Snapshot
One paragraph of essence at series scale: what is constant across all volumes?

## Evolution per Band
### B1 Start
### B1 Ende
### B2 (geplant)

## Beziehungen über die Bände
- **Other character:** B1 dynamic → B2 shift → B3 resolution

## Updates Log

The parser knows two forms: bullets per volume (### B1 Firelight with **Start:** and **Ende:**) and separate H3 headings (### B1 Start, ### B1 Ende). Writing skills keep the form your tracker already uses. The template is templates/series-character-tracker.md.


Series Lifecycle

This is how a character moves from one volume to the next:

  1. During book 1: when a chapter is closed at status Review or Final, chapter-writer proposes a snapshot of the POV character and, after your confirmation, saves it in the database. If the chapter stays at Draft, the proposal is skipped.
  2. Book 1 is complete: the book status chain runs Drafting, Revision, then Proofread once all chapters are Final. Editing, Export Ready and Published you set yourself. Once the book is at Export Ready or Published, /storyforge:harvest-character-evolution firelight proceeds without a question. At Editing or Proofread the skill asks whether to run anyway, earlier it blocks. It reads the end state of each recurring character and their relationships, synthesizes a "B1 Ende" summary and goes through the characters one by one with you (accept, edit, skip, keep existing). What is confirmed goes into the tracker, plus an entry in the updates log.
  3. Create book 2: /storyforge:new-book itself asks for the series and the number, and registers the book via add_book_to_series right while creating it if the number is known. With the series and number known, the skill then automatically copies the recurring character files (filtered by recurs_in) 1:1 into the new book with copy_recurring_chars_to_new_book, after your confirmation. Characters that only appear in book 1 stay out, and you create new book 2 characters manually. The copy step derives the band tag from series_number and skips itself when the number is missing, 0 or 1. If the number was left open at creation and you register it later via add_book_to_series, this automatic copy step no longer runs — you then copy by hand. The Series Workflow Example shows the order.
  4. Bootstrap: /storyforge:bootstrap-book-from-series firelight moonrise reads "B1 Ende" and "B2 (geplant)" per tracker, synthesizes a start state, goes through the characters one by one with you and writes it into the frontmatter of the character file in the new volume, together with series_evolution_imported_from. If the previous book is not yet at Export Ready or Published, the skill asks whether to run anyway.
  5. Writing: chapter-writer reads characters_present[*].series_evolution: the end state in the previous volume (previous_book_end), the plan for the current volume (current_book_plan) and the relationship development (relationships_evolution). The brief fills this for books in either layout, flat under projects/{book} and nested under series/{series}/{book}.
  6. Again: once book 2 is completed in the same way, the harvest runs again for book 3.
Skill or tool When Reads Writes
chapter-writer (POV snapshot) chapter end at Review or Final chapter timeline snapshot in the database
harvest-character-evolution end of book, at book status Export Ready or Published (Editing and Proofread with a question) character file, relationships tracker B{N} Ende, updates log
copy_recurring_chars_to_new_book (after add_book_to_series) start of the next volume tracker recurs_in, character files character files in the new book (copies)
bootstrap-book-from-series after creating, before writing tracker B{prev} Ende, B{new} (geplant) frontmatter of the character file, updates log
Chapter writing brief (series_evolution) every brief in a series book tracker writes nothing

A complete example with all outputs is in the Series Workflow Example.

When series_evolution stays empty

The field is always present in the brief so consumers can check for null. It is null when one of these conditions applies:


← Back to StoryForge Main Page