Isaiahsouf
Add 2 files
cce2ad8 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Faerûn City Generator</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Fauna+One&display=swap">
<style>
body {
font-family: 'Fauna One', serif;
background-color: #f0e6d2;
color: #3a3226;
background-image: url('https://www.transparenttextures.com/patterns/parchment.png');
}
.title-font {
font-family: 'Cinzel', serif;
text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
}
.card {
transition: all 0.3s ease;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
background-color: rgba(255, 253, 245, 0.85);
border: 1px solid #d4c9a8;
border-radius: 8px;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
.progress-bar {
height: 8px;
border-radius: 4px;
background-color: #e0d6b8;
overflow: hidden;
}
.progress-fill {
height: 100%;
transition: width 0.6s ease;
}
.fade-in {
animation: fadeIn 0.8s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.race-bar {
height: 20px;
border-radius: 4px;
margin-bottom: 8px;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.2);
}
.header-bg {
background: linear-gradient(to right, #5c3c20, #8b5a2b);
border-bottom: 3px solid #3a2a1b;
}
.generate-btn {
background: linear-gradient(to bottom, #8b5a2b, #5c3c20);
border: 2px solid #3a2a1b;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
letter-spacing: 1px;
}
.generate-btn:hover {
background: linear-gradient(to bottom, #9d6b3b, #6d4c30);
transform: translateY(-2px);
}
.section-title {
border-bottom: 2px solid #d4c9a8;
color: #5c3c20;
}
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted #5c3c20;
cursor: help;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 200px;
background-color: #3a3226;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -100px;
opacity: 0;
transition: opacity 0.3s;
font-size: 14px;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
.notable-feature {
display: inline-block;
background-color: #e8dfc8;
border-radius: 15px;
padding: 2px 10px;
margin: 2px;
font-size: 0.9em;
border: 1px solid #d4c9a8;
}
</style>
</head>
<body class="bg-amber-50">
<div class="container mx-auto px-4 py-8 max-w-6xl">
<header class="text-center mb-12">
<h1 class="title-font text-5xl font-bold mb-2 text-amber-900">Faerûn City Generator</h1>
<p class="text-amber-800 text-lg">Forge unique settlements for your Forgotten Realms adventures</p>
</header>
<div class="flex justify-center mb-8">
<button id="generateBtn" class="generate-btn text-white font-bold py-3 px-8 rounded-lg shadow-lg transition duration-300 hover:shadow-xl animate__animated animate__pulse animate__infinite">
Forge a New City
</button>
</div>
<div id="cityDisplay" class="bg-white rounded-xl shadow-lg overflow-hidden mb-8 hidden fade-in">
<div class="header-bg text-white p-6">
<h2 id="cityName" class="title-font text-4xl font-bold text-amber-100"></h2>
<p id="cityTagline" class="text-amber-200 italic"></p>
</div>
<div class="p-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Overview Card -->
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Overview</h3>
<div class="space-y-3">
<div>
<span class="font-semibold text-amber-900">Population:</span>
<span id="population" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Size:</span>
<span id="citySize" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Population Density:</span>
<span id="density" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Location:</span>
<span id="location" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Government:</span>
<span id="government" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Languages:</span>
<span id="languages" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Founded:</span>
<span id="founded" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Current Age:</span>
<span id="currentAge" class="text-amber-800"></span>
</div>
</div>
</div>
</div>
<!-- Demographics Card -->
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Demographics</h3>
<div id="raceDemographics" class="space-y-2">
<!-- Race percentages will be inserted here -->
</div>
<div class="mt-4">
<span class="font-semibold text-amber-900">Social Strata:</span>
<span id="socialStrata" class="text-amber-800"></span>
</div>
<div class="mt-2">
<span class="font-semibold text-amber-900">Gender Ratio:</span>
<span id="genderRatio" class="text-amber-800"></span>
</div>
</div>
</div>
<!-- Economy Card -->
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Economy</h3>
<div class="space-y-3">
<div>
<span class="font-semibold text-amber-900">Primary Industries:</span>
<span id="industries" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Major Exports:</span>
<span id="exports" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Trade Partners:</span>
<span id="tradePartners" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Wealth Level:</span>
<span id="wealth" class="text-amber-800"></span>
<div class="progress-bar mt-1">
<div id="wealthBar" class="progress-fill bg-green-700"></div>
</div>
</div>
<div>
<span class="font-semibold text-amber-900">Coinage:</span>
<span id="coinage" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Taxation:</span>
<span id="taxation" class="text-amber-800"></span>
</div>
</div>
</div>
</div>
<!-- Architecture Card -->
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Architecture</h3>
<div class="space-y-3">
<div>
<span class="font-semibold text-amber-900">Style:</span>
<span id="architectureStyle" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Notable Features:</span>
<div id="architectureFeatures" class="mt-1 flex flex-wrap">
<!-- Features will be inserted here -->
</div>
</div>
<div>
<span class="font-semibold text-amber-900">Building Materials:</span>
<span id="buildingMaterials" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Fortifications:</span>
<span id="fortifications" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Layout:</span>
<span id="cityLayout" class="text-amber-800"></span>
</div>
</div>
</div>
</div>
<!-- Geography Card -->
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Geography</h3>
<div class="space-y-3">
<div>
<span class="font-semibold text-amber-900">Terrain:</span>
<span id="terrain" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Climate:</span>
<span id="climate" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Water Source:</span>
<span id="waterSource" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Elevation:</span>
<span id="elevation" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Natural Resources:</span>
<span id="naturalResources" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Hazards:</span>
<span id="hazards" class="text-amber-800"></span>
</div>
</div>
</div>
</div>
<!-- Culture Card -->
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Culture</h3>
<div class="space-y-3">
<div>
<span class="font-semibold text-amber-900">Popular Classes:</span>
<span id="popularClasses" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Religions:</span>
<span id="religions" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Crime Level:</span>
<span id="crime" class="text-amber-800"></span>
<div class="progress-bar mt-1">
<div id="crimeBar" class="progress-fill bg-red-700"></div>
</div>
</div>
<div>
<span class="font-semibold text-amber-900">Magic Prevalence:</span>
<span id="magic" class="text-amber-800"></span>
<div class="progress-bar mt-1">
<div id="magicBar" class="progress-fill bg-purple-700"></div>
</div>
</div>
<div>
<span class="font-semibold text-amber-900">Education:</span>
<span id="education" class="text-amber-800"></span>
</div>
<div>
<span class="font-semibold text-amber-900">Cultural Values:</span>
<span id="culturalValues" class="text-amber-800"></span>
</div>
</div>
</div>
</div>
</div>
<!-- City Description -->
<div class="px-6 pb-6">
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">City Description</h3>
<p id="cityDescription" class="text-amber-900 leading-relaxed"></p>
</div>
</div>
</div>
<!-- Notable Locations -->
<div class="px-6 pb-6">
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Notable Locations</h3>
<div id="notableLocations" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Locations will be inserted here -->
</div>
</div>
</div>
</div>
<!-- Current Events -->
<div class="px-6 pb-6">
<div class="card">
<div class="p-6">
<h3 class="section-title text-xl font-bold mb-4 pb-2">Current Events</h3>
<div id="currentEvents" class="space-y-3">
<!-- Events will be inserted here -->
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// Expanded name components for city generation
const prefixes = ["Al", "Bar", "Cal", "Dor", "El", "Fal", "Gor", "Har", "Il", "Jor",
"Kel", "Lor", "Mor", "Nor", "Oth", "Pel", "Quar", "Riv", "Sel", "Tor",
"Ul", "Val", "Wes", "Xan", "Yar", "Zor", "Bel", "Cor", "Dun", "Ere",
"Fen", "Gul", "Hel", "Iri", "Jar", "Kor", "Lun", "Mir", "Nar", "Olo",
"Pir", "Quil", "Ror", "Sar", "Tel", "Uth", "Vor", "Wil", "Xor", "Yil"];
const middles = ["an", "ar", "en", "il", "or", "ur", "ath", "ith", "oth", "esh",
"ish", "osh", "ash", "eth", "yth", "al", "el", "ol", "ul", "ir",
"am", "em", "im", "om", "um", "in", "on", "un", "ad", "ed",
"id", "od", "ud", "ag", "eg", "ig", "og", "ug", "ak", "ek"];
const suffixes = ["dor", "mar", "ton", "ven", "wick", "ford", "stead", "burg", "holm",
"crest", "watch", "spire", "haven", "port", "reach", "rock", "fall",
"glen", "hollow", "keep", "moor", "peak", "ridge", "vale", "wood",
"bridge", "dale", "field", "gate", "hill", "light", "meet", "nest",
"pass", "quay", "rest", "ship", "tower", "wall", "yard", "band",
"cairn", "dell", "earth", "firth", "garde", "hold", "isle", "joust"];
const standalone = ["Duskendale", "Brightwater", "Stormhaven", "Mooncrest", "Dragonfell",
"Silvermarsh", "Goldspire", "Ironford", "Shadowfen", "Highcliff",
"Deepwood", "Fairwind", "Stonebridge", "Blackmoor", "Whitepeak",
"Neverwinter", "Waterdeep", "Baldur's Gate", "Silverymoon", "Mithral Hall",
"Candlekeep", "Secomber", "Daggerford", "Trollbark", "Shadowdale",
"Myth Drannor", "Zhentil Keep", "Hillsfar", "Elventree", "Eveningstar",
"Suzail", "Westgate", "Procampur", "Tantras", "Elturel", "Scornubel",
"Berdusk", "Iriaebor", "Yartar", "Luskan", "Mirabar", "Longsaddle"];
// Expanded location options
const locations = [
"Along the Sword Coast", "In the Dalelands", "Near the Sea of Fallen Stars",
"In the North", "In the Western Heartlands", "In Amn", "In Tethyr",
"In the Silver Marches", "In the Unapproachable East", "In the Shaar",
"On the Moonsea", "In the Vilhon Reach", "In the Lake of Steam region",
"In the Chultan Peninsula", "In the Underdark", "On an island in the Trackless Sea",
"In the High Forest", "In the Anauroch desert", "In the Storm Horns mountains",
"Along the River Chionthar", "Near the Marsh of Chelimber", "In the Graypeak Mountains",
"In the Lurkwood", "On the edge of the High Moor", "In the Delimbiyr Vale",
"Near the Marsh of Dead Men", "In the Trollclaws", "Along the Trade Way",
"In the Sunset Vale", "Near the Stonelands", "In the Vast", "In the Ride",
"In the Tunlands", "Near the Flooded Forest", "In the Border Kingdoms",
"In the Great Dale", "In the Rawlinswood", "In the Forest of Wyrms",
"On the Shining Plains", "In the Hordelands", "In the Endless Wastes"
];
// Expanded government types with subtypes
const governments = [
{type: "Monarchy", subtype: ["Hereditary", "Elected", "Divine Right", "Constitutional"]},
{type: "Council of Merchants", subtype: ["Oligarchy", "Representative", "Corrupt"]},
{type: "Mageocracy", subtype: ["Archmage Rule", "Circle of Magi", "Arcane Senate"]},
{type: "Theocracy", subtype: ["Temple Rule", "Divine Mandate", "Prophet's Word"]},
{type: "Military Dictatorship", subtype: ["Warlord", "Knightly Order", "Mercenary Company"]},
{type: "Oligarchy", subtype: ["Noble Families", "Guild Masters", "Wealthy Elite"]},
{type: "Democracy", subtype: ["Direct", "Representative", "Magically Enforced"]},
{type: "Feudal System", subtype: ["Traditional", "Decentralized", "Oppressive"]},
{type: "Guild-run", subtype: ["Merchant's League", "Artisan Collective", "Thieves' Guild"]},
{type: "Tribal Council", subtype: ["Elders", "Shamans", "Warrior Chiefs"]},
{type: "Magistrate Rule", subtype: ["Appointed", "Elected", "Hereditary"]},
{type: "Undead Overlord", subtype: ["Lich", "Vampire", "Death Knight"]},
{type: "Dragon Rule", subtype: ["Ancient Wyrm", "Dragon Council", "Half-Dragon"]},
{type: "Plutocracy", subtype: ["Wealth-based", "Trade Prince", "Banker's Guild"]},
{type: "Anarchy", subtype: ["True Chaos", "Neighborhood Collectives", "Survival of the Fittest"]},
{type: "Matriarchy", subtype: ["Queen's Rule", "Priestess Council", "Amazonian"]},
{type: "Patriarchy", subtype: ["King's Rule", "Elder Council", "Warrior Code"]},
{type: "Elder Council", subtype: ["Wise Ones", "Ancient Beings", "Immortal Guardians"]},
{type: "Divine Mandate", subtype: ["Chosen One", "Oracle's Word", "Celestial Being"]},
{type: "Secret Society Control", subtype: ["Illuminati", "Shadow Cabal", "Cult Leadership"]}
];
// City sizes with population ranges and descriptions
const citySizes = [
{ name: "Village", population: "100-1,000", desc: "A small, tight-knit community where everyone knows each other" },
{ name: "Small Town", population: "1,000-5,000", desc: "A growing settlement with basic amenities and some specialization" },
{ name: "Large Town", population: "5,000-10,000", desc: "A bustling town with multiple districts and established trade" },
{ name: "Small City", population: "10,000-25,000", desc: "A proper city with walls, guilds, and significant infrastructure" },
{ name: "Medium City", population: "25,000-50,000", desc: "A regional hub with diverse populations and complex politics" },
{ name: "Large City", population: "50,000-100,000", desc: "A major metropolis with international influence and all amenities" },
{ name: "Metropolis", population: "100,000+", desc: "A vast city that dominates the region, rivaling Waterdeep or Calimport" },
{ name: "City-State", population: "Varies", desc: "An independent city that governs surrounding lands" },
{ name: "Floating City", population: "5,000-50,000", desc: "A magical city suspended in the air or on clouds" },
{ name: "Undercity", population: "1,000-20,000", desc: "A subterranean settlement, either by choice or necessity" }
];
// Population densities with descriptions
const densities = [
{name: "Very sparse (rural)", desc: "Spread out farms and homesteads with large distances between buildings"},
{name: "Sparse", desc: "Small clusters of buildings with open spaces between neighborhoods"},
{name: "Moderate", desc: "Reasonable spacing between buildings with some open areas"},
{name: "Dense", desc: "Close-built structures with narrow streets and few open spaces"},
{name: "Very dense (urban)", desc: "Tightly packed buildings with multi-level structures"},
{name: "Extremely dense (crowded)", desc: "Overflowing population with buildings stacked upon each other"},
{name: "Variable (sprawling)", desc: "Mix of dense centers and sparse outskirts"},
{name: "Vertical density", desc: "Population lives in tall towers or deep underground"},
{name: "Nomadic density", desc: "Population moves seasonally between different areas"}
];
// Architecture styles with descriptions
const architectureStyles = [
{name: "Gothic", desc: "Pointed arches, ribbed vaults, and flying buttresses"},
{name: "Romanesque", desc: "Round arches, thick walls, and sturdy pillars"},
{name: "Elven Elegance", desc: "Graceful curves, living wood, and integration with nature"},
{name: "Dwarven Stonework", desc: "Precise masonry, geometric patterns, and underground structures"},
{name: "Moorish", desc: "Intricate geometric designs, horseshoe arches, and lush courtyards"},
{name: "Byzantine", desc: "Domes, mosaics, and a mix of eastern and western influences"},
{name: "Nordic", desc: "Wooden structures, steep roofs, and runic decorations"},
{name: "Oriental", desc: "Pagoda-style roofs, paper screens, and zen gardens"},
{name: "Mage-touched", desc: "Floating elements, impossible angles, and glowing runes"},
{name: "Underdark", desc: "Fungal lighting, organic curves, and bioluminescent accents"},
{name: "Pirate-inspired", desc: "Salvaged materials, ship-like structures, and waterfront focus"},
{name: "Naval", desc: "Lighthouse motifs, wave patterns, and sea-worthy construction"},
{name: "Agricultural", desc: "Practical designs, large barns, and irrigation systems"},
{name: "Militaristic", desc: "Defensive structures, barracks-like buildings, and watchtowers"},
{name: "Religious", desc: "Temple-like structures, holy symbols, and sacred geometry"},
{name: "Arcane", desc: "Wizard towers, alchemical labs, and magical enhancements"},
{name: "Decadent", desc: "Overly ornate, gilded everything, and excessive decoration"},
{name: "Ruined", desc: "Partially destroyed but still inhabited, with makeshift repairs"},
{name: "Rebuilt", desc: "New construction atop old ruins, with visible layers of history"},
{name: "Eclectic Mix", desc: "No consistent style, with buildings from many different influences"}
];
// Architecture features (now with descriptors)
const architectureFeatures = [
{name: "Tall spires", desc: "Reaching high into the sky, visible for miles"},
{name: "Underground tunnels", desc: "Connecting buildings beneath the streets"},
{name: "Canals", desc: "Waterways used for transport and drainage"},
{name: "Floating districts", desc: "Sections of the city that hover magically"},
{name: "Tree-top walkways", desc: "Bridges and paths connecting canopy dwellings"},
{name: "Massive walls", desc: "Imposing fortifications that dominate the skyline"},
{name: "Glass domes", desc: "Enormous transparent structures covering districts"},
{name: "Hanging gardens", desc: "Terraced greenery on buildings and walls"},
{name: "Elevated walkways", desc: "Second-story paths keeping pedestrians above the streets"},
{name: "Magical lighting", desc: "Ever-burning lamps or floating light orbs"},
{name: "Flying buttresses", desc: "Architectural supports that look like they're flying"},
{name: "Underground cities", desc: "Vast complexes beneath the surface"},
{name: "Portals to other planes", desc: "Permanent gates to other dimensions"},
{name: "Living buildings", desc: "Structures that grow and change like organisms"},
{name: "Shifting architecture", desc: "Buildings that rearrange themselves periodically"},
{name: "Crystal structures", desc: "Geometric formations of glowing crystal"},
{name: "Bone towers", desc: "Structures built from enormous bones or skeletons"},
{name: "Petrified wood buildings", desc: "Hardened wood that's stone-like in durability"},
{name: "Waterfront docks", desc: "Expansive piers and wharves for maritime trade"},
{name: "Multi-level city", desc: "Districts stacked vertically with bridges between"}
];
// Building materials with descriptors
const buildingMaterials = [
{name: "Stone", desc: "Quarried rock, durable and fireproof"},
{name: "Wood", desc: "Local timber, warm but flammable"},
{name: "Brick", desc: "Fired clay, uniform and sturdy"},
{name: "Marble", desc: "Luxurious stone with beautiful veining"},
{name: "Crystal", desc: "Magically grown or naturally formed"},
{name: "Magically reinforced", desc: "Enhanced to be stronger than normal"},
{name: "Living plants", desc: "Still growing and requiring maintenance"},
{name: "Bone", desc: "From large creatures or magical sources"},
{name: "Obsidian", desc: "Volcanic glass, sharp and dark"},
{name: "Metal", desc: "Expensive but extremely durable"},
{name: "Petrified wood", desc: "Ancient wood turned to stone"},
{name: "Ice", desc: "Magically preserved or in cold climates"},
{name: "Adobe", desc: "Sun-dried earth bricks"},
{name: "Thatch", desc: "Dried vegetation for roofing"},
{name: "Mud brick", desc: "Simple and inexpensive"},
{name: "Glass", desc: "For windows or entire structures"},
{name: "Compacted earth", desc: "Rammed into solid forms"},
{name: "Coral", desc: "Harvested from reefs or magically grown"},
{name: "Fungal growth", desc: "Living fungus shaped into structures"},
{name: "Unknown alien material", desc: "From other planes or worlds"}
];
// Fortifications with descriptors
const fortifications = [
{name: "None", desc: "Completely open and undefended"},
{name: "Simple wooden palisade", desc: "Basic defense against small threats"},
{name: "Stone walls", desc: "Standard city defenses"},
{name: "High walls with towers", desc: "Imposing defenses with lookout points"},
{name: "Massive walls with magical defenses", desc: "Nearly impregnable fortifications"},
{name: "Citadel at center", desc: "Last bastion of defense if outer walls fall"},
{name: "Multiple layered walls", desc: "Successive rings of defense"},
{name: "Floating defensive platforms", desc: "Magically suspended guard posts"},
{name: "Underground bunkers", desc: "Hidden shelters beneath the city"},
{name: "Maze-like streets designed for defense", desc: "Confusing layout to slow invaders"},
{name: "Living walls of thorny plants", desc: "Natural barriers that grow back"},
{name: "Animated statues", desc: "Construct guardians that come to life"},
{name: "Elemental guardians", desc: "Bound elemental beings that defend the city"},
{name: "Glyphs and wards", desc: "Magical protections against specific threats"},
{name: "Moat with drawbridges", desc: "Water defenses with controlled access"},
{name: "Cliffside defenses", desc: "Natural terrain enhanced with fortifications"},
{name: "Hidden escape tunnels", desc: "Secret routes out of the city"},
{name: "Magical barrier", desc: "Invisible force field surrounding the city"},
{name: "Dimensional locks", desc: "Preventing teleportation or planar travel"},
{name: "Dragon perches", desc: "Towers designed for dragon allies to land on"}
];
// Terrain types with descriptors
const terrains = [
{name: "Plains", desc: "Flat open land with good visibility"},
{name: "Hills", desc: "Rolling terrain with some elevation changes"},
{name: "Mountains", desc: "Steep slopes and high altitudes"},
{name: "Forest", desc: "Dense tree cover limiting visibility"},
{name: "Jungle", desc: "Lush, overgrown vegetation and high humidity"},
{name: "Desert", desc: "Arid landscape with extreme temperatures"},
{name: "Tundra", desc: "Frozen plains with permafrost"},
{name: "Swamp", desc: "Wetlands with standing water and muddy ground"},
{name: "Coastal", desc: "Along a sea or ocean with maritime influence"},
{name: "Island", desc: "Surrounded by water on all sides"},
{name: "Underground", desc: "Beneath the surface in caves or caverns"},
{name: "Floating", desc: "Suspended in air or water by magic or technology"},
{name: "Cliffside", desc: "Built into or on the side of steep cliffs"},
{name: "Volcanic", desc: "Near active or dormant volcanoes"},
{name: "Marsh", desc: "Wet, boggy ground with reeds and grasses"},
{name: "River delta", desc: "Where a river splits into many channels"},
{name: "Plateau", desc: "Elevated flat terrain with steep sides"},
{name: "Canyon", desc: "Deep gorge with steep walls"},
{name: "Fey-touched", desc: "Landscape altered by Feywild influence"},
{name: "Shadow-infused", desc: "Darkened by Shadowfell energy"}
];
// Climates with descriptors
const climates = [
{name: "Temperate", desc: "Moderate with four distinct seasons"},
{name: "Cold", desc: "Long winters and short summers"},
{name: "Warm", desc: "Hot summers and mild winters"},
{name: "Arid", desc: "Dry with little precipitation"},
{name: "Humid", desc: "Moist air and frequent rainfall"},
{name: "Frigid", desc: "Permanently cold with ice and snow"},
{name: "Tropical", desc: "Hot and wet year-round"},
{name: "Mediterranean", desc: "Hot dry summers and cool wet winters"},
{name: "Magically altered", desc: "Climate controlled by arcane means"},
{name: "Variable", desc: "Changes unpredictably or frequently"},
{name: "Eternal spring", desc: "Perpetually mild and flowering"},
{name: "Perpetual autumn", desc: "Always harvest-like with falling leaves"},
{name: "Controlled by magic", desc: "Weather regulated by spellcasters"},
{name: "Storm-wracked", desc: "Frequent thunderstorms or tempests"},
{name: "Fog-shrouded", desc: "Persistent mists and low visibility"},
{name: "Dusty", desc: "Dry with frequent dust storms"},
{name: "Misty", desc: "Light fog common throughout the year"},
{name: "Rainy", desc: "Frequent precipitation of all types"},
{name: "Windy", desc: "Constant strong breezes or gales"},
{name: "Strange planar influences", desc: "Climate affected by other planes"}
];
// Water sources with descriptors
const waterSources = [
{name: "River", desc: "Flowing freshwater source"},
{name: "Lake", desc: "Large standing body of water"},
{name: "Oasis", desc: "Isolated water in arid regions"},
{name: "Underground springs", desc: "Water rising from below"},
{name: "Magical creation", desc: "Conjured or created water"},
{name: "Rain collection", desc: "Gathered from precipitation"},
{name: "Desalination", desc: "Saltwater made drinkable"},
{name: "Ice melt", desc: "From glaciers or permanent snow"},
{name: "Portals to elemental plane of water", desc: "Endless pure water"},
{name: "Condensation towers", desc: "Devices that pull moisture from air"},
{name: "Aqueducts", desc: "Engineered water transport"},
{name: "Wells", desc: "Dug deep to reach groundwater"},
{name: "Artesian springs", desc: "Naturally pressurized water"},
{name: "Tidal flows", desc: "Using ocean tides for fresh water"},
{name: "Living water creatures", desc: "Elementals or other beings provide water"},
{name: "Divine blessing", desc: "Provided by deities or celestials"},
{name: "Elemental binding", desc: "Water elementals compelled to provide"},
{name: "Dew collectors", desc: "Gathering morning condensation"},
{name: "Cloud siphoning", desc: "Pulling water directly from clouds"},
{name: "Alchemical processes", desc: "Creating water through magic or science"}
];
// Elevations with descriptors
const elevations = [
{name: "Sea level", desc: "At or near the ocean's surface"},
{name: "Lowlands", desc: "Slightly above sea level"},
{name: "Hills", desc: "Moderate elevation changes"},
{name: "Mountainous", desc: "High altitude location"},
{name: "Underground", desc: "Below the surface"},
{name: "Floating", desc: "Above ground level"},
{name: "Cliffside", desc: "On the face of steep drops"},
{name: "Valley", desc: "Surrounded by higher elevations"},
{name: "Plateau", desc: "Elevated flat area"},
{name: "Canyon", desc: "Below ground level between cliffs"},
{name: "Suspended in trees", desc: "Built among giant trees"},
{name: "Built into a giant creature", desc: "On or in a colossal being"},
{name: "Flying", desc: "Constantly airborne"},
{name: "On a massive bridge", desc: "Spanning a chasm or river"},
{name: "In a crater", desc: "Within a massive impact site"},
{name: "On a glacier", desc: "Moving slowly with the ice"},
{name: "On a massive tree", desc: "In the branches of a single enormous tree"},
{name: "On a giant mushroom", desc: "Fungal platform high above ground"},
{name: "On a floating island", desc: "Landmass suspended in air"},
{name: "In a massive geode", desc: "Within a crystal-lined cavern"}
];
// Industries with descriptors
const industries = [
{name: "Agriculture", desc: "Farming crops and livestock"},
{name: "Mining", desc: "Extracting minerals and ores"},
{name: "Fishing", desc: "Harvesting from seas, rivers, or lakes"},
{name: "Lumber", desc: "Forestry and wood products"},
{name: "Textiles", desc: "Cloth and clothing production"},
{name: "Metalworking", desc: "Blacksmithing and metal goods"},
{name: "Shipbuilding", desc: "Constructing maritime vessels"},
{name: "Magic items", desc: "Creating enchanted objects"},
{name: "Alchemy", desc: "Potions and chemical products"},
{name: "Glassmaking", desc: "Glassware and windows"},
{name: "Pottery", desc: "Ceramic goods and tiles"},
{name: "Weapons", desc: "Arms manufacturing"},
{name: "Armor", desc: "Protective gear production"},
{name: "Spices", desc: "Growing or trading in seasonings"},
{name: "Wine", desc: "Viticulture and winemaking"},
{name: "Livestock", desc: "Animal husbandry"},
{name: "Hunting", desc: "Game and fur procurement"},
{name: "Trapping", desc: "Capturing animals for various uses"},
{name: "Fur trade", desc: "Pelts and leather goods"},
{name: "Slave trade", desc: "Unfortunate but profitable"},
{name: "Information brokering", desc: "Selling knowledge and secrets"},
{name: "Smuggling", desc: "Illicit transport of goods"},
{name: "Piracy", desc: "Maritime raiding and theft"},
{name: "Mercenary work", desc: "Selling martial services"},
{name: "Art", desc: "Creative works and craftsmanship"}
];
// Exports with descriptors
const exports = [
{name: "Grain", desc: "Staple crops for food"},
{name: "Ore", desc: "Unrefined mineral resources"},
{name: "Fish", desc: "Fresh or preserved seafood"},
{name: "Timber", desc: "Lumber and wood products"},
{name: "Cloth", desc: "Textiles and fabrics"},
{name: "Metal goods", desc: "Tools, weapons, and implements"},
{name: "Ships", desc: "Seaworthy vessels"},
{name: "Magic items", desc: "Enchanted objects of all kinds"},
{name: "Potions", desc: "Alchemical concoctions"},
{name: "Glassware", desc: "Decorative and practical glass"},
{name: "Ceramics", desc: "Pottery and tilework"},
{name: "Weapons", desc: "From simple to masterwork"},
{name: "Armor", desc: "Protective gear of all types"},
{name: "Spices", desc: "Exotic flavorings"},
{name: "Wine", desc: "Fine vintages and table wines"},
{name: "Livestock", desc: "Live animals for various purposes"},
{name: "Furs", desc: "Pelts and hides"},
{name: "Slaves", desc: "Unfortunate sentient trade"},
{name: "Information", desc: "Secrets and intelligence"},
{name: "Art", desc: "Paintings, sculptures, and more"},
{name: "Exotic animals", desc: "Unusual creatures for menageries"},
{name: "Rare plants", desc: "Botanical specimens"},
{name: "Ancient artifacts", desc: "Relics of past civilizations"},
{name: "Spell components", desc: "Magical ingredients"},
{name: "Mercenaries", desc: "Skilled warriors for hire"}
];
// Trade partners with descriptors
const tradePartners = [
{name: "Waterdeep", desc: "City of Splendors"},
{name: "Baldur's Gate", desc: "Bustling port city"},
{name: "Neverwinter", desc: "City of Skilled Hands"},
{name: "Silverymoon", desc: "Gem of the North"},
{name: "Mirabar", desc: "Mountain fortress city"},
{name: "Luskan", desc: "City of Sails"},
{name: "Calimport", desc: "Southern trade hub"},
{name: "Athkatla", desc: "Amnian trade capital"},
{name: "Suzail", desc: "Cormyrian royal city"},
{name: "Westgate", desc: "City of Merchants"},
{name: "Zhentil Keep", desc: "Mercantile power"},
{name: "Hillsfar", desc: "Red Plume city"},
{name: "Mulmaster", desc: "City of Danger"},
{name: "Phlan", desc: "Reborn city"},
{name: "Elturgard", desc: "Shining crusader state"},
{name: "Daggerford", desc: "Small but strategic"},
{name: "Secomber", desc: "River trade town"},
{name: "Tethyr", desc: "Reborn kingdom"},
{name: "Amn", desc: "Merchant kingdom"},
{name: "Thay", desc: "Red Wizards' domain"},
{name: "Underdark cities", desc: "Drow and duergar metropolises"},
{name: "Elven settlements", desc: "Hidden enclaves"},
{name: "Dwarven strongholds", desc: "Mountain citadels"},
{name: "Gnomish enclaves", desc: "Innovative communities"},
{name: "Dragonmarked houses", desc: "Eberron's mercantile powers"}
];
// Wealth levels with descriptors
const wealthLevels = [
{name: "Destitute", desc: "Most live in poverty", value: 1},
{name: "Poor", desc: "Struggling to get by", value: 2},
{name: "Modest", desc: "Basic needs met", value: 3},
{name: "Comfortable", desc: "Some luxuries available", value: 4},
{name: "Wealthy", desc: "Prosperous with trade", value: 5},
{name: "Very wealthy", desc: "Significant surplus", value: 6},
{name: "Extremely wealthy", desc: "Regional economic power", value: 7},
{name: "Decadently rich", desc: "Almost unimaginable wealth", value: 8}
];
// Popular classes with descriptors
const popularClasses = [
{name: "Fighters", desc: "Martial warriors of all types"},
{name: "Rogues", desc: "Sneaks and thieves"},
{name: "Wizards", desc: "Learned spellcasters"},
{name: "Clerics", desc: "Divine servants"},
{name: "Rangers", desc: "Wilderness experts"},
{name: "Paladins", desc: "Holy warriors"},
{name: "Druids", desc: "Nature's guardians"},
{name: "Bards", desc: "Artists and lorekeepers"},
{name: "Barbarians", desc: "Fierce warriors"},
{name: "Monks", desc: "Disciplined martial artists"},
{name: "Sorcerers", desc: "Innate spellcasters"},
{name: "Warlocks", desc: "Pact-bound magic users"},
{name: "Artificers", desc: "Magical inventors"},
{name: "Blood hunters", desc: "Monster slayers"},
{name: "Psions", desc: "Mind mages"}
];
// Religions with descriptors
const religions = [
{name: "Worship of the Seldarine (elven pantheon)", desc: "Corellon, Sehanine, and others"},
{name: "Moradin and the dwarven pantheon", desc: "Dwarven gods of crafting and war"},
{name: "The Triad (Tyr, Torm, Ilmater)", desc: "Law, justice, and endurance"},
{name: "The Moonmaiden (Selûne)", desc: "Goddess of the moon"},
{name: "The Morninglord (Lathander)", desc: "God of dawn and renewal"},
{name: "The Dead Three (Bane, Bhaal, Myrkul)", desc: "Gods of tyranny, murder, and death"},
{name: "Mystra's faith", desc: "Goddess of magic"},
{name: "The Red Knight", desc: "Goddess of strategy"},
{name: "Tempus", desc: "God of war"},
{name: "Gond", desc: "God of craft"},
{name: "Oghma", desc: "God of knowledge"},
{name: "Chauntea", desc: "Goddess of agriculture"},
{name: "Sune", desc: "Goddess of love and beauty"},
{name: "Shar", desc: "Goddess of darkness"},
{name: "Cyric", desc: "God of lies"},
{name: "Talos", desc: "God of storms"},
{name: "Local deity", desc: "Unique to this region"},
{name: "Primordial worship", desc: "Elemental powers"},
{name: "Dragon cult", desc: "Veneration of dragonkind"},
{name: "Demon worship", desc: "Dark and dangerous"},
{name: "No organized religion", desc: "Secular or individual spirituality"}
];
// Crime levels with descriptors
const crimeLevels = [
{name: "Virtually nonexistent", desc: "Almost perfectly lawful", value: 1},
{name: "Very low", desc: "Occasional petty crimes", value: 2},
{name: "Low", desc: "Some theft and minor offenses", value: 3},
{name: "Moderate", desc: "Regular criminal activity", value: 4},
{name: "High", desc: "Dangerous in some areas", value: 5},
{name: "Very high", desc: "Gangs and organized crime", value: 6},
{name: "Rampant", desc: "Lawlessness common", value: 7},
{name: "Controlled by thieves' guilds", desc: "Criminal organizations rule", value: 8},
{name: "Organized crime rules", desc: "Outlaws hold real power", value: 9},
{name: "Anarchy", desc: "No effective law enforcement", value: 10}
];
// Magic prevalence with descriptors
const magicLevels = [
{name: "Nonexistent", desc: "Magic is feared or unknown", value: 1},
{name: "Very rare", desc: "Few practitioners", value: 2},
{name: "Uncommon", desc: "Present but not widespread", value: 3},
{name: "Common", desc: "Used in daily life", value: 4},
{name: "Widespread", desc: "Integrated into society", value: 5},
{name: "Very common", desc: "Most people benefit", value: 6},
{name: "Ubiquitous", desc: "Affects nearly everything", value: 7},
{name: "Arcane city", desc: "Built on magical principles", value: 8},
{name: "Magocracy", desc: "Mages rule directly", value: 9},
{name: "Magical experiments everywhere", desc: "Constant arcane innovation", value: 10}
];
// Races with color coding and descriptors
const races = [
{ name: "Humans", color: "bg-blue-700", desc: "Adaptable and ambitious" },
{ name: "Elves", color: "bg-green-700", desc: "Graceful and long-lived" },
{ name: "Dwarves", color: "bg-yellow-700", desc: "Sturdy and traditional" },
{ name: "Halflings", color: "bg-red-700", desc: "Cheerful and nimble" },
{ name: "Gnomes", color: "bg-purple-700", desc: "Inventive and curious" },
{ name: "Half-Elves", color: "bg-indigo-700", desc: "Diplomatic and versatile" },
{ name: "Half-Orcs", color: "bg-orange-700", desc: "Strong and resilient" },
{ name: "Tieflings", color: "bg-pink-700", desc: "Fiend-touched outsiders" },
{ name: "Dragonborn", color: "bg-teal-700", desc: "Draconic heritage" },
{ name: "Aasimar", color: "bg-amber-300", desc: "Celestial-touched" },
{ name: "Genasi", color: "bg-cyan-500", desc: "Elemental heritage" },
{ name: "Firbolgs", color: "bg-gray-400", desc: "Giant-kin forest dwellers" },
{ name: "Goliaths", color: "bg-stone-500", desc: "Mountain-dwelling giants" },
{ name: "Tabaxi", color: "bg-orange-500", desc: "Cat-like wanderers" },
{ name: "Tritons", color: "bg-blue-400", desc: "Underwater nobility" },
{ name: "Other", color: "bg-gray-700", desc: "Various uncommon races" }
];
// Languages with descriptors
const languages = [
{name: "Common", desc: "Trade tongue understood by most"},
{name: "Elvish", desc: "Flowing and poetic"},
{name: "Dwarvish", desc: "Guttural and precise"},
{name: "Halfling", desc: "Cheerful and informal"},
{name: "Gnomish", desc: "Technical and complex"},
{name: "Draconic", desc: "Ancient and powerful"},
{name: "Infernal", desc: "Harsh and commanding"},
{name: "Celestial", desc: "Harmonious and pure"},
{name: "Undercommon", desc: "Underdark trade language"},
{name: "Giant", desc: "Booming and simple"},
{name: "Orcish", desc: "Aggressive and blunt"},
{name: "Abyssal", desc: "Chaotic and disturbing"},
{name: "Primordial", desc: "Elemental languages"},
{name: "Sylvan", desc: "Fey tongue"},
{name: "Deep Speech", desc: "Alien and unsettling"},
{name: "Thieves' Cant", desc: "Secret criminal language"},
{name: "Druidic", desc: "Nature's secret tongue"},
{name: "Sign language", desc: "Gestural communication"},
{name: "Regional dialect", desc: "Local variations"},
{name: "Secret tongue", desc: "Unique to this city"}
];
// Taglines with descriptors
const taglines = [
{text: "Where shadows whisper and gold flows like water.", desc: "A city of intrigue and wealth"},
{text: "A jewel of the North, rough-cut but shining bright.", desc: "Proud frontier city"},
{text: "The city of a thousand spires and ten thousand secrets.", desc: "Arcane metropolis"},
{text: "Built on magic, ruled by steel.", desc: "Where might and magic meet"},
{text: "Where the river meets the road and all paths converge.", desc: "Crossroads of civilization"},
{text: "A beacon of civilization in the wild lands.", desc: "Lone bastion against wilderness"},
{text: "The city that never sleeps, for nightmares walk its streets.", desc: "Dark and dangerous"},
{text: "Carved from the living rock, a testament to dwarven ingenuity.", desc: "Underground marvel"},
{text: "Floating on the clouds, touched by the divine.", desc: "Celestial city"},
{text: "A den of scoundrels and thieves, but oh what treasures they hold!", desc: "Notorious pirate haven"},
{text: "Where every stone tells a story older than memory.", desc: "Ancient beyond reckoning"},
{text: "The forge where empires are made and unmade.", desc: "Powerful and political"},
{text: "A tapestry woven from a hundred cultures.", desc: "Melting pot of peoples"},
{text: "The candle that draws moths and burns them to ash.", desc: "Beautiful but deadly"},
{text: "Where the gods walk among mortals and the streets run with miracles.", desc: "Holy city"}
];
// City descriptions with descriptors
const cityDescriptions = [
{text: "This city has stood for centuries, weathering wars, plagues, and magical catastrophes. Its streets tell stories of glory and ruin, with each district bearing the marks of different eras in its architecture and culture.", desc: "Ancient and storied"},
{text: "A relatively new settlement by Faerûnian standards, this city has rapidly grown due to its strategic location and abundant resources. The mix of old traditions and new ideas creates a vibrant, if sometimes chaotic, atmosphere.", desc: "Young and growing"},
{text: "Ancient beyond memory, this city was old when Netheril was young. Its foundations contain secrets best left buried, though scholars and adventurers constantly seek them out.", desc: "Elder city"},
{text: "Built upon layer upon layer of previous civilizations, this city is literally and figuratively deep. The upper levels gleam with wealth and power, while the lower levels descend into darkness and mystery.", desc: "Layered history"},
{text: "Perched precariously in a dangerous location, this city survives through a combination of stubbornness, ingenuity, and sheer luck. Its people are hardened by their environment but proud of their home.", desc: "Defiant stronghold"},
{text: "A city of contrasts, where splendor and squalor exist side by side. The wealthy live in opulent towers while the poor scrape by in shadowed alleys, yet all share a fierce love for their city.", desc: "Divided but united"},
{text: "Known for its stunning beauty and artistic culture, this city attracts bards, artists, and philosophers from across Faerûn. Its walls are adorned with murals and its squares filled with music.", desc: "Cultural center"},
{text: "A grim, utilitarian city where function outweighs form. Its people are practical to a fault, valuing strength and skill above all else. Not a place for the weak or faint of heart.", desc: "No-nonsense"},
{text: "Shrouded in mist and mystery, this city seems half-real at times. Visitors speak of streets that shift when no one is looking and buildings that weren't there yesterday.", desc: "Ethereal and strange"},
{text: "A melting pot of cultures and races, this city thrives on diversity. Dozens of languages can be heard in its markets, and its cuisine is legendary across the Sword Coast.", desc: "Cosmopolitan hub"},
{text: "This city lives and breathes commerce, with goods from across Toril flowing through its markets. The clink of coins is the true language here, and everything has its price.", desc: "Mercantile powerhouse"},
{text: "A holy city where pilgrims come to worship at dozens of temples. The faithful walk the streets alongside skeptics, and divine magic is as common as rain.", desc: "Sacred site"},
{text: "Built around a massive magical college or artifact, this city pulses with arcane energy. Spell duels light up the night sky, and even children know a few cantrips.", desc: "Arcane heart"},
{text: "Once great, now fallen into decay, this city clings to past glories while crumbling at the edges. Yet in its ruins, new life and opportunities spring up like weeds through cobblestones.", desc: "Fading grandeur"},
{text: "A city constantly at war, whether with external enemies or internal factions. Its walls are scarred from battles, and its people know how to fight—whether they want to or not.", desc: "Battleground"}
];
// Social strata options
const socialStrata = [
"Rigid caste system",
"Fluid based on wealth",
"Nobility vs commoners",
"Guild hierarchy dominates",
"Religious hierarchy dominates",
"Military ranks determine status",
"Arcane power determines status",
"Meritocratic (skill determines rank)",
"Egalitarian (little formal hierarchy)",
"Oppressive (rulers vs oppressed)",
"Complex web of competing systems",
"Ancestry determines status",
"Foreigners have lower status",
"Magical ability grants status",
"Adventurers have special status"
];
// Gender ratios
const genderRatios = [
"Balanced",
"Slightly more males",
"Slightly more females",
"Mostly males",
"Mostly females",
"Non-binary majority",
"Varies by district",
"Genderless society",
"Fluid concepts of gender",
"Strict gender roles"
];
// City founding eras
const foundingEras = [
"Ancient (before -1000 DR)",
"Old (-1000 DR to 0 DR)",
"Early (1 DR to 500 DR)",
"Middle (501 DR to 1000 DR)",
"Recent (1001 DR to 1350 DR)",
"Very recent (1351 DR to present)",
"Mythic (date unknown)",
"From another time",
"Multiple foundings",
"Always existed"
];
// Current ages
const currentAges = [
"Golden Age",
"Silver Age",
"Bronze Age",
"Iron Age",
"Age of Decline",
"Age of Rebirth",
"Age of Turmoil",
"Age of Expansion",
"Age of Isolation",
"Age of Innovation"
];
// Coinage types
const coinage = [
"Standard Faerûnian (gp, sp, cp)",
"Local variant with different weights",
"Foreign coins accepted",
"Commodity-based (barter system)",
"Magical credit system",
"Guild scrip",
"Gem-based economy",
"Multiple competing currencies",
"No formal currency",
"Exotic (platinum standard)"
];
// Taxation systems
const taxation = [
"Heavy and oppressive",
"Reasonable and fair",
"Light and minimal",
"Nonexistent",
"Complex with many exceptions",
"Paid in goods or services",
"Magically enforced",
"Voluntary donations",
"Only on foreigners",
"Only on certain goods"
];
// City layouts
const cityLayouts = [
"Concentric rings",
"Grid pattern",
"Organic growth",
"Spiral design",
"Radial from center",
"Divided districts",
"Vertical stacking",
"Underground layers",
"Floating platforms",
"No discernible pattern"
];
// Natural resources
const naturalResources = [
"Fertile farmland",
"Rich mineral deposits",
"Abundant timber",
"Freshwater access",
"Strategic location",
"Magical ley lines",
"Unique flora/fauna",
"Gemstone mines",
"Hot springs",
"Nothing special"
];
// Hazards
const hazards = [
"Frequent monster attacks",
"Natural disasters",
"Disease outbreaks",
"Political instability",
"Economic crashes",
"Magical anomalies",
"Undead incursions",
"Planar rifts",
"Criminal activity",
"Environmental decay"
];
// Education levels
const educationLevels = [
"Nonexistent",
"Basic for elites",
"Apprenticeship system",
"Guild training",
"Temple schools",
"Public education",
"Magical academies",
"University system",
"Oral tradition",
"Varied by district"
];
// Cultural values
const culturalValues = [
"Honor and glory",
"Wealth and power",
"Knowledge and wisdom",
"Faith and devotion",
"Freedom and individuality",
"Tradition and stability",
"Innovation and progress",
"Community and cooperation",
"Strength and survival",
"Beauty and artistry"
];
// Notable location types
const notableLocationTypes = [
"Grand Temple",
"Wizard's Tower",
"Thieves' Guild",
"Merchant Exchange",
"Noble Estate",
"Ancient Ruins",
"Magical Academy",
"Underground Warrens",
"Floating Gardens",
"Coliseum",
"Great Library",
"Alchemist's Quarter",
"Docks District",
"Market Square",
"City Gates",
"Palace Complex",
"Artisan's Row",
"Slums",
"Military Barracks",
"Planar Gateway"
];
// Current event types
const currentEventTypes = [
"Festival",
"Political Unrest",
"Economic Boom",
"Plague",
"Invasion Threat",
"Religious Revival",
"Magical Phenomenon",
"Natural Disaster",
"Royal Wedding",
"Tournament",
"Trade Fair",
"Assassination Plot",
"Prophetic Vision",
"Dragon Sighting",
"Undead Rising",
"Artistic Renaissance",
"Scandal",
"Exploration Opportunity",
"Mysterious Disappearances",
"Divine Omen"
];
// Generate a random city name
function generateCityName() {
// 30% chance for a standalone name
if (Math.random() < 0.3) {
return standalone[Math.floor(Math.random() * standalone.length)].name || standalone[Math.floor(Math.random() * standalone.length)];
}
// 70% chance for a constructed name
const useMiddle = Math.random() < 0.5;
let name = prefixes[Math.floor(Math.random() * prefixes.length)];
if (useMiddle) {
name += middles[Math.floor(Math.random() * middles.length)];
}
name += suffixes[Math.floor(Math.random() * suffixes.length)];
// 20% chance to add a second word
if (Math.random() < 0.2) {
const secondWordType = Math.random();
if (secondWordType < 0.5) {
// Add another constructed name
let secondName = prefixes[Math.floor(Math.random() * prefixes.length)];
if (Math.random() < 0.5) {
secondName += middles[Math.floor(Math.random() * middles.length)];
}
secondName += suffixes[Math.floor(Math.random() * suffixes.length)];
name += " " + secondName;
} else {
// Add a descriptor
const descriptors = ["Upper", "Lower", "New", "Old", "East", "West",
"North", "South", "High", "Deep", "Far", "Near",
"Greater", "Lesser", "Inner", "Outer", "Free", "Royal"];
name += " " + descriptors[Math.floor(Math.random() * descriptors.length)];
}
}
return name;
}
// Generate random race percentages that add up to 100
function generateRacePercentages() {
const percentages = [];
let remaining = 100;
// Generate percentages for all races except "Other"
for (let i = 0; i < races.length - 1; i++) {
if (remaining <= 0) {
percentages.push(0);
continue;
}
// The first few races get larger percentages
let max;
if (i < 3) {
max = Math.min(remaining, 40);
} else {
max = Math.min(remaining, 20);
}
const min = i < 3 ? 5 : 0;
const percent = Math.floor(Math.random() * (max - min + 1)) + min;
percentages.push(percent);
remaining -= percent;
}
// Add "Other" with whatever is left
percentages.push(remaining);
// Shuffle the array (except "Other" which should stay last)
for (let i = races.length - 2; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[percentages[i], percentages[j]] = [percentages[j], percentages[i]];
}
return percentages;
}
// Generate a random selection from an array with 1-4 items
function generateRandomSelection(array, min = 1, max = 4) {
const count = Math.floor(Math.random() * (max - min + 1)) + min;
const shuffled = [...array].sort(() => 0.5 - Math.random());
const selected = shuffled.slice(0, count);
// If objects have a 'name' property, use that, otherwise use the item directly
return selected.map(item => item.name || item).join(", ");
}
// Generate notable locations
function generateNotableLocations() {
const count = Math.floor(Math.random() * 5) + 3; // 3-7 locations
const shuffled = [...notableLocationTypes].sort(() => 0.5 - Math.random());
const selected = shuffled.slice(0, count);
return selected.map(location => {
return {
type: location,
name: generateLocationName(location),
description: generateLocationDescription(location)
};
});
}
// Generate a name for a notable location
function generateLocationName(type) {
const prefixes = ["
</html>