diff --git a/.gitignore b/.gitignore
index 2bc55c2..e4f0703 100644
--- a/.gitignore
+++ b/.gitignore
@@ -133,3 +133,5 @@ dist
LGMRD_new.pdf
pandoc*
+
+.obsidian
diff --git a/README.md b/README.md
index 733d08d..5d7a83d 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ LGMRD is officially pronounced "Lymm Grid" and LGMMBRD "Lymm Bard".
- [HTML](https://github.com/crit-tech/LGMRD/blob/main/LGMRD.html) **Updated: Thu, 08 Feb 2024 02:14:22 GMT**
- [All-in-one Markdown](https://github.com/crit-tech/LGMRD/blob/main/LGMRD.md) **Updated: Sun, 10 Mar 2024 23:21:26 GMT**
- [Separate Markdown](https://github.com/crit-tech/LGMRD/tree/main/markdown_separate) files **Updated: Sun, 10 Mar 2024 23:21:26 GMT**
-- [Markdown for Obsidian](https://github.com/crit-tech/LGMRD/tree/main/markdown_obsidian) **Updated: Sun, 10 Mar 2024 23:31:19 GMT**
+- [Markdown for Obsidian](https://github.com/crit-tech/LGMRD/tree/main/markdown_obsidian) **Updated: Mon, 11 Mar 2024 03:36:54 GMT**
- [JSON](https://github.com/crit-tech/LGMRD/blob/main/LGMRD.json) **Updated: Thu, 08 Feb 2024 02:14:27 GMT**
- [NPM](https://www.npmjs.com/package/@crit-tech/lgmrd) **Updated: Thu, 08 Feb 2024 02:14:27 GMT**
- [PDF](https://github.com/crit-tech/LGMRD/blob/main/LGMRD.pdf) **Updated: Thu, 08 Feb 2024 02:14:24 GMT**
diff --git a/markdown_obsidian/5e Quick Encounter Building.md b/markdown_obsidian/5e Quick Encounter Building.md
index c2d6e0b..44477a4 100644
--- a/markdown_obsidian/5e Quick Encounter Building.md
+++ b/markdown_obsidian/5e Quick Encounter Building.md
@@ -1,5 +1,3 @@
-# 5e Quick Encounter Building
-
When building encounters, start by choosing the type and number of monsters that make sense for the situation. Then use the following guidelines to compare the challenge rating of the monsters, the level of the characters, and the ratio of monsters to characters. If the quantity of monsters or their challenge rating is beyond the indicated guidelines, the encounter might be deadly. Be especially careful with potentially deadly encounters when the characters are 1st level.
## For Characters of 1st Level
diff --git a/markdown_obsidian/Building an RPG Group.md b/markdown_obsidian/Building an RPG Group.md
index 48defcb..3a2cc77 100644
--- a/markdown_obsidian/Building an RPG Group.md
+++ b/markdown_obsidian/Building an RPG Group.md
@@ -1,5 +1,3 @@
-# Building an RPG Group
-
## Finding and Maintaining a Solid Group
Finding and maintaining a solid group for roleplaying gaming remains the most difficult task for many GMs. This section offers suggestions for finding players that fit well with your group, and for keeping that group going for years to come.
diff --git a/markdown_obsidian/Connecting Characters.md b/markdown_obsidian/Connecting Characters.md
index d43078a..1033690 100644
--- a/markdown_obsidian/Connecting Characters.md
+++ b/markdown_obsidian/Connecting Characters.md
@@ -1,5 +1,3 @@
-# Connecting Characters
-
During your session zero of a new campaign, or if you're running a single-session one-shot game, consider establishing connections between the characters to help build a cohesive bond between them before the game begins. This can help prevent ham-fisted and convoluted attempts to build a story that connects the characters, when all the players already know perfectly well that they're coming together simply for the adventure.
This section presents two potential approaches to connecting characters. First, all the characters can be previously connected through a single organization, faction, or patron, using ideas from the Group Connections table. Alternatively, each character can establish a connection to one or more other characters through a personal relationship and history, using ideas from the Character Connections table. Players can work together to come up with these shared histories based on the overall themes of the campaign, or the group can randomly select potential relationships and tweak the results as desired.
@@ -10,6 +8,8 @@ For single-session games, consider establishing a single group relationship for
## Group Connections
+`dice: [[Connecting Characters#^group-connections]]`
+
1. Mercenary company
2. Self-employed investigators
3. Official investigators
@@ -31,8 +31,12 @@ For single-session games, consider establishing a single group relationship for
19. Protectors of the common folk
20. Seekers of vengeance
+^group-connections
+
## Character Connections
+`dice: [[Connecting Characters#^character-connections]]`
+
1. Sibling of
2. Saved by
3. Served with
@@ -53,3 +57,5 @@ For single-session games, consider establishing a single group relationship for
18. Trained by
19. Dueling partner of
20. On the run with
+
+^character-connections
diff --git a/markdown_obsidian/Core Adventure Generators.md b/markdown_obsidian/Core Adventure Generators.md
index b8b8532..bf6f56c 100644
--- a/markdown_obsidian/Core Adventure Generators.md
+++ b/markdown_obsidian/Core Adventure Generators.md
@@ -1,5 +1,3 @@
-# Core Adventure Generators
-
The tables in this section can help you generate a core fantasy adventure based on the traditional concept of getting hired by a patron or other NPC to take on a quest in a specific location. Often these adventures take place in small settlements surrounded by ancient ruins and monstrous lairs on the edge of civilization.
Use these tables together to generate and inspire full adventures, or use individual tables to fill in the details of other adventures you create or play. This generator (and specifically, the Dungeon Monsters table and the Treasure table) is set up for characters of 1st to 4th level, but can be easily modified for higher-level adventures.
@@ -8,6 +6,9 @@ Use these tables together to generate and inspire full adventures, or use indivi
Use these tables to generate a patron or NPC for your adventure, applying an NPC stat block to create villains, hirelings, rivals, or heralds.
+**Behavior: **`dice: [[Core Adventure Generators#^patrons-and-npcs]]|Behavior`
+**Ancestry: **`dice: [[Core Adventure Generators#^patrons-and-npcs]]|Ancestry`
+
| d20 | Behavior | Ancestry |
| --- | ------------- | ----------------- |
| 1 | Enthusiastic | Human |
@@ -31,12 +32,16 @@ Use these tables to generate a patron or NPC for your adventure, applying an NPC
| 19 | Opportunistic | Lycanthrope |
| 20 | Soft spoken | Artifact |
+^patrons-and-npcs
+
## Quests
Any quests the characters are asked to fulfill might be distilled down to one of the following starting points.
## 1d20 Quests
+`dice: [[Core Adventure Generators#^1d20-quests]]`
+
1. Find an item
2. Kill a villain
3. Rescue an NPC
@@ -58,10 +63,16 @@ Any quests the characters are asked to fulfill might be distilled down to one of
19. Discover a monument
20. Dig up an artifact
+^1d20-quests
+
## Locations, Monuments, and Items
The location of the quest might also contain specific monuments or items tied to the adventure's goals.
+**Location: **`dice: [[Core Adventure Generators#^locations-monuments-and-items]]|Location`
+**Monument: **`dice: [[Core Adventure Generators#^locations-monuments-and-items]]|Monument`
+**Item: **`dice: [[Core Adventure Generators#^locations-monuments-and-items]]|Item`
+
| d20 | Location | Monument | Item |
| --- | ------------ | ------------- | -------- |
| 1 | Tower | Sarcophagus | Coin |
@@ -85,10 +96,16 @@ The location of the quest might also contain specific monuments or items tied to
| 19 | Cove | Cage | Mask |
| 20 | Castle | Brazier | Necklace |
+^locations-monuments-and-items
+
## Condition, Description, and Origin
Locations, monuments, or items can be flavored by determining their condition, description, and origin.
+**Condition: **`dice: [[Core Adventure Generators#^condition-description-and-origin]]|Condition`
+**Description: **`dice: [[Core Adventure Generators#^condition-description-and-origin]]|Description`
+**Origin: **`dice: [[Core Adventure Generators#^condition-description-and-origin]]|Origin`
+
| d20 | Condition | Description | Origin |
| --- | ----------- | ----------- | ---------- |
| 1 | Smoky | Ruined | Human |
@@ -112,12 +129,16 @@ Locations, monuments, or items can be flavored by determining their condition, d
| 19 | Crystalline | Overgrown | Ethereal |
| 20 | Silvered | Shattered | Abyssal |
+^condition-description-and-origin
+
## Chambers
Use this list when you need to define the purpose of a chamber in a dungeon, keep, or similar site. Reflavor any chamber to suit the theme of the adventure.
## 1d20 Chambers
+`dice: [[Core Adventure Generators#^1d20-chambers]]`
+
1. Armory
2. Prison
3. Throne room
@@ -139,12 +160,16 @@ Use this list when you need to define the purpose of a chamber in a dungeon, kee
19. Bone yard
20. Scrying chamber
+^1d20-chambers
+
## Dungeon Discoveries
Add useful discoveries such as the following to your adventure, to create upward beats in the characters' story.
## 1d20 Discoveries
+`dice: [[Core Adventure Generators#^1d20-discoveries]]`
+
1. Helpful NPC
2. Holy fountain
3. Inspiring statue
@@ -166,6 +191,8 @@ Add useful discoveries such as the following to your adventure, to create upward
19. Useful machinery
20. Historical library
+^1d20-discoveries
+
## Dungeon Monsters
You can add monsters and other foes to your adventure by consulting the following list. Roll a d8 for easy monsters, roll a d12 to expand the range into hard monsters, or roll a d20 to also include dangerous monsters. If you decide to use a monster as a boss monster, give it double hit points and let it take an extra action each turn.
@@ -174,6 +201,8 @@ For foes such as bandits and cultists, you can also roll for ancestry on the NPC
## 1d20 Monsters
+`dice: [[Core Adventure Generators#^1d20-monsters]]`
+
1. Giant rats
2. Bandits
3. Cultists
@@ -195,12 +224,16 @@ For foes such as bandits and cultists, you can also roll for ancestry on the NPC
19. Hell hounds
20. Mummies
+^1d20-monsters
+
## Traps and Hazards
Add traps as they make sense for the adventure. At 1st through 4th level, traps often have a DC of 13, and deal 7 (2d6) damage for easy traps or 11 (2d10) damage for hard traps.
## 1d20 Traps and Hazards
+`dice: [[Core Adventure Generators#^1d20-traps-and-hazards]]`
+
1. Spiked pit
2. Lightning blasts
3. Poisoned darts
@@ -222,12 +255,16 @@ Add traps as they make sense for the adventure. At 1st through 4th level, traps
19. Thick webs
20. Freezing jets
+^1d20-traps-and-hazards
+
## Treasure
This list lets you add treasure to the adventure as appropriate. Roll a d10 to determine monetary treasure, or a d20 for monetary and magical treasure.
## 1d20 Treasures
+`dice: [[Core Adventure Generators#^1d20-treasures]]`
+
1. Coins
2. Bag of gemstones
3. Platinum jewelry
@@ -249,12 +286,16 @@ This list lets you add treasure to the adventure as appropriate. Roll a d10 to d
19. Magic ranged weapon
20. Magic armor
+^1d20-treasures
+
## Spells
Some commonly discovered relics might grant a single- use spell, while less common magic items might allow their wielder to cast a spell daily. Use the list of common spells below or choose specialized spells to create unique magic item rewards.
## 1d20 Spells
+`dice: [[Core Adventure Generators#^1d20-spells]]`
+
1. *Magic missile*
2. *Burning hands*
3. *Shield*
@@ -275,3 +316,5 @@ Some commonly discovered relics might grant a single- use spell, while less comm
18. *Dispel magic*
19. *Haste*
20. *Fly*
+
+^1d20-spells
diff --git a/markdown_obsidian/Creating Secrets and Clues.md b/markdown_obsidian/Creating Secrets and Clues.md
index cc0bd37..a8531ed 100644
--- a/markdown_obsidian/Creating Secrets and Clues.md
+++ b/markdown_obsidian/Creating Secrets and Clues.md
@@ -1,5 +1,3 @@
-# Creating Secrets and Clues
-
Secrets and clues are short pieces of information the characters might discover during an adventure. Secrets and clues are initially written without regard to the method by which they might be discovered. Instead, we improvise their discovery as the characters engage with the adventure's locations and NPCs.
The following prompts don't create specific secrets and clues. Rather, the questions they ask are meant to inspire the creation of your own secrets for your campaign. Keep in mind that secrets are meant to serve you. Don't overthink them or worry about making them perfect. There's no wrong way to use secrets and clues as long as they help you run your game.
@@ -8,6 +6,8 @@ The following prompts don't create specific secrets and clues. Rather, the quest
Use character secrets to tie the characters to the world around them. These sorts of secrets might be revealed by NPCs, old journals or letters, suddenly recalled memories, or prophetic dreams.
+`dice: [[Creating Secrets and Clues#^character-secrets]]`
+
1. What family history might be revealed?
2. What ties the character to this location?
3. What ghost or spirit haunts the character?
@@ -19,12 +19,16 @@ Use character secrets to tie the characters to the world around them. These sort
9. What ritual was the character blessed with as a child?
10. What previous event ties the character to the story?
+^character-secrets
+
## Historical Secrets
Use historical secrets to give the characters meaningful and useful information as they explore the setting of the campaign. Secrets of this kind should provide characters and players alike with bite-sized pieces of local or world history.
Historical secrets might be found as mosaics in ancient tombs, statues in old ruins, dusty tomes in ancient libraries, markings on strange weapons, or tales shared among elderly villagers.
+`dice: [[Creating Secrets and Clues#^historical-secrets]]`
+
1. What dead god has a connection to the area?
2. What armies once battled here?
3. What cruel lord was slain in this place?
@@ -36,12 +40,16 @@ Historical secrets might be found as mosaics in ancient tombs, statues in old ru
9. What was this location's former purpose?
10. What horrific monster once ruled here?
+^historical-secrets
+
## NPC and Villain Secrets
Use NPC and villain secrets to reveal information about these NPCs to the characters, especially as a means of introducing villains before they face the characters.
Characters might learn NPC or villain secrets from a villain's herald or sidekick, rumors at a local pub, recovered journals, a minion's last words, captured letters, or town gossip.
+`dice: [[Creating Secrets and Clues#^npc-and-villain-secrets]]`
+
1. What dark history follows the NPC?
2. What makes the NPC think they're right?
3. What was the NPC's great accomplishment?
@@ -53,12 +61,16 @@ Characters might learn NPC or villain secrets from a villain's herald or sidekic
9. Who does the NPC love above all others?
10. What secret does the NPC want to keep hidden?
+^npc-and-villain-secrets
+
## Plot and Story Secrets
Use plot and story secrets to teach characters about the larger events going on in the world, and to move the characters forward in the story of your campaign.
Characters might learn these secrets from quest-giving NPCs, notes found on defeated foes, dreams or portents from the gods, NPCs fleeing a disaster, arcane feedback from an object, or psychic projections.
+`dice: [[Creating Secrets and Clues#^plot-and-story-secrets]]`
+
1. What villainous event will soon come to pass?
2. What disaster is about to befall the land?
3. What royal figure was just assassinated?
@@ -69,3 +81,5 @@ Characters might learn these secrets from quest-giving NPCs, notes found on defe
8. What natural disaster has recently struck the area?
9. What unnatural being has appeared in the world?
10. What unusual creature was seen walking the wilds?
+
+^plot-and-story-secrets
diff --git a/markdown_obsidian/Example Strong Starts.md b/markdown_obsidian/Example Strong Starts.md
index 08654ae..f8a8877 100644
--- a/markdown_obsidian/Example Strong Starts.md
+++ b/markdown_obsidian/Example Strong Starts.md
@@ -1,11 +1,11 @@
-# Example Strong Starts
-
A strong start kicks your game off in the middle of the action. It helps the players to let go of the real world and fall into the story unfolding at the table. Depending on where your adventure takes place, you can use any of the following strong starts in your own game, whether running a single-session adventure or a longer campaign.
## Cities and Towns
In a settlement, a strong start can make use of either combat or roleplaying.
+`dice: [[Example Strong Starts#^cities-and-towns]]`
+
1. The characters interrupt bandits breaking into a shop.
2. Something slithers out of a nearby sewer.
3. A noble lord bumps into one of the characters and threatens to have them arrested.
@@ -17,10 +17,14 @@ In a settlement, a strong start can make use of either combat or roleplaying.
9. A golem from a wizards' academy goes on a rampage.
10. The local monarch is assassinated and a villain takes over the government.
+^cities-and-towns
+
## Sewers
A session that starts in a sewer can make use of numerous monsters and hazards.
+`dice: [[Example Strong Starts#^sewers]]`
+
1. A flood of poisonous water flows past the characters' position.
2. The sewer collapses into deeper tunnels sealed up for centuries.
3. A wererat approaches the characters, offering to sell valuable information.
@@ -32,10 +36,14 @@ A session that starts in a sewer can make use of numerous monsters and hazards.
9. A wall collapses, revealing a hidden temple of the god of slimes and oozes.
10. A flood of water draws the characters into a dangerously large mechanical sluice system.
+^sewers
+
## Wilderness
Wilderness locations can involve either action or mystery in a strong start.
+`dice: [[Example Strong Starts#^wilderness]]`
+
1. A nearby tree opens up, and a satyr steps through and says "Hi!"
2. A rampaging werebear storms through the area, mistaking the characters for the hunters who killed their mate.
3. Night falls, revealing an alien starscape above.
@@ -47,10 +55,14 @@ Wilderness locations can involve either action or mystery in a strong start.
9. A skeleton hanging from a tree begs the characters to right the wrong it committed while alive.
10. A sinkhole opens up, revealing the tunnels of long-forgotten burial chambers.
+^wilderness
+
## Dungeons, Caves, and Caverns
Subterranean adventures lend themselves to the widest possible range of strong starts.
+`dice: [[Example Strong Starts#^dungeons-caves-and-caverns]]`
+
1. A vampire appears from a sudden rise of mist, introduces herself, and asks the characters for a favor.
2. An ancient statue turns its head toward the characters and whispers a valuable secret.
3. The floor collapses, revealing even deeper tunnels long forgotten.
@@ -61,3 +73,5 @@ Subterranean adventures lend themselves to the widest possible range of strong s
8. The ground cracks open and a pillar of chipped obsidian juts out, projecting a prophecy in red Infernal glyphs on the walls of the chamber.
9. Stars swim in a moonlit well, then rise up to reveal themselves as will-o'-wisps.
10. A spectral hound guides the characters to the camp of a reclusive mage.
+
+^dungeons-caves-and-caverns
diff --git a/markdown_obsidian/Lazy Combat Encounter Building for 5e.md b/markdown_obsidian/Lazy Combat Encounter Building for 5e.md
index af6a933..29dc0f3 100644
--- a/markdown_obsidian/Lazy Combat Encounter Building for 5e.md
+++ b/markdown_obsidian/Lazy Combat Encounter Building for 5e.md
@@ -1,5 +1,3 @@
-# Lazy Combat Encounter Building for 5e
-
This section helps you build and improvise dynamic combat encounters based on the fiction of the game.
## Start with the Story
diff --git a/markdown_obsidian/Lazy Solo 5e.md b/markdown_obsidian/Lazy Solo 5e.md
index 79620b3..b813336 100644
--- a/markdown_obsidian/Lazy Solo 5e.md
+++ b/markdown_obsidian/Lazy Solo 5e.md
@@ -1,5 +1,3 @@
-# Lazy Solo 5e
-
These rules let you play a solo game of 5e using lists in this document. With these guidelines, a single character explores a dungeon to complete quests. Let your imagination take over as you fill in the story and details of the quest, location, and adventure.
This scenario begins at 1st level, and your character gains a level after each successful quest.
@@ -24,6 +22,8 @@ Each time your roll comes up 4, 5, 6, or 7, indicated by "QP" below, your quest
On your fourth roll of quest progress, you reach the final challenge of the quest. If you succeed, you have completed the quest and gain a new level.
+`dice: [[Lazy Solo 5e#^exploring-the-dungeon]]`
+
1. Trap or hazard
2. Trap or hazard
3. Monster and harmful monument
@@ -35,6 +35,8 @@ On your fourth roll of quest progress, you reach the final challenge of the ques
9. Healing font (restore 2d6 hit points).
10. Unguarded treasure
+^exploring-the-dungeon
+
## Traps and Hazards
Roll for the trap type on the Traps and Hazards table in the "[Core Adventure Generators]()" section. Then make a DC 12 Wisdom (Perception) check to locate the trap or hazard. Roll the most applicable ability check or saving throw vs DC 12 to avoid the trap or hazard. Failure on either roll results in 1d6 damage per character level of a type appropriate for the trap.
@@ -51,6 +53,8 @@ Each monster encounter includes a helpful, neutral, or harmful monument. Generat
Roll a d6 to determine the effect of the monument.
+`dice: [[Lazy Solo 5e#^monuments]]`
+
1. +1 to AC
2. +1 to attacks and save DCs
3. +1 AC and saving throws
@@ -58,6 +62,8 @@ Roll a d6 to determine the effect of the monument.
5. +1d6 damage per five character levels
6. Advantage on attack rolls
+^monuments
+
Helpful monuments provide this benefit to your character. Harmful monuments provide this benefit to monsters. For neutral monuments, your character can roll a DC 12 Intelligence (Arcana or Religion) check. On a success, your character gains the benefit. On a failure, the monster gains the benefit.
## Treasure
@@ -66,6 +72,8 @@ When you defeat a monster or enter a chamber with unguarded treasure, roll on th
## 1d8 Treasures
+`dice: [[Lazy Solo 5e#^1d8-treasures]]`
+
1. No treasure
2. No treasure
3. 3d12 gp
@@ -75,4 +83,6 @@ When you defeat a monster or enter a chamber with unguarded treasure, roll on th
7. Consumable item
8. Permanent item
+^1d8-treasures
+
For consumable and permanent items, roll on the tables in the "[Treasure Generator]()" section or a random treasure table of your choice. You can replace any consumable magic item with a *potion of healing*. You can replace any permanent magic item with a *+1 weapon* of your choice.
diff --git a/markdown_obsidian/Monster Difficulty Dials.md b/markdown_obsidian/Monster Difficulty Dials.md
index 1bfea57..35eb507 100644
--- a/markdown_obsidian/Monster Difficulty Dials.md
+++ b/markdown_obsidian/Monster Difficulty Dials.md
@@ -1,5 +1,3 @@
-# Monster Difficulty Dials
-
Balancing combat encounters is notoriously difficult. Different groups of characters can bring very different capabilities to each battle, even at the same level. However, because monsters as they are typically presented are the average of their type, you can adjust the averages to subtly or dramatically change the difficulty of a given monster or group of monsters. By turning these "difficulty dials" for monsters, you can easily shift the tone of combat even in the middle of a battle.
## "Hit Point" Dial
diff --git a/markdown_obsidian/Monster Templates.md b/markdown_obsidian/Monster Templates.md
index f97c87b..f2794ab 100644
--- a/markdown_obsidian/Monster Templates.md
+++ b/markdown_obsidian/Monster Templates.md
@@ -1,5 +1,3 @@
-# Monster Templates
-
The following monster templates can help you customize existing monsters into new unique variants that can fit a variety of locations and circumstances. With just a few templates in hand, your core monster books can become much more useful.
## Challenge Rating Increase?
@@ -10,6 +8,10 @@ The challenge ratings described in these templates are loose guides, so use your
Apply this template to any monster to make an elemental version of that monster. Choose from or roll on the following table to determine the type of elemental template you want to apply:
+**Elemental Template: **`dice: [[Monster Templates#^elemental-monsters]]|Elemental Template`
+**d8: **`dice: [[Monster Templates#^elemental-monsters]]|d8`
+**Elemental Template: **`dice: [[Monster Templates#^elemental-monsters]]|Elemental Template`
+
| d8 | Elemental Template | d8 | Elemental Template |
| -- | ------------------ | -- | ------------------ |
| 1 | Fire | 5 | Poison |
@@ -17,6 +19,8 @@ Apply this template to any monster to make an elemental version of that monster.
| 3 | Lighting | 7 | Radiant |
| 4 | Acid | 8 | Thunder |
+^elemental-monsters
+
Then choose one or more of the following traits to customize your monster, making use of the damage type determined by the elemental template:
* **Elemental Resistance.** The templated creature has resistance against its damage type.
@@ -65,6 +69,10 @@ Some monsters can innately cast magical spells. Spell-infused monsters typically
Spell-infused creatures do not require components to cast their spells. They typically use each of their spells once, recovering the ability to do so when they finish a long rest. Roll for or choose from the table to determine which spells a creature can use. Spells that deal high damage can affect a creature's challenge rating.
+**Spell: **`dice: [[Monster Templates#^spell-infused-monsters]]|Spell`
+**d20: **`dice: [[Monster Templates#^spell-infused-monsters]]|d20`
+**Spell: **`dice: [[Monster Templates#^spell-infused-monsters]]|Spell`
+
| d20 | Spell | d20 | Spell |
| --- | -------------- | --- | ---------------- |
| 1 | Burning hands | 11 | Invisibility |
@@ -77,3 +85,5 @@ Spell-infused creatures do not require components to cast their spells. They typ
| 8 | Thunderwave | 18 | Gaseous form |
| 9 | Blur | 19 | Lightning bolt |
| 10 | Darkness | 20 | Fireball |
+
+^spell-infused-monsters
diff --git a/markdown_obsidian/NPC Generator.md b/markdown_obsidian/NPC Generator.md
index 561cdf7..c738a2b 100644
--- a/markdown_obsidian/NPC Generator.md
+++ b/markdown_obsidian/NPC Generator.md
@@ -1,5 +1,3 @@
-# NPC Generator
-
NPCs bring our game worlds to life. You can use the generator in this section to quickly build NPCs to drop into your game, rolling on the tables below to generate baseline characteristics. To really bring the NPC to life, you can then model their personality and roleplaying off characters from your favorite books, TV shows, or movies, switching up gender and other traits to make them feel fresh.
## Names
@@ -14,6 +12,8 @@ Use the following table to choose a random ancestry for your NPC.
## 1d10 Ancestries
+`dice: [[NPC Generator#^1d10-ancestries]]`
+
1. Human
2. Elf
3. Dwarf
@@ -25,12 +25,16 @@ Use the following table to choose a random ancestry for your NPC.
9. Dragonborn
10. Tiefling
+^1d10-ancestries
+
## Worldview
An NPC's worldview can help determine how they initially react to the characters, adjusted by how the characters approach them. Improvise DCs for social interaction ability checks based on that approach, with checks usually ranging between DC 10 (easy) and DC 20 (very hard). A default of DC 12 is usually a good choice.
## 1d20 Worldviews
+`dice: [[NPC Generator#^1d20-worldviews]]`
+
1. Surly
2. Friendly
3. Brash
@@ -52,12 +56,16 @@ An NPC's worldview can help determine how they initially react to the characters
19. Greedy
20. Outgoing
+^1d20-worldviews
+
## Appearance and Mannerisms
NPCs will often be most easily remembered by the players based on some unique aspect of their appearance or manners.
## 1d20 Appearances and Mannerisms
+`dice: [[NPC Generator#^1d20-appearances-and-mannerisms]]`
+
1. Wild hair
2. Scarred cheek
3. Body tattoos
@@ -79,12 +87,16 @@ NPCs will often be most easily remembered by the players based on some unique as
19. Missing fingers
20. Half-shaved head
+^1d20-appearances-and-mannerisms
+
## Profession
Assign a profession to your NPC to add color to their stat block. The commoner is the default stat block for NPCs of this type.
## 1d20 Professions
+`dice: [[NPC Generator#^1d20-professions]]`
+
1. Farmer
2. Blacksmith
3. Clerk
@@ -105,3 +117,5 @@ Assign a profession to your NPC to add color to their stat block. The commoner i
18. Veteran
19. Knight
20. Mage
+
+^1d20-professions
diff --git a/markdown_obsidian/Quest Templates.md b/markdown_obsidian/Quest Templates.md
index 35c5ed8..4a86d5b 100644
--- a/markdown_obsidian/Quest Templates.md
+++ b/markdown_obsidian/Quest Templates.md
@@ -1,5 +1,3 @@
-# Quest Templates
-
Quest templates are general-purpose designs around which you can build specific quests for your own game, using adventure archetypes that have been standard for more than forty years in RPGs. This section offers ten quest templates you can customize for your own adventures. If generating a random adventure, just roll a d10 to determine which quest template to use, then fill in the details of the quest with your own ideas or by making use of the adventure generators found later in this document.
## 1. Kill the Boss
diff --git a/markdown_obsidian/Quick Tricks for Lazier 5e Games.md b/markdown_obsidian/Quick Tricks for Lazier 5e Games.md
index d40c8f2..22dce65 100644
--- a/markdown_obsidian/Quick Tricks for Lazier 5e Games.md
+++ b/markdown_obsidian/Quick Tricks for Lazier 5e Games.md
@@ -1,5 +1,3 @@
-# Quick Tricks for Lazier 5e Games
-
## Start with Inspiration
Award inspiration to each character at the beginning of a session. This takes some of the weight off of needing to remember to reward inspiration during the game. You can still award it again during the game if players have used it.
diff --git a/markdown_obsidian/Random Dungeon Monsters.md b/markdown_obsidian/Random Dungeon Monsters.md
index ea304a8..a6a3eb4 100644
--- a/markdown_obsidian/Random Dungeon Monsters.md
+++ b/markdown_obsidian/Random Dungeon Monsters.md
@@ -1,5 +1,3 @@
-# Random Dungeon Monsters
-
The following tables let you randomly select monsters based on "dungeon level." Although these charts are built for old-school dungeon delving, you can use them to generate randomly encountered monsters in just about any setting - a ruin, an old church, caves, catacombs, an old wizard's tower, or some other forgotten lair.
To use these tables, first decide what dungeon level the characters are on. This might correspond to the level of the characters but it doesn't have to. If 2nd-level characters decide to descend to dungeon level 5, so be it.
@@ -29,6 +27,8 @@ Before the number of monsters is set, you can gauge whether your intended encoun
## Monster List 1 (CR 1/8—1/4)
+`dice: [[Random Dungeon Monsters#^monster-list-1-cr-1814]]`
+
1. Bandit
2. Cultist
3. Flying snake
@@ -50,8 +50,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Swarm of bats
20. Swarm of rats
+^monster-list-1-cr-1814
+
## Monster List 2 (CR 1/4—1)
+`dice: [[Random Dungeon Monsters#^monster-list-2-cr-141]]`
+
1. Wolf
2. Zombie
3. Cockatrice
@@ -73,8 +77,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Bugbear
20. Death dog
+^monster-list-2-cr-141
+
## Monster List 3 (CR 1—2)
+`dice: [[Random Dungeon Monsters#^monster-list-3-cr-12]]`
+
1. Dire wolf
2. Duergar
3. Ghoul
@@ -96,8 +104,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Giant constrictor snake
20. Gibbering mouther
+^monster-list-3-cr-12
+
## Monster List 4 (CR 2—3)
+`dice: [[Random Dungeon Monsters#^monster-list-4-cr-23]]`
+
1. Azer
2. Green dragon wyrmling
3. Grick
@@ -119,8 +131,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Bearded devil
20. Blue dragon wyrmling
+^monster-list-4-cr-23
+
## Monster List 5 (CR 3—4)
+`dice: [[Random Dungeon Monsters#^monster-list-5-cr-34]]`
+
1. Doppelganger
2. Giant scorpion
3. Green hag
@@ -142,8 +158,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Ettin
20. Ghost
+^monster-list-5-cr-34
+
## Monster List 6 (CR 4—5)
+`dice: [[Random Dungeon Monsters#^monster-list-6-cr-45]]`
+
1. Lamia
2. Red dragon wyrmling
3. Succubus/incubus
@@ -165,8 +185,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Shambling mound
20. Troll
+^monster-list-6-cr-45
+
## Monster List 7 (CR 5—8)
+`dice: [[Random Dungeon Monsters#^monster-list-7-cr-58]]`
+
1. Salamander
2. Vampire spawn
3. Water elemental
@@ -188,8 +212,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Chain devil
20. Cloaker
+^monster-list-7-cr-58
+
## Monster List 8 (CR 8—12)
+`dice: [[Random Dungeon Monsters#^monster-list-8-cr-812]]`
+
1. Frost giant
2. Hezrou
3. Hydra
@@ -211,8 +239,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
19. Remorhaz
20. Archmage
+^monster-list-8-cr-812
+
## Monster List 9 (CR 12—16)
+`dice: [[Random Dungeon Monsters#^monster-list-9-cr-1216]]`
+
1. Erinyes
2. Adult white dragon
3. Nalfeshnee
@@ -226,8 +258,12 @@ Before the number of monsters is set, you can gauge whether your intended encoun
11. Purple worm
12. Adult blue dragon
+^monster-list-9-cr-1216
+
## Monster List 10 (CR 16—24)
+`dice: [[Random Dungeon Monsters#^monster-list-10-cr-1624]]`
+
1. Iron golem
2. Marilith
3. Adult red dragon
@@ -238,3 +274,5 @@ Before the number of monsters is set, you can gauge whether your intended encoun
8. Lich
9. Ancient blue dragon
10. Ancient red dragon
+
+^monster-list-10-cr-1624
diff --git a/markdown_obsidian/Random Items.md b/markdown_obsidian/Random Items.md
index 8da9b51..33247c0 100644
--- a/markdown_obsidian/Random Items.md
+++ b/markdown_obsidian/Random Items.md
@@ -1,5 +1,3 @@
-# Random Items
-
The following lists allow you to generate useful relics and objects, from mundane discoveries to powerful magical artifacts. If you want to come up with an interesting magic weapon, for example, you might roll on the Item Condition, Item Origin, Weapon, and Spell Effect tables. If you just want a weird mundane item, roll on the Item Condition, Item Origin, and Mundane Item tables without adding any effect.
Some strange relics might allow a single use of a powerful magical spell. Roll on the Item Condition, Item Origin, Mundane Item, and Spell Effect table to generate a unique single-use magical relic.
@@ -8,6 +6,8 @@ Also included is a table noting the four types of *healing potions* and how many
## 1d20 Weapon Types
+`dice: [[Random Items#^1d20-weapon-types]]`
+
1. Dagger
2. Mace
3. Quarterstaff
@@ -29,8 +29,12 @@ Also included is a table noting the four types of *healing potions* and how many
19. Heavy crossbow
20. Longbow
+^1d20-weapon-types
+
## 1d20 Item Origins
+`dice: [[Random Items#^1d20-item-origins]]`
+
1. Draconic
2. Dwarven
3. Elven
@@ -52,8 +56,12 @@ Also included is a table noting the four types of *healing potions* and how many
19. Elemental
20. Gnomish
+^1d20-item-origins
+
## 1d20 Item Conditions
+`dice: [[Random Items#^1d20-item-conditions]]`
+
1. Grimy
2. Chipped
3. Rough
@@ -75,8 +83,12 @@ Also included is a table noting the four types of *healing potions* and how many
19. Shining
20. Smoldering
+^1d20-item-conditions
+
## 1d12 Armor Types
+`dice: [[Random Items#^1d12-armor-types]]`
+
1. Leather
2. Studded leather
3. Hide
@@ -90,8 +102,12 @@ Also included is a table noting the four types of *healing potions* and how many
11. Plate
12. Shield
+^1d12-armor-types
+
## 50 Mundane Items
+`dice: [[Random Items#^50-mundane-items]]`
+
1. Amulet
2. Arrowhead
3. Bell
@@ -143,8 +159,12 @@ Also included is a table noting the four types of *healing potions* and how many
49. Vial
50. Wand
+^50-mundane-items
+
## 50 Spell Effect
+`dice: [[Random Items#^50-spell-effect]]`
+
1. *Acid arrow*
2. *Acid splash*
3. *Bane*
@@ -196,11 +216,19 @@ Also included is a table noting the four types of *healing potions* and how many
49. *True strike*
50. *Web*
+^50-spell-effect
+
## Potions of Healing
+**Potion of: **`dice: [[Random Items#^potions-of-healing]]|Potion of`
+**Rarity: **`dice: [[Random Items#^potions-of-healing]]|Rarity`
+**HP Regained: **`dice: [[Random Items#^potions-of-healing]]|HP Regained`
+
| d20 | Potion of | Rarity | HP Regained |
| ------- | ---------------- | --------- | ----------- |
| 1 - 12 | Healing | Common | 2d4 + 2 |
| 13 - 16 | Greater healing | Uncommon | 4d4 + 4 |
| 17 - 19 | Superior healing | Rare | 8d4 + 8 |
| 20 | Supreme healing | Very rare | 10d4 + 20 |
+
+^potions-of-healing
diff --git a/markdown_obsidian/Random Monuments.md b/markdown_obsidian/Random Monuments.md
index ad41a62..3b96956 100644
--- a/markdown_obsidian/Random Monuments.md
+++ b/markdown_obsidian/Random Monuments.md
@@ -1,9 +1,9 @@
-# Random Monuments
-
Filling the various chambers and locations in your game with interesting features is always a challenge — and can be even more difficult to improvise. The following four "Monuments" lists can help you generate fantastic features with a number of potential effects. You don't need to roll on every table each time you want to generate a feature. Sometimes, just establishing the condition and the type of a feature is enough to give you a starting point. Then you can let the story or even the background of one of the characters guide the feature's additional elements.
## 1d20 Origins
+`dice: [[Random Monuments#^1d20-origins]]`
+
1. Draconic
2. Dwarven
3. Elven
@@ -25,8 +25,12 @@ Filling the various chambers and locations in your game with interesting feature
19. Elemental
20. Gnomish
+^1d20-origins
+
## 1d20 Conditions
+`dice: [[Random Monuments#^1d20-conditions]]`
+
1. Crumbling
2. Sunken
3. Pristine
@@ -48,8 +52,12 @@ Filling the various chambers and locations in your game with interesting feature
19. Decorated
20. Floating
+^1d20-conditions
+
## 1d20 Unusual Effects
+`dice: [[Random Monuments#^1d20-unusual-effects]]`
+
1. Undeath
2. Fire
3. Madness
@@ -71,8 +79,12 @@ Filling the various chambers and locations in your game with interesting feature
19. Thunder
20. Tentacles
+^1d20-unusual-effects
+
## 100 Monument Structures
+`dice: [[Random Monuments#^100-monument-structures]]`
+
1. Aerie
2. Altar
3. Aqueduct
@@ -173,3 +185,5 @@ Filling the various chambers and locations in your game with interesting feature
98. Waymarker
99. Well
100. Windmill
+
+^100-monument-structures
diff --git a/markdown_obsidian/Random Town Events.md b/markdown_obsidian/Random Town Events.md
index fd1ba68..c99d6ed 100644
--- a/markdown_obsidian/Random Town Events.md
+++ b/markdown_obsidian/Random Town Events.md
@@ -1,9 +1,9 @@
-# Random Town Events
-
Whenever the characters enter a new town or start a new session there, adding some detail and context to the setting can help bring things to life. These "Town Events" lists help determine what might be going on in a town, how the townsfolk are currently feeling, what the weather is, and what mundane or fantastic event might be taking place.
## 1d20 Town Sentiments
+`dice: [[Random Town Events#^1d20-town-sentiments]]`
+
1. Happy
2. Elated
3. Uncaring
@@ -25,8 +25,12 @@ Whenever the characters enter a new town or start a new session there, adding so
19. Busy
20. Suspicious
+^1d20-town-sentiments
+
## 1d20 Mundane Events
+`dice: [[Random Town Events#^1d20-mundane-events]]`
+
1. Wedding
2. Funeral
3. Preparing for war
@@ -48,8 +52,12 @@ Whenever the characters enter a new town or start a new session there, adding so
19. Wrangling of rampaging beasts
20. Festival of kites
+^1d20-mundane-events
+
## 1d20 Notable Weather Condtions
+`dice: [[Random Town Events#^1d20-notable-weather-condtions]]`
+
1. Fog
2. Heavy mist
3. New moon
@@ -71,8 +79,12 @@ Whenever the characters enter a new town or start a new session there, adding so
19. Moderate snowfall
20. Snowstorm
+^1d20-notable-weather-condtions
+
## 1d20 Fantastic Events
+`dice: [[Random Town Events#^1d20-fantastic-events]]`
+
1. The stars have disappeared from the sky
2. An unexpected solar eclipse
3. The blood moon rises
@@ -93,3 +105,5 @@ Whenever the characters enter a new town or start a new session there, adding so
18. The lord's castle disappears
19. The border to the fey realm grows thin
20. The world of shadow bleeds over into the material realm
+
+^1d20-fantastic-events
diff --git a/markdown_obsidian/Random Traps.md b/markdown_obsidian/Random Traps.md
index de8d5bf..bcd4806 100644
--- a/markdown_obsidian/Random Traps.md
+++ b/markdown_obsidian/Random Traps.md
@@ -1,11 +1,11 @@
-# Random Traps
-
Use these lists to generate simple or complex traps, incorporating multiple features, plus energy damage or conditions.
To generate a simple trap, just roll on the Type list and the Trigger table. For a more dangerous trap, add an effect from the Flavor table to put a unique twist on the damage or impose a debilitating condition. For a really devious trap, you can roll on the Flavor table and Type table twice, combining features into deadly combinations such as 'sleep-inducing bolos and thunderous crushing pillars, triggered by an onyx demon's skull.'
## 1d20 Flavors
+`dice: [[Random Traps#^1d20-flavors]]`
+
1. Fiery
2. Freezing
3. Necrotic
@@ -27,8 +27,12 @@ To generate a simple trap, just roll on the Type list and the Trigger table. For
19. Maddening
20. Confusing
+^1d20-flavors
+
## 1d20 Types
+`dice: [[Random Traps#^1d20-types]]`
+
1. Bolts
2. Spears
3. Scythes
@@ -50,8 +54,12 @@ To generate a simple trap, just roll on the Type list and the Trigger table. For
19. Hammers
20. Shurikens
+^1d20-types
+
## 1d20 Triggers
+`dice: [[Random Traps#^1d20-triggers]]`
+
1. Door
2. Floor plate
3. Tripwire
@@ -73,6 +81,8 @@ To generate a simple trap, just roll on the Type list and the Trigger table. For
19. Weapon on an altar
20. Idol on pedestal
+^1d20-triggers
+
## Damage Severity by Level
| Character Level | Setback | Dangerous | Deadly |
diff --git a/markdown_obsidian/Running Hordes.md b/markdown_obsidian/Running Hordes.md
index 21632ac..4a743cb 100644
--- a/markdown_obsidian/Running Hordes.md
+++ b/markdown_obsidian/Running Hordes.md
@@ -1,5 +1,3 @@
-# Running Hordes
-
This section helps you more easily run battles in which the characters face large numbers of monsters.
To accommodate running horde combat, we change the rules for running monsters in two ways: adjusting how we track damage done to monsters in a horde, and how we adjudicate attack rolls and saving throws for the horde. You can use these approaches individually or together when running large numbers of monsters.
diff --git a/markdown_obsidian/Safety Tools.md b/markdown_obsidian/Safety Tools.md
index 9773ae8..11bb916 100644
--- a/markdown_obsidian/Safety Tools.md
+++ b/markdown_obsidian/Safety Tools.md
@@ -1,5 +1,3 @@
-# Safety Tools
-
Safety tools help ensure that you and your players are always comfortable with the subject matter of the games you run — especially when that subject matter involves potentially troubling tropes or themes. The safety tools presented in this section can be used individually or together to make sure that everyone is comfortable with the material in the game, even as that material evolves during play. You can choose which safety tools work well for you and your group, and discuss their use early in your game. Usually this means discussing safety tools during your campaign's session zero, or at the beginning of a single-session game.
## Potentially Sensitive Topics
diff --git a/markdown_obsidian/Session Zero Checklist.md b/markdown_obsidian/Session Zero Checklist.md
index 1e39655..b6ede30 100644
--- a/markdown_obsidian/Session Zero Checklist.md
+++ b/markdown_obsidian/Session Zero Checklist.md
@@ -1,5 +1,3 @@
-# Session Zero Checklist
-
Session zero is a vital tool for getting players and GMs on the same page about a new campaign. A session zero takes place before the first session of a campaign. This special session gives you time to ensure that the players are on board with the themes of the campaign, and that their characters will integrate well together and with the adventures to come.
The following guidelines take you step-by-step through a session zero.
@@ -36,6 +34,8 @@ If desired, you can connect the characters together with individual relationship
## Relationships
+`dice: [[Session Zero Checklist#^relationships]]`
+
1. Adopted siblings
2. Mentor and student
3. Friendly rivals
@@ -57,6 +57,8 @@ If desired, you can connect the characters together with individual relationship
19. Business partners
20. Master and servant
+^relationships
+
## Run a Short Adventure
Once the characters are built and your players are ready, you can run a short adventure at the end of session zero to introduce the characters to the campaign in a fast and exciting way. You might choose to run a single combat encounter with some added negotiation and exploration, after which the characters advance to 2nd level and are ready to fully engage with the story of the campaign.
diff --git a/markdown_obsidian/Spiral Campaign Development.md b/markdown_obsidian/Spiral Campaign Development.md
index 71883bb..aecc732 100644
--- a/markdown_obsidian/Spiral Campaign Development.md
+++ b/markdown_obsidian/Spiral Campaign Development.md
@@ -1,5 +1,3 @@
-# Spiral Campaign Development
-
Spiral campaign development builds campaign worlds starting in the area immediately surrounding the characters, then spirals out, expanding the world as the characters experience it. This section offers suggestions and inspiration for building a spiral campaign.
## Campaign Pitch
@@ -8,6 +6,8 @@ Start off by describing the central theme of your campaign in a single sentence.
## Campaign Pitches
+`dice: [[Spiral Campaign Development#^campaign-pitches]]`
+
1. Prevent the summoning of the Dragon Queen
2. Prevent the coming of the Black Moon
3. End the dark reign of Elenda the lich queen
@@ -29,6 +29,8 @@ Start off by describing the central theme of your campaign in a single sentence.
19. Slay the ancient dragon Larthyx Flametongue
20. End the dark pact of Karthyn the archdevil
+^campaign-pitches
+
## Six Truths
Once you have your pitch, identify six truths that set your campaign apart from others, then share them with your players. Here are six example truths for a campaign built around the coming of the Black Moon from above.
@@ -46,6 +48,8 @@ Spiral campaigns begin in a central location, often a small settlement from whic
## 1d10 Starting Locations
+`dice: [[Spiral Campaign Development#^1d10-starting-locations]]`
+
1. Adventurers' guild
2. Mining outpost
3. Recent shipwreck
@@ -57,12 +61,16 @@ Spiral campaigns begin in a central location, often a small settlement from whic
9. Planar hub city
10. Crumbling fortress
+^1d10-starting-locations
+
## Campaign Fronts
Campaign fronts are the external motivators in a campaign. Like a battlefront (from which they're named), a front is a point of conflict that advances and retreats as the campaign develops. Fronts are often villains, but might also be external forces such as natural disasters or grim fate. Campaigns might have up to three fronts at any given time, including any of the following.
## 1d20 Campaign Fronts
+`dice: [[Spiral Campaign Development#^1d20-campaign-fronts]]`
+
1. Thieves' guild
2. Dark necromancer
3. Armageddon cult
@@ -84,10 +92,14 @@ Campaign fronts are the external motivators in a campaign. Like a battlefront (f
19. Draconic terror
20. Undead prince
+^1d20-campaign-fronts
+
## Local Adventure Locations
As the campaign spirals outward, the characters will become aware of local adventuring locations. Drop three such adventure locations into the areas close by the starting location. And if you need help filling out an adventure location, look to later sections of this document.
+`dice: [[Spiral Campaign Development#^local-adventure-locations]]`
+
1. Ancient crypt
2. Forgotten sewers
3. Haunted keep
@@ -108,3 +120,5 @@ As the campaign spirals outward, the characters will become aware of local adven
18. Submerged grotto
19. Dead hollow tree
20. Sundered shipwreck
+
+^local-adventure-locations
diff --git a/markdown_obsidian/Stress Effects.md b/markdown_obsidian/Stress Effects.md
index 7e33b72..f1c12c9 100644
--- a/markdown_obsidian/Stress Effects.md
+++ b/markdown_obsidian/Stress Effects.md
@@ -1,5 +1,3 @@
-# Stress Effects
-
The guidelines in this section replace the madness rules found in other books. The concept of "madness" has long been used to malign and marginalize complex psychological symptoms and the individuals coping with them.
This new approach works with explicitly supernatural hindrances to break away from those stereotypes.
@@ -39,6 +37,8 @@ Whenever a character witnesses a potential stress event, you can ask for a Chari
## 1d20 Stress Results
+`dice: [[Stress Effects#^1d20-stress-results]]`
+
1. You slip into a mental vision of a restful place.
2. You whisper in a tongue no mortal understands.
3. Blood flows from your eyes.
@@ -60,6 +60,8 @@ Whenever a character witnesses a potential stress event, you can ask for a Chari
19. You scream as blood flows from your mouth.
20. You feel as though all your bones begin to crack.
+^1d20-stress-results
+
You determine how long the effect lasts and can add mechanical hindrances inspired by the effect at your discretion. Alternatively, you can add the following mechanical effect:
On a failed save, the character becomes stunned for 1 minute. The character can repeat the saving throw at the end of each of their turns and whenever they take damage, ending the effect on themself on a success. If the character's saving throw is successful or if the effect ends for it, the character is immune to this effect for the next 24 hours. A character can also choose to break this effect at the start of their turn by taking 4 (1d8) psychic damage per two character levels. A *lesser restoration* or equivalent effect likewise negates a stress effect.
diff --git a/markdown_obsidian/The Eight Steps of Lazy RPG Prep.md b/markdown_obsidian/The Eight Steps of Lazy RPG Prep.md
index 071588b..71f20bc 100644
--- a/markdown_obsidian/The Eight Steps of Lazy RPG Prep.md
+++ b/markdown_obsidian/The Eight Steps of Lazy RPG Prep.md
@@ -1,5 +1,3 @@
-# The Eight Steps of Lazy RPG Prep
-
For a typical game session, the Lazy RPG Prep checklist looks like this:
* Review the characters
diff --git a/markdown_obsidian/The Lazy GM's Resource Document.md b/markdown_obsidian/The Lazy GM's Resource Document.md
index a7f8c7c..3346e47 100644
--- a/markdown_obsidian/The Lazy GM's Resource Document.md
+++ b/markdown_obsidian/The Lazy GM's Resource Document.md
@@ -1,5 +1,3 @@
-# The Lazy GM's Resource Document
-
Michael E. Shea, [SlyFlourish.com](https://slyflourish.com).
Updated 10 September 2023
diff --git a/markdown_obsidian/The Lazy RPG Preparation Process.md b/markdown_obsidian/The Lazy RPG Preparation Process.md
index d4cdfb7..c891b21 100644
--- a/markdown_obsidian/The Lazy RPG Preparation Process.md
+++ b/markdown_obsidian/The Lazy RPG Preparation Process.md
@@ -1,5 +1,3 @@
-# The Lazy RPG Preparation Process
-
## The Lazy RPG Prep Toolkit
* Dice, pencils, and dry-erase markers
diff --git a/markdown_obsidian/Theater of the Mind Guidelines (Abbreviated).md b/markdown_obsidian/Theater of the Mind Guidelines (Abbreviated).md
index b032b1f..e45651e 100644
--- a/markdown_obsidian/Theater of the Mind Guidelines (Abbreviated).md
+++ b/markdown_obsidian/Theater of the Mind Guidelines (Abbreviated).md
@@ -1,5 +1,3 @@
-# Theater of the Mind Guidelines (Abbreviated)
-
This section offers abbreviated guidelines for running "theater of the mind" combat — no maps or miniatures, making use only of narrative and your players' imaginations. Share these guidelines with your players so that everyone has a common understanding of how this style of playing out combat works at the table.
## Core Principles
diff --git a/markdown_obsidian/Theater of the Mind Guidelines (Extended).md b/markdown_obsidian/Theater of the Mind Guidelines (Extended).md
index 70b84e1..2a5ecb1 100644
--- a/markdown_obsidian/Theater of the Mind Guidelines (Extended).md
+++ b/markdown_obsidian/Theater of the Mind Guidelines (Extended).md
@@ -1,5 +1,3 @@
-# Theater of the Mind Guidelines (Extended)
-
The following guidelines can help Gamemasters run combat in the "theater of the mind," without the need for a gridded battle map or miniatures. This style of combat takes the emphasis away from tactical features such as distance, range, and the specific size of areas of effect. Instead, it focuses on the in-game action, the intent of the characters, and what happens in the story.
This style of combat works just like any other scene in your game. On each player's turn, you describe the current situation, the players describe their intent, and you adjudicate what happens as a result.
diff --git a/markdown_obsidian/Tools for 5e Improvisation.md b/markdown_obsidian/Tools for 5e Improvisation.md
index ff8ccb0..2c2cf6a 100644
--- a/markdown_obsidian/Tools for 5e Improvisation.md
+++ b/markdown_obsidian/Tools for 5e Improvisation.md
@@ -1,5 +1,3 @@
-# Tools for 5e Improvisation
-
## Difficulty Checks
For any given task or challenge, ask yourself how hard it is to accomplish. Then assign a DC from 10 (easy) to 20 (very hard). If a task is trivial, don't bother asking for a roll. Rather, the characters automatically succeed. Likewise, reserve DCs above 20 for superhuman challenges.
diff --git a/markdown_obsidian/Treasure Generator.md b/markdown_obsidian/Treasure Generator.md
index e9d9e49..814c699 100644
--- a/markdown_obsidian/Treasure Generator.md
+++ b/markdown_obsidian/Treasure Generator.md
@@ -1,5 +1,3 @@
-# Treasure Generator
-
Piles of coins, shining gems, and powerful relics hidden away in the depths of the world await adventurers brave enough to seek them. This section offers a simple set of tables and guidelines that let you quickly reward treasure for your fantasy RPG, and which work well alongside the more detailed treasure rules of the game.
## Gold Per Level
@@ -21,6 +19,8 @@ As desired, you can augment monetary treasure with consumable magic items from t
## 1d12 Consumable Treasure
+`dice: [[Treasure Generator#^1d12-consumable-treasure]]`
+
1. *Potion of healing*
2. *Potion of greater healing*
3. *Oil of slipperiness*
@@ -34,6 +34,8 @@ As desired, you can augment monetary treasure with consumable magic items from t
11. *Dust of disappearance*
12. *Dust of dryness*
+^1d12-consumable-treasure
+
Rather than standard consumable items, you can also award powerful single-use magic items generated using the Spells table from the "Core Adventure Generator" included in this document. You can also use the Condition, Description, and Origin table in that section to give an item a unique flavor.
## Magical Treasure
@@ -42,6 +44,8 @@ Permanent magic items can be included with treasure as desired, with the uncommo
## 40 Magical Treasures
+`dice: [[Treasure Generator#^40-magical-treasures]]`
+
1. *Weapon +1*
2. *Armor +1*
3. *Ammunition +1*
@@ -82,3 +86,5 @@ Permanent magic items can be included with treasure as desired, with the uncommo
38. *Stone of good luck*
39. *Wand of magic missiles*
40. *Wand of web*
+
+^40-magical-treasures
diff --git a/markdown_obsidian/Undead Templates.md b/markdown_obsidian/Undead Templates.md
index 6035bac..59556fd 100644
--- a/markdown_obsidian/Undead Templates.md
+++ b/markdown_obsidian/Undead Templates.md
@@ -1,5 +1,3 @@
-# Undead Templates
-
Death comes to all things, but not even death can keep a good monster down. You can easily create an undead variant of any monster simply by giving it the undead type and describing its undead appearance, letting the narrative feed the players' impression of fighting undead without requiring any mechanical changes. But for even more realistic undead, you can use any of the following templates to give a monster some of the properties and attributes of a specific type of undead creature.
## Undead Templates
diff --git a/markdown_obsidian/Wilderness Travel and Exploration.md b/markdown_obsidian/Wilderness Travel and Exploration.md
index 99697c9..2391092 100644
--- a/markdown_obsidian/Wilderness Travel and Exploration.md
+++ b/markdown_obsidian/Wilderness Travel and Exploration.md
@@ -1,5 +1,3 @@
-# Wilderness Travel and Exploration
-
This section offers a systematic approach for handling travel through wild lands filled with potential dangers, and can be used with both point crawls (see the previous page) or hex crawls.
As the characters travel overland, they undertake specific activities related to the journey. Select appropriate DCs for those activities, with checks usually ranging between DC 10 (easy) and DC 20 (very hard). A default of DC 12 is usually a good choice.
diff --git a/markdown_obsidian/Zone-Based Combat.md b/markdown_obsidian/Zone-Based Combat.md
index b2e8a2e..6ef6641 100644
--- a/markdown_obsidian/Zone-Based Combat.md
+++ b/markdown_obsidian/Zone-Based Combat.md
@@ -1,5 +1,3 @@
-# Zone-Based Combat
-
Zone-based combat can help GMs run fast, dynamic, and high-action combat without worrying about all the details of tactical combat played out on a grid. It supports multiple combat styles, including pure narrative theater-of-the-mind combat, quickly drawn abstract sketches, or miniatures used with detailed maps or 3D terrain. Using zone-based combat means you have to worry less about the details of a 5-foot-per-square grid and can focus more on big heroic action. Zone-based combat simply requires that the GM and the players work together with the shared goal of creating fantastic stories of high adventure.
## Zone Rules
diff --git a/markdown_obsidian_5e_monster_builder/Bosses and Minions.md b/markdown_obsidian_5e_monster_builder/Bosses and Minions.md
index 01151d4..b7766ea 100644
--- a/markdown_obsidian_5e_monster_builder/Bosses and Minions.md
+++ b/markdown_obsidian_5e_monster_builder/Bosses and Minions.md
@@ -1,5 +1,3 @@
-# Bosses and Minions
-
When creating a boss battle, thinking about which bosses pair well with which minions can be a great starting point. You can use the table below to match up minions and bosses in a number of classic adventure environments.
| Boss CR | Boss | Environments | Minions |
diff --git a/markdown_obsidian_5e_monster_builder/Building a Quick Monster.md b/markdown_obsidian_5e_monster_builder/Building a Quick Monster.md
index e29d83f..aea45b9 100644
--- a/markdown_obsidian_5e_monster_builder/Building a Quick Monster.md
+++ b/markdown_obsidian_5e_monster_builder/Building a Quick Monster.md
@@ -1,5 +1,3 @@
-# Building a Quick Monster
-
Sometimes you need a monster right now but you don't have the right one handy. Maybe the creature you're imagining doesn't exist in any given book of published monsters, or you simply don't have the time to look it up. Maybe you're in the middle of your game and want some quick statistics for a creature you didn't think you'd need. For all these problems, this section offers solutions.
The core tool for building a quick monster for a 5e game is the Monster Statistics by Challenge Rating table, which offers you a set of statistics that can be used to build and run a quick monster of any challenge rating (CR). You then have two paths for customizing a monster built from these baseline statistics—with flavor and description during the game, or with a refinement of the creature's mechanics.
diff --git a/markdown_obsidian_5e_monster_builder/General-Use Combat Stat Blocks.md b/markdown_obsidian_5e_monster_builder/General-Use Combat Stat Blocks.md
index 3681c0d..bf9bd55 100644
--- a/markdown_obsidian_5e_monster_builder/General-Use Combat Stat Blocks.md
+++ b/markdown_obsidian_5e_monster_builder/General-Use Combat Stat Blocks.md
@@ -1,5 +1,3 @@
-# General-Use Combat Stat Blocks
-
This section contains several general-use stat blocks specifically built for reskinning into whatever monsters you need for your combat encounters.
Each stat block uses d8 Hit Dice, but can be used for creatures in a range of sizes. Each focuses on a primary ability score, but you can shift abilities as needed to better fit the story of the creature the stat block represents. Swap Strength and Intelligence to run a spellcaster instead of a melee combatant, or switch Dexterity and Strength to turn a shifty rogue into a powerful fighter.
diff --git a/markdown_obsidian_5e_monster_builder/Lazy Tricks for Running Monsters.md b/markdown_obsidian_5e_monster_builder/Lazy Tricks for Running Monsters.md
index ffffdff..2df0e35 100644
--- a/markdown_obsidian_5e_monster_builder/Lazy Tricks for Running Monsters.md
+++ b/markdown_obsidian_5e_monster_builder/Lazy Tricks for Running Monsters.md
@@ -1,5 +1,3 @@
-# Lazy Tricks for Running Monsters
-
This section presents a number of tricks and tips that can help you more easily prepare and run monsters during your games. We call them "lazy tricks" not because they're about cheating or doing less work overall, but because they're meant to let you quickly accomplish things when your game is in progress and you don't have a lot of extra time.
## Quick Monster Statistics
diff --git a/markdown_obsidian_5e_monster_builder/Lightning Rods.md b/markdown_obsidian_5e_monster_builder/Lightning Rods.md
index 7583533..8776f56 100644
--- a/markdown_obsidian_5e_monster_builder/Lightning Rods.md
+++ b/markdown_obsidian_5e_monster_builder/Lightning Rods.md
@@ -1,5 +1,3 @@
-# Lightning Rods
-
When characters rise above 4th level, their ability to deal with powerful foes makes a huge jump. But challenging characters of 5th level and higher isn't just about making things hard. It's easy for GMs to fall into the trap of thwarting the coolest things the heroes can do, by giving monsters immunities to certain conditions, increasing their hit points to offset the high damage a character can deal, or running monsters with tactics clearly built to bypass the characters' best attacks. But thwarting the characters' best features can be frustrating to the players, for obvious reasons.
So instead of shutting down the characters, build your encounters around monsters specifically designed to show off—by eating up—the characters' cool new capabilities as they rise in level. You can think of these monsters as "lightning rods"—intended victims ready to take the full effect of a character's most powerful attacks and features.
diff --git a/markdown_obsidian_5e_monster_builder/Monster Combinations for a Hard Challenge.md b/markdown_obsidian_5e_monster_builder/Monster Combinations for a Hard Challenge.md
index 6638cb4..a110484 100644
--- a/markdown_obsidian_5e_monster_builder/Monster Combinations for a Hard Challenge.md
+++ b/markdown_obsidian_5e_monster_builder/Monster Combinations for a Hard Challenge.md
@@ -1,5 +1,3 @@
-# Monster Combinations for a Hard Challenge
-
When GMs design encounters, we often have a concept that includes the number of foes the characters will face. An encounter might feature a squad of four monsters going against the characters one-to-one, or perhaps a larger force of six or eight swarming the heroes. Or maybe we want a stronger creature, acting as a boss or captain, with only a few other creatures to back them up. And, of course, it's always fun for characters to face a single dangerous foe.
This section provides guidelines for combining creatures of different challenge ratings to enable these various concepts. Simply pick your concept, consult the appropriate table for the number of characters in your game, look up their average character level, and you have the monster challenge ratings you need to build different types of encounters and boss scenarios. You can then use the other tips in this document to make encounters unique.
diff --git a/markdown_obsidian_5e_monster_builder/Monster Roles.md b/markdown_obsidian_5e_monster_builder/Monster Roles.md
index e8dbb6f..a2ac5c9 100644
--- a/markdown_obsidian_5e_monster_builder/Monster Roles.md
+++ b/markdown_obsidian_5e_monster_builder/Monster Roles.md
@@ -1,5 +1,3 @@
-# Monster Roles
-
Thinking about the roles that creatures play in combat helps to create better encounters. A monster who has tons of hit points can stand up front, soaking up damage while the more vulnerable evil wizard launches devastating spells from behind cover. Skirmisher monsters can dart in from the sides and back away, forcing the characters to spread out and leaving them open to an ambusher. Foes of different roles complement each other, creating an effective team.
Monsters in 5e don't have defined roles with connections to specific mechanics and tactics, as the creatures in some fantasy RPGs do. However, many 5e foes either already fit a specific role or are flexible enough to allow us to assign roles to them. For example, a harpy is a highly effective controller, and a spy is an excellent skirmisher or ambusher. We can also modify monsters to enable them to play a role. By assigning a role to a foe, you enable a specific set of tactics that allow you to challenge the characters more effectively.
diff --git a/markdown_obsidian_5e_monster_builder/Monsters and the Tiers of Play.md b/markdown_obsidian_5e_monster_builder/Monsters and the Tiers of Play.md
index 8be84b4..96eea5f 100644
--- a/markdown_obsidian_5e_monster_builder/Monsters and the Tiers of Play.md
+++ b/markdown_obsidian_5e_monster_builder/Monsters and the Tiers of Play.md
@@ -1,5 +1,3 @@
-# Monsters and the Tiers of Play
-
How combat plays out against specific types of monsters in other 5e games changes depending on the level of the characters. Character power progression isn't smooth and linear across levels. Rather, it spikes at particular levels, potentially changing the outcome of a battle dramatically. As an example, the jump from 4th to 5th level gives melee characters twice as many attacks, while spellcasters gain access to spells such as *fireball*, significantly raising a party's damage output overnight. Recognizing when and how these changes take place can help GMs understand and prepare for these shifts in game play.
## 1st Level
diff --git a/markdown_obsidian_5e_monster_builder/Monsters by Adventure Location.md b/markdown_obsidian_5e_monster_builder/Monsters by Adventure Location.md
index 8b6ede8..cd0690c 100644
--- a/markdown_obsidian_5e_monster_builder/Monsters by Adventure Location.md
+++ b/markdown_obsidian_5e_monster_builder/Monsters by Adventure Location.md
@@ -1,5 +1,3 @@
-# Monsters by Adventure Location
-
This section offers quick starting points for building encounters, in the form of tables that cover a broad range of foes in twelve types of common adventure location. The tables serve four purposes:
* They show which creatures might inhabit a particular adventure location.
diff --git a/markdown_obsidian_5e_monster_builder/The Combat Encounter Checklist.md b/markdown_obsidian_5e_monster_builder/The Combat Encounter Checklist.md
index c541047..0e14651 100644
--- a/markdown_obsidian_5e_monster_builder/The Combat Encounter Checklist.md
+++ b/markdown_obsidian_5e_monster_builder/The Combat Encounter Checklist.md
@@ -1,5 +1,3 @@
-# The Combat Encounter Checklist
-
Sometimes all a game needs is an interesting location and some cool monsters to fight, setting up a combat encounter that a GM might build right at the table. The characters go somewhere, everyone decides it's time for a fun fight, and you whip something up. Or you determine that, given the circumstances going on in the story, it's time for the characters to run into some opposition, and you're off to the races.
Sometimes we need more, though, particularly for big set-piece battles or boss fights. When it's time to build an interesting and dynamic encounter, the following checklist can help determine what options a big combat might need:
diff --git a/markdown_obsidian_5e_monster_builder/The Lazy Encounter Benchmark.md b/markdown_obsidian_5e_monster_builder/The Lazy Encounter Benchmark.md
index 990244c..dd3fab9 100644
--- a/markdown_obsidian_5e_monster_builder/The Lazy Encounter Benchmark.md
+++ b/markdown_obsidian_5e_monster_builder/The Lazy Encounter Benchmark.md
@@ -1,5 +1,3 @@
-# The Lazy Encounter Benchmark
-
This section sets out a simple calculation you can keep in your head to give you a gauge of the difficulty of an encounter. This "lazy encounter benchmark" isn't perfect or precise. Rather, it's a tool for getting a rough sense of the potential challenge of a combat encounter–and for recognizing when an encounter crosses over from challenging to potentially deadly. Think of it like a tachometer measuring how fast the engine is running in a car. If you go beyond the limit defined by the benchmark, you're "in the red"–pushing to a point where your encounter might be more than the characters can handle.
## Using the Benchmark
diff --git a/markdown_obsidian_5e_monster_builder/The Lazy GM's 5e Monster Builder Resource Document.md b/markdown_obsidian_5e_monster_builder/The Lazy GM's 5e Monster Builder Resource Document.md
index 4972d3f..c6e1843 100644
--- a/markdown_obsidian_5e_monster_builder/The Lazy GM's 5e Monster Builder Resource Document.md
+++ b/markdown_obsidian_5e_monster_builder/The Lazy GM's 5e Monster Builder Resource Document.md
@@ -1,5 +1,3 @@
-# The Lazy GM's 5e Monster Builder Resource Document
-
Scott Fitzgerald Gray, Teos Abadía, Michael E. Shea.
Updated 18 January 2024
diff --git a/metadata/updates.json b/metadata/updates.json
index aa988d4..027979d 100644
--- a/metadata/updates.json
+++ b/metadata/updates.json
@@ -11,6 +11,6 @@
"mb-markdown": "2024-03-10T23:21:27.774Z",
"mb-markdown_separate": "2024-03-10T23:21:27.918Z",
"mb-json": "2024-03-10T23:21:54.715Z",
- "markdown_obsidian": "2024-03-10T23:31:19.690Z",
- "mb-markdown_obsidian": "2024-03-10T23:31:20.859Z"
+ "markdown_obsidian": "2024-03-11T03:36:54.266Z",
+ "mb-markdown_obsidian": "2024-03-11T03:36:55.445Z"
}
\ No newline at end of file
diff --git a/src/formats/markdownObsidian.ts b/src/formats/markdownObsidian.ts
index 3ae59aa..940fa9e 100644
--- a/src/formats/markdownObsidian.ts
+++ b/src/formats/markdownObsidian.ts
@@ -4,9 +4,23 @@ import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import remarkStringify from "remark-stringify";
-import { Root } from "mdast";
+import {
+ Heading,
+ InlineCode,
+ List,
+ Node,
+ Parent,
+ Root,
+ RootContent,
+ Strong,
+ TableCell,
+ TableRow,
+ Text,
+} from "mdast";
import { toString } from "mdast-util-to-string";
import { visit, EXIT } from "unist-util-visit";
+import { visitParents } from "unist-util-visit-parents";
+import slugify from "slugify";
import {
DocType,
@@ -18,6 +32,58 @@ import {
getAndDeletePreviousMarkdown,
} from "../utils/markdown.js";
+function updateRollableTable(
+ node: Parent,
+ ancestors: Parent[],
+ tableIds: Set
+): string {
+ // Look through previous siblings to get the first heading
+ let heading: Node | undefined;
+ const highestAncestor = ancestors[ancestors.length - 1];
+ visit(highestAncestor, "heading", (headingNode) => {
+ if (
+ (headingNode.position?.end.offset ?? 0) <
+ (node.position?.start.offset ?? 0)
+ ) {
+ heading = headingNode;
+ } else {
+ return EXIT;
+ }
+ });
+
+ let tableId = "";
+ if (!heading) {
+ tableId = "table";
+ } else {
+ tableId = slugify.default(toString(heading), {
+ lower: true,
+ strict: true,
+ });
+ }
+
+ let tableIncrement = 1;
+ const baseTableId = tableId;
+ while (tableIds.has(tableId)) {
+ tableId = baseTableId + tableIncrement;
+ tableIncrement++;
+ }
+
+ tableIds.add(tableId);
+
+ const indexOfSelf = ancestors[0].children.indexOf(node as RootContent);
+ ancestors[0].children.splice(indexOfSelf + 1, 0, {
+ type: "paragraph",
+ children: [
+ {
+ type: "text",
+ value: `^${tableId}`,
+ },
+ ],
+ });
+
+ return tableId;
+}
+
export async function convertToMarkdownObsidian(
docType: DocType,
html: string
@@ -70,8 +136,9 @@ export async function convertToMarkdownObsidian(
obsidianMarkdownFiles.push(markdownFilePath);
}
- // Second pass over files to update links
+ // Second pass over files to update links and process tables/ordered lists
for (const file of obsidianMarkdownFiles) {
+ const tableIds = new Set();
const markdownFileContent = fs.readFileSync(file, "utf8");
const linkUpdaterPlugin = () => {
@@ -91,15 +158,134 @@ export async function convertToMarkdownObsidian(
};
};
+ const addRollingToTablePlugin = () => {
+ return (tree: Root) => {
+ const diceRolls: {
+ diceRoll: string;
+ parent: Parent;
+ table: Parent;
+ headings: string[];
+ }[] = [];
+
+ visitParents(tree, "table", (node: Parent, ancestors: Parent[]) => {
+ const headingRow = node.children[0] as TableRow;
+ const headings = headingRow.children.map((cell) =>
+ toString(cell as TableCell)
+ );
+ const cell0 = headings.shift(); // Remove the dice roll column
+
+ if (!cell0?.match(/^\d*d[0-9]+$/)) {
+ // Not a dice roll column
+ return;
+ }
+
+ const tableId = updateRollableTable(node, ancestors, tableIds);
+ const diceRoll = `dice: [[${path.basename(
+ file,
+ ".md"
+ )}#^${tableId}]]`;
+
+ diceRolls.push({
+ diceRoll,
+ parent: ancestors[0],
+ table: node,
+ headings,
+ });
+ });
+
+ for (const { diceRoll, parent, table, headings } of diceRolls) {
+ const indexOfSelf = parent.children.indexOf(table as RootContent);
+
+ const paragraphChildren: (Text | InlineCode | Strong)[] = [];
+ for (let i = 0; i < headings.length; i++) {
+ paragraphChildren.push({
+ type: "strong",
+ children: [
+ {
+ type: "text",
+ value: `${headings[i]}: `,
+ },
+ ],
+ });
+ paragraphChildren.push({
+ type: "inlineCode",
+ value: `${diceRoll}|${headings[i]}`,
+ });
+ if (i < headings.length - 1) {
+ paragraphChildren.push({
+ type: "text",
+ value: " \n",
+ });
+ }
+ }
+
+ parent.children.splice(indexOfSelf, 0, {
+ type: "paragraph",
+ children: paragraphChildren,
+ });
+ }
+ };
+ };
+
+ const addRollingToListPlugin = () => {
+ return (tree: Root) => {
+ const diceRolls: {
+ diceRoll: string;
+ parent: Parent;
+ list: Parent;
+ }[] = [];
+
+ visitParents(tree, "list", (node: Parent, ancestors: Parent[]) => {
+ if (!(node as List).ordered) return;
+
+ const tableId = updateRollableTable(node, ancestors, tableIds);
+ const diceRoll = `dice: [[${path.basename(
+ file,
+ ".md"
+ )}#^${tableId}]]`;
+
+ diceRolls.push({ diceRoll, parent: ancestors[0], list: node });
+ });
+
+ for (const { diceRoll, parent, list } of diceRolls) {
+ const indexOfSelf = parent.children.indexOf(list as RootContent);
+ parent.children.splice(indexOfSelf, 0, {
+ type: "paragraph",
+ children: [
+ {
+ type: "inlineCode",
+ value: diceRoll,
+ },
+ ],
+ });
+ }
+ };
+ };
+
+ const removeH1Plugin = () => {
+ return (tree: Root) => {
+ visitParents(tree, "heading", (node: Heading, ancestors: Parent[]) => {
+ if (node.depth === 1) {
+ const indexOfSelf = ancestors[0].children.indexOf(node);
+ ancestors[0].children.splice(indexOfSelf, 1);
+ }
+ });
+ };
+ };
+
const data = await unified()
.use(remarkParse)
.use(remarkGfm)
.use(linkUpdaterPlugin)
+ .use(addRollingToTablePlugin)
+ .use(addRollingToListPlugin)
+ .use(removeH1Plugin)
.use(remarkStringify)
.process(markdownFileContent);
- fs.writeFileSync(file, data.toString());
- newMarkdown += "\n" + data.toString();
+ const content = data.toString().replace(/ /g, " ");
+ fs.writeFileSync(file, content);
+ newMarkdown += "\n" + content;
}
process.stdout.write("Done\n");
diff --git a/src/package-lock.json b/src/package-lock.json
index fe5c6b9..3d51834 100644
--- a/src/package-lock.json
+++ b/src/package-lock.json
@@ -28,6 +28,7 @@
"tsx": "^4.6.2",
"unified": "^11.0.4",
"unist-util-visit": "^5.0.0",
+ "unist-util-visit-parents": "^6.0.1",
"word-wrap": "^1.2.5"
},
"devDependencies": {
diff --git a/src/package.json b/src/package.json
index fbb32af..f75f819 100644
--- a/src/package.json
+++ b/src/package.json
@@ -45,6 +45,7 @@
"tsx": "^4.6.2",
"unified": "^11.0.4",
"unist-util-visit": "^5.0.0",
+ "unist-util-visit-parents": "^6.0.1",
"word-wrap": "^1.2.5"
}
}