Bookings[email protected] San Antonio · Texas
Obsidian guide · Game masters

Run your campaign from Obsidian.

Write each fact once, and every place, faction and session page lists it for you: a prep template, a secrets-and-clues tracker and NPC lists that fill themselves in. Any game system, no plugins.

Updated October 2026 · Tested in Obsidian 1.14 · No plugins

What you’ll build

Campaign notes usually go wrong the same way: the fact you need is in a note from three sessions ago, and you can’t remember which. Here each fact lives in one small note, and lists find it for you:

  • A session prep template that fits on one screen.
  • A secrets-and-clues tracker showing what the players haven’t found yet.
  • NPC notes that appear on their place’s page, and a list grouped by location.
  • Faction clocks you move between sessions.

Nothing here depends on rules or stats, so it works with any game system. You need Obsidian 1.9 or later with the Bases core plugin on. Everything below was tested in Obsidian 1.14 with no community plugins.

Step 1: A prep page you can fill in 30 minutes

Prep situations, not a script. This template keeps prep short and useful at the table:

Templates/Session.md
---
type: session
number:
session_on:
status: Planned
---
## Prep
**Last time:** two lines from the last recap.

**Strong start:** how this session opens, mid-action if you can.

**Possible scenes** (options, not a script):
-

**Secrets and clues to reveal** (link the notes):
-

**NPCs and places likely to come up:**
-

## Recap (after the game, 5 minutes)
- What happened:
- Clues found:
- Loose threads:
  • Strong start: open in the middle of something. It’s the one scene worth preparing carefully.
  • Possible scenes are options. If the players skip one, nothing is lost.
  • Secrets and clues are facts the players could learn, not tied to any one scene, so you can reveal them wherever the game goes.
  • The recap takes five minutes after the game and becomes the “last time” of the next prep.

Step 2: Secrets and clues, until they’re revealed

Give each secret or clue its own small note, linked to who or what it’s about:

Lore/Veyra funds the raids.md
---
type: lore
kind: Secret
revealed: false
about: "[[Lady Veyra]]"
---
Lady Veyra is paying the bandits to raid her own caravans.
- How the party could learn this (aim for three ways):

This Base lists every secret and clue the players haven’t found yet:

Lore.base
filters:
  and:
    - type == "lore"
    - '!file.inFolder("Templates")'
properties:
  file.name:
    displayName: Entry
views:
  - type: table
    name: Unrevealed
    filters:
      and:
        - '!revealed'
        - kind == "Secret" || kind == "Clue"
    order:
      - file.name
      - kind
      - about
  - type: table
    name: About this
    filters:
      and:
        - file.hasLink(this.file)
    order:
      - file.name
      - kind
      - revealed

When one comes out at the table, tick revealed and it drops off the list. Aim for three ways the party could learn each important secret, because players often miss one. About this works like the NPC trick in step 3: on a character’s page, it lists every secret about them.

Step 3: NPCs that show up where they live

One note per NPC, with links to their place and faction:

NPCs/Marta Hale.md
---
type: npc
role: Innkeeper
location: "[[Millbrook]]"
faction: "[[The Lantern Guild]]"
attitude: Friendly
status: Alive
---
**Wants:** to keep the inn out of the guild's feud.
NPCs.base
filters:
  and:
    - type == "npc"
    - '!file.inFolder("Templates")'
formulas:
  mood: if(attitude == "Friendly", "🟢 Friendly", if(attitude == "Hostile", "🔴 Hostile", if(attitude == "Neutral", "⚪ Neutral", "❔ Unknown")))
properties:
  file.name:
    displayName: NPC
  formula.mood:
    displayName: Attitude
views:
  - type: table
    name: By place
    groupBy:
      property: location
      direction: ASC
    order:
      - file.name
      - role
      - formula.mood
      - status
  - type: table
    name: Here
    filters:
      and:
        - file.hasLink(this.file)
    order:
      - file.name
      - role
      - formula.mood
      - status

By place groups every NPC under their location. Here is the clever one: embed it in a place note, and file.hasLink(this.file) keeps only the NPCs whose properties link to that note.

Places/Millbrook.md
---
type: place
kind: Town
---
**First impression:** smoke from the mill, and a bell that rings at odd hours.

## Who's here
![[NPCs.base#Here]]

## Secrets and lore
![[Lore.base#About this]]

Millbrook’s page now lists Marta and everyone else who lives there, and it updates itself when you add someone. Faction pages can list their members the same way, and if each NPC has a first_seen link to a session, session pages list who the party met.

Step 4: Faction clocks

A clock is a goal in six steps. Give each faction note a goal and a clock number from 0 to 6. Between sessions, ask what each faction did and move its clock. When a clock fills, the goal happens.

Factions.base
filters:
  and:
    - type == "faction"
    - '!file.inFolder("Templates")'
formulas:
  progress: if(clock, clock.toString() + " of 6", "0 of 6")
properties:
  file.name:
    displayName: Faction
  formula.progress:
    displayName: Clock
views:
  - type: table
    name: Clocks
    order:
      - file.name
      - goal
      - formula.progress
    sort:
      - property: clock
        direction: DESC

The progress formula shows “4 of 6”, and the fullest clocks come first: those are the factions about to change your world.

Step 5: A Home page for game night

Make a note called Home:

Home.md
## Secrets and clues not yet revealed
![[Lore.base#Unrevealed]]

## Faction clocks
![[Factions.base#Clocks]]

## Who's where
![[NPCs.base#By place]]

Open it while you prep, and keep it in a pinned tab at the table. What you need to improvise sits on one screen.

After the game: five minutes

  1. Fill in the recap while it’s fresh.
  2. Tick revealed on every secret or clue that came out.
  3. Make notes for any NPC you invented on the spot.
  4. Ask what each faction did, and move its clock.

That’s a good part of the next session’s prep already done.

Mistakes that cost us time

  • Prepping a script. The players will go somewhere else. Prep secrets, places and people instead.
  • Templates showing up as NPCs. The !file.inFolder("Templates") filter fixes it.
  • A place page that stays empty. The NPC’s location link must match the place note’s name; pick it from the [[ suggestions.
  • One giant note per session. Small notes per NPC, place and secret are what make the lists work.
  • Spoilers on a shared screen. If players can see your screen, keep the Lore list closed at the table.
More guides

Keep going.