6.9 KiB
name, description
| name | description |
|---|---|
| tttk-authoring | Author and edit TTRPG game design documents for the tttk (Tabletop Toolkit) CLI. Use when writing or modifying markdown content that uses tttk custom elements (:md-dice, :md-table, :md-deck, :md-print, :md-pins, etc.), custom fenced code blocks (role=spark-table / declare / file / tag), companion CSV data files, or when previewing content with `tttk serve` and validating it with `tttk check`. |
Authoring tttk game design documents
tttk (Tabletop Toolkit) renders a folder of markdown into an interactive TTRPG
web app. A game design document is ordinary GFM markdown plus exactly two
extensions:
- Custom elements written with
marked-directivesyntax::name[content]{attrs}. - Custom fenced code blocks whose info string carries a
role=attribute.
Everything else — headings, lists, tables, blockquotes, alerts, mermaid — is
standard markdown. Do not invent element names, props, or roles; check
reference.md when unsure. Deeper topics have their own files: yaml-tag.md
(deck config), csv.md (data files), layout.md (columns), and markdown.md
(alerts and mermaid).
Workflow
- Content lives in a directory (commonly
content/). Preview with hot reload:npx tttk serve ./content(default port 3000, override with-p 8080). - Validate after every edit:
npx tttk check ./content. It exits1when there are errors and printsfile:linediagnostics. Use--jsonfor machine-readable output and--quietfor errors only. This is the primary verification loop: write → check → fix. - The scanner picks up
.md,.csv,.yarn, and.svgfiles. - All paths in directives are relative to the current markdown file
(
./data.csv,../shared/npcs.csv,./images/map.png). - A typical game/adventure folder:
my-adventure/ ├── design.md # design notes (plain markdown) ├── adventure.md # the document players/GM read ├── locations.csv # data referenced by :md-table ├── cast.csv └── route.csv
Directive syntax
:name[content]{key="value" .class #id}
[content]is the directive body — a path, dice formula, color, etc.{key="value"}sets attributes.{.class}and{#id}are shorthands.- Container directives use
::: name…:::; nest deeper with::::,:::::.
Use the registered element names: :md-dice, not :dice. The full list is
in reference.md.
Code block roles
Fenced blocks are dispatched by the role= attribute in the info string. Both
backtick and tilde (~~~) fences work; the closing fence must reuse the opening
marker, and fence attribute keys may contain hyphens (e.g. data-foo=bar):
| Info string | Behavior |
|---|---|
```csv role=spark-table |
Body is CSV; replaced with :md-table[./csv_<hash>]. First column header must be a dice formula (d6, 2d6+1, …). |
```markdown role=spark-table |
Body is a GFM pipe table; converted to CSV, then same as above. |
```yaml role=declare |
YAML vars: / tags: maps defining reactive variables and tag modifiers. Block is stripped. |
```<lang> role=file |
Body stored as text content, block stripped, referenced by its derived id. |
```yaml role=tag |
Kept intact; rendered as a custom element from YAML (tag:, body:, …). |
```<lang> (no role) |
Rendered as a normal visible code block. |
| unknown role | Warned about and stripped. |
Rules that prevent broken output
- Quote any attribute value containing spaces or
":{pins="A:30,40 B:10,30"}. - In CSV, wrap fields containing
,,", or a newline in double quotes and escape"as"". Lines starting with#are comments. labelandbodyare the conventional CSV columns. Put titles insidebodyas markdown headings; use bold labels for sub-fields, not headings.- A
groupcolumn in a table CSV automatically produces group tabs — no attribute needed. - Reference each CSV once per document; don't repeat the same
:md-table. - For card decks, use the
yaml role=tagform withtag: md-deck(seeyaml-tag.md). The:md-deck[...]{...}directive is legacy and can't express template layers or card backs. - To print a rules document, use
:md-print[./rules.md](or theyaml role=tagform). It paginates into A4 landscape sheets holding two A5 pages, each withcolumnscolumns (default 2). Seereference.mdfor the attributes. - Keep CSV files clean — header row plus data. Put deck config and templates in
the YAML block's
data-config, not in CSV front matter (seecsv.md). {{prop}}in a CSVbodyinterpolates another column (or front-matter key) from the same row; with{remix}it pulls from a random row instead.
Validation
npx tttk check ./content validates against the same content registry the app
uses, so a clean check means the app resolves the content too. Errors exit 1:
| Code | Meaning |
|---|---|
TTTK-S002 |
container directive ::: never closed |
TTTK-D001 |
unknown :md-* element name |
TTTK-D002 |
malformed attribute block (e.g. an unquoted value with a space) |
TTTK-R001 |
unknown code-block role= (the block is silently dropped) |
TTTK-R003 |
role=declare failed to parse |
TTTK-R005 |
role=tag YAML is invalid |
TTTK-R006 |
role=tag missing or naming an unknown element |
TTTK-C001 |
content reference does not resolve |
TTTK-C004 |
:md-embed cycle |
TTTK-L001 |
link target file does not exist |
TTTK-V001 |
CSV failed to parse (e.g. an unclosed quote) |
Warnings are usually real too:
| Code | Meaning |
|---|---|
TTTK-R002 |
spark-table first header is not a dice formula |
TTTK-R004 |
role=declare block declares nothing |
TTTK-C002 |
reference resolves to an unexpected file type |
TTTK-L002 |
#section matches no heading |
TTTK-A001 |
icon missing under assets/ |
TTTK-A002 |
image missing |
TTTK-V002 |
CSV row column count differs from the header |
TTTK-V003 |
duplicate label values |
TTTK-V004 |
{{prop}} is not a CSV column or front-matter key |
TTTK-V005 |
spark-table roll value is not a number or range |
TTTK-C003 (info) flags the same CSV referenced twice by :md-table in one
document. Icon checks assume no assets/ directory exists above the checked
directory. The full code catalog lives in reference.md.
Reference
reference.md— generated catalog of every custom element, inline directive, code block role, and dice notation. Do not edit by hand; regenerate from the repo withnpm run gen:skill-reference.yaml-tag.md—role=tagblocks,data-configlayers, card backs, and the legacy:md-decklayer syntax.csv.md— CSV authoring: columns,{{prop}}interpolation, quoting, and the discouraged front-matter form.layout.md— column layout markers.markdown.md— GitHub alerts and mermaid diagrams.examples/adventure.mdandexamples/encounters.csv— a complete minimal document and its data file.