No description
Find a file
Dan 20c0b49a77 Review fix pass: data-loss criticals, codec hardening, leak cleanup
Full senior-review sweep (all findings fixed, 530 tests green):

- Prep board: sync cached body after own section writes (typed scenes
  could vanish from the UI and then be erased from disk)
- Dashboard: pip toggle is now a read-modify-write against the note's
  current Fronts section, re-located by name (stale cache silently
  deleted fronts added on Foundation)
- CampaignStore: notify on body-only changes to managed notes (root
  cause under both criticals); self-write marks now outlive done() so
  the cache echo still reads as a self-write (in-flight counted)
- sections.ts: fence-aware parsing (fenced ## lines no longer corrupt
  managed writes); body-split tolerates BOM and empty frontmatter
- Frontmatter codecs: unknown-key passthrough on write (newer-version
  fields survive older-plugin writes), id-bearing secret rows survive
  empty text (tombstone resurrection), ledger/session-zero patches read
  current state inside processFrontMatter instead of metadataCache
- Monster builder: attack-count round-trip no longer corrupts damage at
  CR 1/8, 9, 16, 17; CR fractions render as 1/8-1/2; preview title live
- Wizard double-fire guard; loadIfDeferred in openView; starter/demo
  builders refuse re-runs; safer filenames (#^[], reserved names)
- Per-render listener scopes (RenderScopes) for header/rail, prep, run
  scenes/secrets, tables; popout-safe timers; toast/undo handle cleanup
- Log-row rollback on failed writes; 0x table weights round-trip;
  duplicate doom lines preserved; obsidian dep pinned to 1.13.1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 10:58:35 -04:00
.claude Scaffold lazy-campaign plugin from new-obsidian-plugin skill 2026-07-11 15:21:29 -04:00
.github Add GitHub Sponsors funding link (manifest fundingUrl + FUNDING.yml) 2026-07-14 15:29:42 -04:00
assets Refresh README screenshots post-rename (Strong Start title, run redesign, World tab) [skip changelog] 2026-07-14 14:49:37 -04:00
scripts 0.5.0: first public release 2026-07-14 15:18:17 -04:00
src Review fix pass: data-loss criticals, codec hardening, leak cleanup 2026-07-20 10:58:35 -04:00
tests Review fix pass: data-loss criticals, codec hardening, leak cleanup 2026-07-20 10:58:35 -04:00
.gitignore M1: walking skeleton - host view, campaign store, sessions, dashboard 2026-07-11 15:59:10 -04:00
AGENTS.md Rename to Strong Start (id strong-start) 2026-07-14 14:29:50 -04:00
CHANGELOG.md Review fix pass: data-loss criticals, codec hardening, leak cleanup 2026-07-20 10:58:35 -04:00
esbuild.config.mjs Rename to Strong Start (id strong-start) 2026-07-14 14:29:50 -04:00
eslint.config.mjs Address store review: remove sentence-case eslint disables [skip changelog] 2026-07-14 16:39:10 -04:00
LICENSE Scaffold lazy-campaign plugin from new-obsidian-plugin skill 2026-07-11 15:21:29 -04:00
main.ts Review fix pass: data-loss criticals, codec hardening, leak cleanup 2026-07-20 10:58:35 -04:00
manifest.json 0.6.1: store review lint feedback (CSS and eslint-disable removal) 2026-07-14 16:41:07 -04:00
package-lock.json Review fix pass: data-loss criticals, codec hardening, leak cleanup 2026-07-20 10:58:35 -04:00
package.json Review fix pass: data-loss criticals, codec hardening, leak cleanup 2026-07-20 10:58:35 -04:00
README.md README: expand AI disclosure wording [skip changelog] 2026-07-14 14:49:51 -04:00
references.md Scaffold lazy-campaign plugin from new-obsidian-plugin skill 2026-07-11 15:21:29 -04:00
SCHEMA.md Review fix pass: data-loss criticals, codec hardening, leak cleanup 2026-07-20 10:58:35 -04:00
styles.css Address store review CSS lint: drop :has() and !important [skip changelog] 2026-07-14 16:32:00 -04:00
tsconfig.json Scaffold lazy-campaign plugin from new-obsidian-plugin skill 2026-07-11 15:21:29 -04:00
version-bump.mjs Scaffold lazy-campaign plugin from new-obsidian-plugin skill 2026-07-11 15:21:29 -04:00
versions.json 0.6.1: store review lint feedback (CSS and eslint-disable removal) 2026-07-14 16:41:07 -04:00
vitest.config.mjs Scaffold lazy-campaign plugin from new-obsidian-plugin skill 2026-07-11 15:21:29 -04:00

Strong Start

Create and run TTRPG campaigns in Obsidian with the eight steps of lazy RPG prep, secrets that carry forward between sessions, and rollable random tables.

Built on the method from Return of the Lazy Dungeon Master: this project contains a guided eight-step session prep board, a campaign dashboard, a distraction-free run mode for the table, built-in random tables and generators, user-authored custom tables, and an optional 5e improvisation module.

Everything the plugin creates is a plain markdown note in your vault — campaigns, sessions, NPCs, locations, quests, etc. The plugin's views are a lens over those notes.

AI Disclosure

This application was written with extensive use of Claude Code. I know some people in the TTRPG community will be turned away by this, and I totally understand. I am a lead AI engineer at work, and this project is the result of a mandate at work to learn these tools in depth, so learn them I have. At least I can provide a (hopefully) interesting project for a community I love.

The lazy RPG prep workflow

  1. Create a campaign — a guided wizard for the pitch, six truths, and a front or two, with inspiration rolls at every field.
  2. Prep a session — the eight-step worksheet: characters, strong start, scenes, secrets & clues, locations, NPCs, monsters, and rewards.
  3. Run it — A dedicated window with a session timer, scene list, face-down secrets that peek before they reveal, a dice roller, safety tools, and a log bar for taking notes during the session.
  4. End the session — tallies and a recap, then unrevealed secrets carry forward to the next session automatically.

Campaign dashboard

The eight-step prep board

Run mode

Features

  • Eight-step prep board — master/detail worksheet with per-step "inspire me" rolls for prepping quickly.
  • Secrets & clues that carry forward — unrevealed secrets flow into the next session; a ledger tracks what's in play, revealed, or retired across the whole campaign.
  • Run mode — read-optimized and players-glancing-safe. Secrets stay masked until you peek and reveal them.
  • Built-in tables & generators — strong starts, secrets, NPCs, treasure, traps, monuments, town events, dungeon monsters, and more from the Lazy GM's Resource Document, plus NPC/treasure/trap/monument/quest generators with per-line rerolls.
  • Custom tables — any note with a bullet list or die-range table becomes rollable; a custom table with a built-in's id replaces that built-in.
  • Session zero & safety tools — interactive checklist, lines & veils that surface in run mode's safety card.
  • Player-facing exports — copy a campaign recap that mechanically filters unrevealed secrets, a session-zero player guide, or a one-page session sheet.
  • Starter campaign — one command builds the document's own village of Whitesparrow and "The Night Blade" adventure as a ready-to-run campaign: eight NPCs, five locations, a quest, and session 1 fully prepped.
  • 5e module (toggleable) — encounter benchmark, improvised DCs/damage, monster difficulty dials, wilderness travel reference, stress-effect rules and tables.
  • Monster builder (5e module) — build a custom monster from the Lazy GM's per-CR statistics table (or seven general-use stat blocks), customize attacks, roles, and features with a live preview, and save it as a campaign note; boss/minion pairings and monsters-by-location reference tables included.
  • Lazy Solo 5e (toggleable) — the document's solo-play oracle tables and procedure.
  • Phone-ready — bottom tab bar, drill-down prep, and a run mode built for the phone at the table.
Run mode on a phone

Getting started

  1. Enable the plugin, then open it from the ribbon (castle icon) or the "Open view" command.
  2. Run the Create starter campaign command for a ready-to-run adventure (the CC-BY village of Whitesparrow — add your party and run session 1 tonight), or Create demo campaign to explore a mid-campaign example with carried secrets. Delete their folders when done.
  3. Create your own campaign from the dashboard and prep session 1.

Install

Not yet in the community plugin store. Until then:

  • BRAT: add this repository in BRAT as a beta plugin.
  • Manual: copy main.js, manifest.json, and styles.css from a release into <vault>/.obsidian/plugins/strong-start/, then enable it in Community plugins.

Data & privacy

  • Every entity is a markdown note under one lazyCampaign frontmatter key — see SCHEMA.md for the full, frozen contract.
  • Secrets are stored as plain YAML in session notes: the vault is the GM's screen. Share player-safe material with the recap/guide exports instead of sharing the vault.
  • The plugin makes no network calls, requires no account, and has no payment gate.
  • Works on desktop and mobile.

Attribution

This plugin includes content from the Lazy GM's Resource Document by Michael E. Shea of SlyFlourish.com, released under the Creative Commons Attribution 4.0 International License. Portions of that document are derived from the System Reference Document 5.1 by Wizards of the Coast LLC, also licensed under CC-BY 4.0.

This work includes material taken from the Lazy GM's 5e Monster Builder Resource Document written by Teos Abadía of Alphastream.org, Scott Fitzgerald Gray of Insaneangel.com, and Michael E. Shea of SlyFlourish.com, available under a Creative Commons Attribution 4.0 International License. (That document powers the 5e module's monster builder and its reference tables, and likewise includes material from the SRD 5.1, CC-BY 4.0.)

License

MIT — see LICENSE. Embedded content from the Lazy GM's Resource Document and the Lazy GM's 5e Monster Builder Resource Document remains CC-BY 4.0 as noted above.