| KINGDOM | Valeska | Bresinga | Velanus | Faldin | Odan |
|---|---|---|---|---|---|
| MONARCH | Buried King Endrin | King Avvar | King Brashen | Queen Hest | King Unadin |
# Kingdom of Valeska
Kingdom of Valeska
Overview
Valeska is the capital city, and still termed a kingdom, ruled by the Buried King, which is currently King Endrin.
Buried King
Buried King
The Buried King is the head of state of United Kingdom of Valammar and rules from Valeska.
The Buried King rotates every 5 years and must remain in Valeska for the rest of their life, unless a Desolation occurs.
The Buried King is the commander in chief of the Legion of the Dead.
Link to originalDistricts
Areas & Points of Interest
Valeska
Valeska
Overview
Valeska is the capital city, and still termed a kingdom, ruled by the Buried King, which is currently King Endrin.
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Old City
Military District
The Cross
Amberwind Forges
Middle Pass
Ironwood District
Stonerise Town
Starfall
Link to originalBeer Ring
Political Landscape
Allies
Groups this faction supports or is supported by.
- None
Rivals
Groups this faction is at odds with or actively sabotaging.
- None
Hierarchy & Agents
Direct Members
Link to originalBeholden Sub-Groups
- None
# Kingdom of Bresinga
Kingdom of Bresinga
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
Districts
Areas & Points of Interest
# Adamant
Transclude of Adamant# Alcombey
Alcombey
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
Districts
Areas & Points of Interest
Longwalk
Nooncliff
Upper Ward
Ratbrook
West Gate
South Road
Link to originalGrey Stair
# Ardglass
Ardglass
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Light Tower
Fortress
Raven Rock
The Markets
West Gate
Link to originalSailor's Gate
# Cragpass
Cragpass
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Old Town
Beertown
Castle
South Road
Dairy House
Elm Road
Link to originalNarrow Chapel
# Gunzir
Gunzir
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Old Town
Three Crosses
East Ward
Greenchapel
Upper District
South Gate
Sunbowl
Saltrock
Link to originalWoolstar
Political Landscape
Allies
Groups this faction supports or is supported by.
- None
Rivals
Groups this faction is at odds with or actively sabotaging.
- None
Hierarchy & Agents
Direct Members
Link to originalBeholden Sub-Groups
- None
# Kingdom of Velanus
Kingdom of Velanus
Overview
The United Kingdom of Valammar is the several century old union of the formerly sovereign dwarven nations. These nations remain largely autonomous regions to the present day, the hereditary ruler of which retains their royal title. Each of the four extant rulers serve as the Buried King every 5 years. The Buried King is the commander in chief of the Legion of the Dead and head of state. The Buried King will not see the surface during their service with the sole exception of a Desolation. The Legion of the Dead are warriors who swore a lifelong oath to defend Valammar from the continual Illithid incursions. Any visiting rulers or dignitaries who seek an audience must journey below to the last remaining city, Valeska, of the once great dwarven demesne.
Districts
Areas & Points of Interest
Icemeet
Icemeet
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Copper Field
Fortress
Soldiers Crossing
Cattlemill
Two Towers
Link to originalCotton Crown
Leeside
Leeside
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Trade District
Farsprawl
The Docks
Stormspring
Northgate
Forest Wood
Clearreach
Fortress
Dawnhook
Link to originalBreadknot
Political Landscape
Allies
Groups this faction supports or is supported by.
- None
Rivals
Groups this faction is at odds with or actively sabotaging.
- None
Hierarchy & Agents
Direct Members
Link to originalBeholden Sub-Groups
- None
# Kingdom of Faldin
Kingdom of Faldin
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
Districts
Areas & Points of Interest
Taedmorden
Taedmorden
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Old Town
Citadel
Richar's Way
Southgate
Cabbage Meadow
Blackgate
Widemire
Link to originalNorth Ward
Political Landscape
Allies
Groups this faction supports or is supported by.
- None
Rivals
Groups this faction is at odds with or actively sabotaging.
- None
Hierarchy & Agents
Direct Members
Link to originalBeholden Sub-Groups
- None
# Kingdom of Odan
Kingdom of Odan
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
Districts
Areas & Points of Interest
Frostford
Frostford
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
North Town
Castle
The Docks
Fogknot
Ratrow
Murky Way
Cheeselane
Potters Wood
Link to originalMilloven's Gate
Therinfal
Therinfal
Overview
(A brief 1-2 sentence description of the location’s vibe or history.)
let current = dv.current(); let title = current.file?.name || current.name || ""; // 0. Suppress artwork search on template notes if (title.toLowerCase().includes("template")) { dv.paragraph(`*(Location / Building Image Preview)*`); } else { // 1. Gather all potential names (Title, quoted nicknames, and Obsidian Aliases) let rawNames = [title]; // Extract quoted nickname if present in title (e.g. Holy Dominion "Estwatch" -> Estwatch) let matchNick = title.match(/"([^"]+)"/); if (matchNick && matchNick[1]) { rawNames.push(matchNick[1]); } // Pull aliases safely let aliases = current.file?.aliases || current.aliases || []; if (typeof aliases === "string") { rawNames.push(aliases); } else if (Array.isArray(aliases) || (aliases && typeof aliases[Symbol.iterator] === "function")) { for (let a of aliases) { if (a && typeof a === "string") rawNames.push(a); } } // 2. Build sanitized search terms let searchTerms = new Set(); for (let name of rawNames) { if (!name || typeof name !== "string") continue; let lower = name.toLowerCase().trim().replace(/["']/g, ""); let slug = lower.replace(/[\s-]+/g, "_").replace(/^_+|_+$ /g, ""); if (lower.length >= 2) searchTerms.add(lower); if (slug.length >= 2) searchTerms.add(slug); } // 3. Search target folders for matching image files (.png, .webp, .jpg, etc.) let imageFolders = ["Images/Locations", "Image/Locations", "Images/Buildings", "Image/Buildings"]; let fallbackImage = ""; let matches = app.vault.getFiles().filter(f => { let pathLower = f.path.toLowerCase(); let inTargetFolder = imageFolders.some(folder => pathLower.includes(folder.toLowerCase())); if (!inTargetFolder) return false; if (fallbackImage && pathLower.includes(fallbackImage.toLowerCase())) return false; let imgName = f.name.toLowerCase(); return Array.from(searchTerms).some(term => term && imgName.includes(term)); }); // 4. Select match (prioritize "settlement", "overview", "cover", or "map", otherwise take the first file) let match = matches.find(f => { let nameLower = f.name.toLowerCase(); return nameLower.includes("settlement") || nameLower.includes("overview") || nameLower.includes("cover") || nameLower.includes("map"); }) || (matches.length > 0 ? matches[0] : null); // 5. Render artwork, fallback image, or clean message if (match && match.path) { dv.paragraph(`![[${match.path}|cover]]`); } else { let fallbackFile = null; if (fallbackImage && fallbackImage.trim() !== "") { let cleanFB = fallbackImage.toLowerCase().trim(); fallbackFile = app.vault.getFiles().find(f => f.path.toLowerCase() === cleanFB || f.path.toLowerCase().includes(cleanFB) || f.name.toLowerCase().includes(cleanFB) ); } if (fallbackFile && fallbackFile.path) { dv.paragraph(`![[${fallbackFile.path}|cover]]`); } else { dv.paragraph(`*No map or illustration found for ${title}*`); } } }Districts
Areas & Points of Interest
Old Therinfal
Castle
West Gate
Greatarch
Link to originalHoney Crown
Political Landscape
Allies
Groups this faction supports or is supported by.
- None
Rivals
Groups this faction is at odds with or actively sabotaging.
- None
Hierarchy & Agents
Direct Members
Link to originalBeholden Sub-Groups
- None









