AChronicles / Accelerated Accelerated · 13 modules

AshForge Chronicles · the whole tool, one course

A quest is rows and slots.
A menu is not a branch.

Chronicles authors quests, objectives and dialogue. Most of what feels like branching is a menu that reconverges, and its validation promises less than its name suggests — this course is the whole tool with those two facts up front.

Application  AshForge Chronicles Prerequisites  none Format  one course, 13 modules Time  ~80 min

What it is

A quest editor. Objectives are rows, dialogue is slots, and both save into your mod's data.

Modules 1–4 are reading and writing a quest, 5–8 are branching, 9–13 are what actually reaches the game.

The honest limit

Quests can never ship as data. The game has no quest, dialogue or lore definition type — none. Chronicles' output reaches a game only through a compiled assembly.

That is not pending work; it is the shape of the game. Modules 9 onward.

Why this is one course

Chronicles is a focused tool. Its content is 13 things worth knowing, not three escalating tiers — the old split implied the later material needed the earlier, and it does not. Read straight through, or jump to the module that matches your problem.

01

The Quests tab

Read one before writing one

Read Demo data ~4 min

The Quests tab is already active when Chronicles opens, and there are two demo entries waiting in the list.

Drill01

Select First Contact
  1. Click the first of the two entries, First Contact.
  2. The inspector fills with the whole quest at once.
  3. Read down it before touching anything.

Done whenYou can name every section without scrolling back.

What is there01b

Eight sections, one of them different
  • Title, and a free-text Description
  • Difficulty — Easy, Medium, Hard or Legendary
  • Status — Draft, Active or Complete
  • Objectives, Rewards, Prerequisites and Notes

Most of those are prose and behave exactly as you would expect. Objectives does not, and that is the whole point of this tutorial.

02

The one idea

An objective is a row

Read 4 fields ~8 min

Press Add Objective and you do not get a text box. You get four separate fields, and only one of them is written for a human being.

Type Description Target Seconds the game reads the player reads the game reads the game reads nothing checks that these two agree

Figure 01 — one objective Four fields. Three of them are machine-facing, one is not, and no part of the tool keeps them in step.

Type is a dropdown offering exactly four options: elapsed, eliminate_faction, manual and deliver. That word is what the game enforces. Target names what it acts on, and Seconds matters for the timed types. Description is the sentence the player sees, and the game does nothing with it whatsoever.

Key
The description is a label on the box rather than the thing inside it. Change the wording and the quest plays identically. Change the Type and the quest becomes a different quest, whatever the sentence still claims.
Note
The dropdown and the documentation disagree. The data model's own comment lists six types, adding collect, talk_to and custom while omitting manual. Only the four above are selectable, so trust the dropdown: it is what you can actually author with.
02b

Watch it come apart in the demo data

Look at First Contact's first objective. The inspector columns are narrow, so read the stored values rather than what happens to fit on screen:

Type: elapsed   Description: "Speak with the village elder"   Target: (empty)   Seconds: 0

Read as prose, that is an instruction to go and speak to someone. Read as data, it is a request to wait for zero seconds with nothing to wait on. The sentence says one thing and the fields say another, and nothing in the tool will point it out, because it is not an error. It is simply a quest that does something other than what it reads like.

The second objective is coherent by comparison: deliver, described as “Deliver the token”, with elder_token as its target. A type, a matching verb, and something to actually deliver.

And The Lost Cache goes one step further. Its third objective ships as type manual — the option the model's own documentation does not list. The demo content was authored against the dropdown rather than against the docs.

03

Your first quest

Write your own

Build New quest ~6 min

You are not starting from an empty form. Chronicles hands you a working skeleton and expects you to make it mean something.

Drill03

Press New, then fill it deliberately
  1. Press New. You get New Quest 3, Difficulty Medium, Status Draft.
  2. Note that one objective is already scaffolded for you: elapsed, sixty seconds.
  3. Give the quest a title and a description, then make that objective do real work.
  4. Choose deliver, describe it as “Bring the sealed crate to the elder”, and put the recipient's id in Target.

Done whenThe sentence and the data say the same thing.

Rewards03b

Names, not descriptions

The Rewards box says it plainly: one per line, reference Items/Weapons by name. Basic Medkit in the demo is not descriptive text, it is a lookup.

Spell it the way the game spells it, or the reward quietly is not there. It is the same idea as the objective Type: you are writing names into a vocabulary someone else defined.

04

Validation

What Validate promises

Check 3 areas ~4 min

Press Validate and you will most likely get “Narrative validation passed — no issues found.” It is worth knowing exactly what that sentence is promising, because it is narrower than it sounds.

AreaWhat it catches
Quests No title; no objectives at all; an objective with an empty description.
Dialogues No title; a node with neither text nor choices; a choice pointing at a node that does not exist.
Lore An entry missing its title or its content.

That is the entire list. It does not check that a Type matches its Description, that a Target exists, that a reward name is real, or that any of it is any good.

But Undo is

Autosave protects your typing. It does not protect an undo, and that is worth knowing before you rely on the button.

The first edit of a session cannot be undone at all. Chronicles only snapshots after a change, and never records the state you opened with, so after one edit there is nothing to go back to — the Undo button simply stays greyed until you have made a second one.

And an undo that does work never reaches the file. Undoing marks the project clean, which stops the autosave from firing, so the window and the file disagree. I removed a quest with Undo and watched the window show three while the file still held four — then reopened Chronicles and got the fourth one back.

So if an undo matters, make one more edit afterwards (or press Save) to force the corrected state onto disk.

Key
Validate is a broken-link checker rather than an editor. A green result means the narrative is structurally complete: every required field is filled and every dialogue choice points somewhere real. It says nothing at all about whether the quest works. The dangling-choice check is the one that genuinely earns its keep, and you will meet it properly in tutorial two.
05

The shipped demo

A menu, not a branch

Read Elder Greeting ~6 min

Select Elder Greeting and the inspector splits in two: a node graph in the top pane, and a scrolling form beneath it. The hint under the buttons spells the division out — “node graph is the top pane; wheel zooms/pans there; this form scrolls.”

There is exactly one node. The Elder says “Stranger… you carry the old mark.” and offers two choices. Scroll the form down to the Choices box and you can see why that is not yet a conversation:

I come in peace.||
I seek the cache.||

Each line is Text | NextNodeId | Condition. Both NextNodeId slots are empty, and empty means end. The player is being offered a fork where both paths stop.

Elder "…the old mark." ends ends Elder "…the old mark." Welcome The cache… what ships what you wire

Figure 01 — before and after Two choices with nowhere to go is a menu. The shape on the right is about thirty seconds of work away.

06

How dialogue is edited

Two editors, one model

Build Graph & text ~10 min

The Choices box carries its own warning label: “Choices (Text|NextNodeId lines; connections in graph also update this)”. That parenthesis is the important part of the sentence.

Key
The graph and the text box are two views of the same data. Drag a connection in the top pane and the text below rewrites itself; type an id into the text and the graph redraws. Neither one is the real version, and there is a Sync Graph <-> Model button precisely because two views over one model can drift apart.

Use whichever suits the job in front of you. The graph is better for shape — seeing where a conversation loops, spotting an orphaned node — and the text is better for precision. The text is also the only place the Condition field can be reached at all.

Do this

Add two nodes and wire them up

  1. Above the form are + NPC Node and + Player Node, plus a generic Add Dialogue Node and an Add Node (text) button lower down. Add two nodes, one reply for each existing choice. a branch needs somewhere for both paths to land
  2. Connect them by dragging from the Elder node's right-hand port to a new node's left port, or by typing the ids directly. either edits the same model, so use whichever is quicker for you
  3. To type them you need the ids, and the form gives them to you: each node's header reads Node 0 (5b868865), where the number is its position and the value in parentheses is its id. position and identity are different things, and only one of them is stable
I come in peace.|5b868865|
I seek the cache.|a91c3f02|

Reload the graph and the fork is real.

Note
Ids are generated rather than chosen. They are eight hexadecimal characters minted when the node is created, so yours will differ from every example on this page. Always read the id out of the form rather than copying one from a tutorial.
07

Conditions

The third slot

Read Text | Next | Condition ~5 min

Each choice line has room for one more field, and it is the one that connects a conversation to the rest of your narrative.

A condition gates whether the choice is offered at all. The data model gives its shape as a prerequisite expression, along the lines of quest:foo.complete.

Chronicles does not evaluate it. It does not parse it, check it, or warn you when it is nonsense. What it does do is carry it: the export writes each choice as { text, next, condition }, and the game is what reads that third field and decides.

Familiar
If you did the Sentinel tutorials this will feel like something you have already met, and it should. Both editors author declarations that the game fulfils. Sentinel names tasks it does not implement, and Chronicles writes conditions it does not evaluate. That is the shape of the suite rather than a gap in either tool.
08

Validation

The check that earns its keep

Break it Validate ~6 min

Tutorial one described Validate as a broken-link checker. This is the link it checks, and it is the one bug in a branching conversation that you genuinely cannot find by reading.

Do this

Break it on purpose

  1. Point a choice at a node that does not exist by editing a line to read I seek the cache.|deadbeef|. an id that was never minted is indistinguishable from one you deleted
  2. Click away so the edit commits, then press Validate. the edit lands when the field loses focus, not as you type
Validation found 1 issue(s).

Dialogue 'Elder Greeting': choice "I seek the cache."
links to a missing node (deadbeef)

It names the dialogue, quotes the choice text, and prints the id that went nowhere. Put the real id back and it returns to “Narrative validation passed — no issues found.”

This matters more than it looks. A dangling NextNodeId is invisible in the graph, because there is simply no line drawn, which looks identical to a choice that deliberately ends the conversation. It survives a read-through, because the text still makes sense. It only shows up in play, when a conversation stops dead in the middle.

Habit
Run Validate after any session of re-wiring, and especially after deleting a node. Deleting a node does not clear the choices that pointed at it — those choices are left aimed at an id that no longer exists, and this check is the only thing standing between that and a player.
09

The Lore tab

The hint that isn't a link

Read Lore tab ~8 min

Lore is where a narrative stops being a list of records and starts to feel like a place. It is also the point at which Chronicles quietly stops checking your work, and the demo entry that ships with the tool happens to illustrate the problem rather well.

Drill01

Open Lore → The Ashfall
  1. Switch to the Lore tab and select the one demo entry.
  2. Note the Category dropdown, which reads History.
  3. Read the opening of the Content body: “When the sky burned, the old world ended…”
  4. Then read the last three fields together, because they are the reason this tier exists.

Done whenYou can say which of those three fields the game will ever read, and which one is there purely for you.

The three fields01b

Two of these are data. One is a note to yourself.
  • Unlock Hint / Conditions — reading Complete First Contact
  • Related Quests (names/IDs, one per line) — empty
  • Related Dialogues (names/IDs, one per line) — empty

NoticeThe entry describes a dependency in prose while the field that would record it has been left blank.

Key

The hint tells you this entry depends on First Contact, and that quest does exist — it is two tabs away. What has been left empty is the field that would record the relationship in a form something could act on.

It is the same split the beginner tier found inside a single objective row, one level up: the prose and the data disagree, and only the data ships. Treat anything you write in Unlock Hint as a note to yourself.

Note
The field label is worth reading too, because it says names/IDs and means it. Accepting either is convenient while you are writing, but it is also the reason nothing downstream can check the value: a title is not an id, so there is no single thing to look the entry up by.
10

Validation, and where it stops

A count is not a check

Break it Validate Generate Report ~12 min

Tutorial two ended by praising Validate for catching a dangling NextNodeId, and that praise was earned. This lesson finds the edge of it. Rather than take anyone's word for where that edge sits, you are going to walk into it deliberately.

Do this

Point a lore entry at a quest that does not exist

  1. In Related Quests, type the name of a quest that appears nowhere in the project. The Quest That Never Was will do. the field is free text, so nothing will stop you
  2. Click away so the edit commits, then press Validate. Chronicles commits the edit when the field loses focus, so validating before that only tests the old value
  3. Read the result, then press Generate Report and open the .txt file it names in the log. the report is the only place this cross-reference surfaces at all, and it surfaces as a number
Narrative validation passed (no issues).

That is with a lore entry pointing at a quest which has never existed anywhere in the project. Now generate the report, and look at the last line:

AshForge Chronicles Narrative Report
Mod: Unnamed Mod  Generated: 2026-08-29T06:27:54Z
Quests: 2
  - First Contact (Easy) : 2 objs, 1 rewards
  - The Lost Cache (Medium) : 3 objs, 2 rewards
Dialogues: 1
  - Elder Greeting : 1 nodes, 2 choices
Lore: 1
  - The Ashfall [History] links Q:1 D:0
Stop

That count is measuring how many lines are in the box, not how many of them point at something real. Validate never resolves these references at all: for a lore entry it asks whether there is a title and whether there is a body, and those two questions are the whole rule.

The practical consequence is worth sitting with for a moment. Rename a quest and every lore entry that mentioned it goes stale immediately. The count stays where it was, validation stays green, and nothing in the tool will mention it.

02b

The same tool, two different answers

Cross-referenceChecked?Why
choice → NextNodeIdYes Nodes carry generated ids, so a choice can only mean one node.
lore → Related QuestsNo Free text accepting names or ids, one per line, with nothing to resolve against.
lore → Related DialoguesNo The same field type, for the same reason.
Unlock HintNo Prose, and never parsed by anything.
Fix
Paste the quest's exact title into Related Quests rather than typing it from memory, and get into the habit of treating a rename as a two-part job: change the quest, then search your lore for the old title. Nothing will remind you to do the second half. Clear the bogus entry now and run Validate again before carrying on.
11

The export seam

Three files, three fidelities

Read 5 header buttons ~10 min

Five buttons run along the header: Export Bundle, Test in Crucible, Export Narrative, Generate Report and Merge Bundle. Three of them write files, all into user://output, and every one of them reports only to the log. There is no dialog and no toast, so unless you read that line you will not know what was written or where it went.

PRESS WRITES WHAT'S IN IT Export Bundle Export Narrative Generate Report _definitions.json _narrative.json _narrative_runtime.json _report_<ts>.txt · .json · .html lossy — objectives flattened to strings; no prerequisites or status the entire project object, editor state and all the flattened, game-ready shape — this is the one to ship for you, not for the game (the .json omits the link counts) Test in Crucible → launches with --definitions <whichever file you exported last> nothing exported and no mod root set? it launches Crucible with --help

Figure 01 — the export seam One button writes two files, and the flag named --definitions will accept a file that is not a definition bundle without complaint.

The differences between these files are real rather than cosmetic. _narrative.json is the project serialised whole, which makes it the safest thing to archive and the wrong thing to ship. _narrative_runtime.json is assembled field by field for loading, so quests keep their structured objectives with type, target and seconds intact.

_definitions.json is the handoff contract shared across the suite, and it is the lossy one. Objectives collapse into plain strings — the objective's description where it has one, otherwise type:target — and prerequisites, status and notes are not part of the bundle shape at all. That is a deliberate contract boundary rather than a bug, but it does mean a round trip through the bundle is not a round trip through your work.

Careful
Reports are timestamped, which means they accumulate: every press leaves three more files in the output folder. The exports do the opposite and overwrite in place. If you want a snapshot of a day's work, copy _narrative.json somewhere dated yourself, because nothing in the tool is keeping one for you.
12

Test in Crucible

Whatever you touched last

Diagnose Crucible handoff ~6 min

Test in Crucible looks as though it knows what your project is. What it actually knows is which button you pressed most recently, and that difference matters more than it sounds.

Drill04

Watch the argument change
  1. Press Export Bundle, then Test in Crucible, and read the log line.
  2. Now press Export Narrative, then Test in Crucible again.
  3. Read the log a second time. The argument has changed.

Done whenYou can predict the argument before you press the button.

The rule04b

It decides in this order
  • The project's mod root, if one is set → --mod
  • Otherwise the last file any export button wrote--definitions
  • Otherwise → --help

NoticeThe third case fails quietly. Crucible opens on its help text and nothing explains why.

Both Export Bundle and Export Narrative write to that same “last exported” slot, so the flag stays constant while its argument moves underneath you. Export the narrative last and Crucible is handed the whole-project dump under a flag named for the bundle. The runtime file, written in the same click and the one actually shaped for loading, is never what gets passed.

Key
Setting a mod root removes the ambiguity entirely. With ModRoot populated the button always passes --mod and never consults the export slot. If you are testing repeatedly it is worth setting once so you can stop thinking about button order; if you would rather not, make a rule of pressing the export you mean immediately before Test.
13

Ending a session

A shipping pass

Ship 6 steps ~4 min

None of what follows is enforced by Chronicles. It is simply what working carefully with it looks like, once you know where its checks stop.

Every session

The end-of-work sequence

  1. Run Validate. it catches dangling dialogue links and empty required fields, which is necessary but not sufficient
  2. Press Generate Report and read the lore lines, comparing each links Q:n against the quests you know exist. this reconciliation is manual, and nothing in the tool can do it for you
  3. Press Export Narrative, which gives you the archive copy and the runtime copy together. Ship _narrative_runtime.json. one button writes two files, and only one of them is the game's
  4. Copy the archive somewhere dated. the next export will overwrite it in place
  5. Run Test in Crucible last, or set a mod root and stop worrying about the order. so the export slot holds what you think it holds
  6. Read the log after each of these. every one of these buttons succeeds and fails silently in the interface
05b

When it goes wrong

SymptomWhat it actually meansFix
Validation is green, but a lore link goes nowhere Validate never resolves cross-references. For a lore entry it checks only the title and the body. Reconcile each links Q:n against the real quests by hand, using the report.
The report still shows links Q:1 for a quest you renamed The count is the number of lines in the box, not the number of targets that exist. Treat a rename as a two-part job and search your lore for the old title.
Crucible opens on its help text There is no mod root set, and no export has been pressed this session. Set ModRoot, or export immediately before pressing Test.
The game ignores objectives you carefully structured You shipped _definitions.json, where objectives are flattened to strings. Ship _narrative_runtime.json instead.
Yesterday's export has gone Exports overwrite in place. Only reports are timestamped. Copy _narrative.json to a dated file at the end of each session.
Nothing appeared to happen when you pressed a button It most likely worked. Every export reports to the log and nowhere else. Read the log line, which names the full output path.

Course complete

What you now know

Check yourself

  • An objective is four fields, and only one of them is written for the player.
  • Type is a fixed vocabulary the game enforces; Description is free text it ignores entirely.
  • The dropdown offers four types while the model's comment documents six. The dropdown is the truth.
  • The two can disagree silently, and in the shipped demo data they already do.
  • Rewards are names looked up in the game's own list rather than descriptions.
  • New gives you a working skeleton with an objective already in place.
  • Chronicles auto-saves your typing — but the first edit of a session cannot be undone, and an undo never reaches the file until you make another edit or press Save.
  • Validate proves structural completeness and never sense.
  • A choice is Text | NextNodeId | Condition, and an empty NextNodeId ends the conversation.
  • The shipped demo offers two choices and ends on both, which makes it a menu rather than a branch.
  • The graph and the text box edit one model. Sync Graph <-> Model exists because they can drift.
  • Node ids are generated and shown in the form as Node 0 (id). Read them rather than inventing them.
  • Condition is carried into the export and evaluated by the game, never by Chronicles.
  • The dangling-link check is invisible by reading and lethal in play. Validate after every rewire, and always after a delete.
  • Lore's Unlock Hint is prose, and ships as prose. Only Related Quests and Related Dialogues are data, and both are free text that will accept a name or an id.
  • Validate checks a lore entry for a title and a body, and nothing else. Cross-references are never resolved.
  • links Q:1 counts the lines in a box rather than the connections that exist, which you confirmed by pointing a lore entry at a quest that was never created.
  • Three buttons write four files at three fidelities. _definitions.json is lossy by contract, and _narrative_runtime.json is the one to ship.
  • Reports accumulate and exports overwrite, so archiving is something you do deliberately.
  • Test in Crucible passes the last exported path, or the mod root if one is set, or --help if it has neither.
  • Every one of these buttons reports to the log and nowhere else.

That is Chronicles. ⛔ Worth repeating because it changes how you plan: no quest reaches the game as data. Use it to design and record a questline that an assembly will then implement.