UP | HOME

RPG Character Maker

Table of Contents

1. Description

This is the Character Maker.

2. Settings

Stat Total:
Maxstat:
Ext. Alignment:
Gender:
Race:
Class:
Lawfulness:
Goodness:
Birth Year:

3. Output

Your next adventerer will appear here.

4. Source Code

4.1. Static Data

The code in this section doesn't contain any logic, they're basically just big tables of data that get used by other pieces of code later in the program.

4.1.1. Races

These are the lists of all the fantasy races that the character (player) can be. The first is the big monolithic one of all the races, then the others are for selecting a random subrace (Human (random), Dwarf (random), Genasi (random), etc…). They are 2D lists that associate each race with their life expectancy. The life expectancy is used primarily in the backstory function.

const racelist = [["Human (Calishite)",80],
  ["Human (Calishite)",80],
  ["Human (Chondathan)",80],
  ["Human (Chondathan)",80],
  ["Human (Damaran)",80],
  ["Human (Damaran)",80],
  ["Human (Illuskan)",80],
  ["Human (Illuskan)",80],
  ["Human (Mulan)",80],
  ["Human (Mulan)",80],
  ["Human (Rashemi)",80],
  ["Human (Rashemi)",80],
  ["Human (Shou)",80],
  ["Human (Shou)",80],
  ["Human (Tethyrian)",80],
  ["Human (Tethyrian)",80],
  ["Human (Turami)",80],
  ["Human (Turami)",80],
  ["Dwarf (Hill)",350],
  ["Dwarf (Hill)",350],
  ["Dwarf (Hill)",350],
  ["Dwarf (Hill)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Duergar)",350],
  ["Dwarf (Duergar)",350],
  ["Dwarf (Duergar)",350],
  ["Dwarf (Duergar)",350],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Elf (Wood)",750],
  ["Elf (Wood)",750],
  ["Elf (High)",750],
  ["Elf (High)",750],
  ["Elf (Drow)",750],
  ["Elf (Drow)",750],
  ["Elf (Sea)",750],
  ["Elf (Sea)",750],
  ["Elf (Eladrin)",750],
  ["Elf (Eladrin)",750],
  ["Dragonborn (Black)",80],
  ["Dragonborn (Blue)",80],
  ["Dragonborn (Green)",80],
  ["Dragonborn (Red)",80],
  ["Dragonborn (White)",80],
  ["Dragonborn (Brass)",80],
  ["Dragonborn (Bronze)",80],
  ["Dragonborn (Copper)",80],
  ["Dragonborn (Gold)",80],
  ["Dragonborn (Silver)",80],
  ["Gnome (Forest)",350],
  ["Gnome (Forest)",350],
  ["Gnome (Forest)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Deep)",350],
  ["Gnome (Deep)",350],
  ["Gnome (Deep)",350],
  ["Tiefling (Baalzebul)",150],
  ["Tiefling (Dispater)",150],
  ["Tiefling (Fierna)",150],
  ["Tiefling (Glasya)",150],
  ["Tiefling (Levistus)",150],
  ["Tiefling (Mammon)",150],
  ["Tiefling (Mephistopheles)",150],
  ["Tiefling (Zariel)",150],
  ["Aasimar (Scourge)",2],
  ["Aasimar (Scourge)",2],
  ["Aasimar (Protector)",2],
  ["Aasimar (Protector)",2],
  ["Aasimar (Fallen)",2],
  ["Aasimar (Fallen)",2],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tortle",500],
  ["Tortle",500],
  ["Tortle",500],
  ["Tortle",500],
  ["Tortle",500],
  ["Satyr",50],
  ["Satyr",80],
  ["Satyr",80],
  ["Satyr",80],
  ["Satyr",750],
  ["Neufolk (Verdi)",80],
  ["Neufolk (Zurri)",80],
  ["Neufolk (Grigii)",80],
  ["Neufolk (Rossi)",80],
  ["Neufolk (Violi)",80],
  ["Owlin",100],
  ["Owlin",100],
  ["Owlin",100],
  ["Owlin",100],
  ["Half-Elf (High)",180],
  ["Half-Elf (Wood)",180],
  ["Half-Elf (Sea)",180],
  ["Half-Elf (Wood)",180],
  ["Half-Orc",71],
  ["Half-Orc",71],
  ["Half-Orc",71],
  ["Half-Orc",71],
  ["Bugbear",80],
  ["Bugbear",80],
  ["Bugbear",80],
  ["Bugbear",80],
  ["Centaur",80],
  ["Centaur",80],
  ["Centaur",80],
  ["Centaur",500],
  ["Githyanki",96],
  ["Githyanki",96],
  ["Githzerai",100],
  ["Githzerai",100],
  ["Goblin",50],
  ["Goblin",50],
  ["Goblin",50],
  ["Goblin",50],
  ["Goliath",80],
  ["Goliath",80],
  ["Goliath",808],
  ["Lizardfolk",75],
  ["Lizardfolk",75],
  ["Lizardfolk",75],
  ["Orc",50],
  ["Orc",50],
  ["Orc",50],
  ["Triton",200],
  ["Triton",200],
  ["Triton",200],
  ["Warforged",50],
  ["Warforged",50],
  ["Warforged",50],
  ["Dohwar",65],
  ["Dohwar",65],
  ["Dohwar",65],
  ["Vedalken",375],
  ["Vedalken",375],
  ["Vedalken",375],
  ["Leonin",80],
  ["Leonin",80],
  ["Leonin",80],
  ["Aarakocra",30],
  ["Aarakocra",30],
  ["Aarakocra",30],
  ["Fire Genasi",120],
  ["Fire Genasi",120],
  ["Air Genasi",120],
  ["Air Genasi",120],
  ["Water Genasi",120],
  ["Water Genasi",120],
  ["Earth Genasi",120],
  ["Earth Genasi",120],
  ["Changeling",80],
  ["Changeling",80],
  ["Fairy",80],
  ["Fairy",240],
  ["Harengon",75],
  ["Harengon",75],
  ["Hobgoblin",50],
  ["Kenku",60],
  ["Yuan-ti",1.1],
  ["Milifian",56],
  ["Drider",750],
  ["Hadozee",60],
  ["Thri-kreen",90],
  ["Loxodon",450],
  ["Verdan",180],
  ["Grung",50],
  ["Locathah",80],
  ["Plasmoid",120],
  ["Autognome",50]];

const humanlist = [["Human (Calishite)",80],
  ["Human (Chondathan)",80],
  ["Human (Damaran)",80],
  ["Human (Illuskan)",80],
  ["Human (Mulan)",80],
  ["Human (Rashemi)",80],
  ["Human (Shou)",80],
  ["Human (Tethyrian)",80],
  ["Human (Turami)",80]];

const dwarflist = [["Dwarf (Hill)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Duergar)",350]];

const elflist = [["Elf (Wood)",750],
  ["Elf (High)",750],
  ["Elf (Drow)",750],
  ["Elf (Sea)",750],
  ["Elf (Eladrin)",750]];

const halflinglist = [["Halfling (Lightfoot)",150],
  ["Halfling (Stout)",150]];

const dragonbornlist = [["Dragonborn (Black)",80],
  ["Dragonborn (Blue)",80],
  ["Dragonborn (Green)",80],
  ["Dragonborn (Red)",80],
  ["Dragonborn (White)",80],
  ["Dragonborn (Brass)",80],
  ["Dragonborn (Bronze)",80],
  ["Dragonborn (Copper)",80],
  ["Dragonborn (Gold)",80],
  ["Dragonborn (Silver)",80]];

const gnomelist = [["Gnome (Forest)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Deep)",350]];

const tieflinglist = [["Tiefling (Baalzebul)",150],
  ["Tiefling (Dispater)",150],
  ["Tiefling (Fierna)",150],
  ["Tiefling (Glasya)",150],
  ["Tiefling (Levistus)",150],
  ["Tiefling (Mammon)",150],
  ["Tiefling (Mephistopheles)",150],
  ["Tiefling (Zariel)",150]];

const aasimarlist = [["Aasimar (Scourge)",2],
  ["Aasimar (Protector)",2],
  ["Aasimar (Fallen)",2]];

const genasilist = [["Fire Genasi",120],
  ["Air Genasi",120],
  ["Water Genasi",120],
  ["Earth Genasi",120]];

const neufolklist = [["Neufolk (Verdi)",80],
  ["Neufolk (Zurri)",80],
  ["Neufolk (Grigii)",80],
  ["Neufolk (Rossi)",80],
  ["Neufolk (Violi)",80]];

const githlist = [["Githyanki",96],
  ["Githzerai",100]];

4.1.2. Names

These are the mythical name lists. Many of the names for the more common races, I got from the D&D Player's handbook, but every other name in this section was made up by myself and Wesley or is the name of a past player character in our group.

const humanCalishiteMaleNames = ["Aseir","Bardeid","Haseid","Khemed","Mehmen","Sudeiman","Zasheir"];
const humanCalishiteFemaleNames = ["Atala","Ceidil","Hama","Jasmal","Meilil","Seipora","Yasheira","Zasheida"];
const humanCalishiteLastNames = ["Basha","Dumein","Jassan","Khalid","Mostana","Pashar","Rein"];

const humanChondathanMaleNames = ["Darvin","Dorn","Evendur","Gorstag","Grim","Helm","Malark","Morn","Randal","Stedd"];
const humanChondathanFemaleNames = ["Arveene","Esvele","Jhessail","Kerri","Lureene","Miri","Rowan","Shandri","Tessele","Thespa"];
const humanChondathanLastNames = ["Amblecrown","Buckman","Dundragon","Evenwood","Greycastle","Tallstag","Hormir","Pennypacker"];

const humanDamaranMaleNames = ["Bor","Fodel","Glar","Grigor","Igan","Ivor","Kosef","Mival","Orel","Pavel","Sergor"];
const humanDamaranFemaleNames = ["Alethra","Kara","Katernin","Mara","Natali","Olma","Tana","Zora"];
const humanDamaranLastNames = ["Bersk","Chernin","Dotsk","Kulenov","Marsk","Nemetsk","Shemov","Starag"];

const humanIlluskanMaleNames = ["Ander","Blath","Bran","Frath","Geth","Lander","Luth","Malcer","Stor","Taman","Urth"];
const humanIlluskanFemaleNames = ["Amafrey","Betha","Cefrey","Kethra","Mara","Olga","Silifrey","Westra"];
const humanIlluskanLastNames = ["Brightwood","Helder","Hornraven","Lackman","Stormwind","Windrivver"];

const humanMulanMaleNames = ["Aoth","Bareris","Ehput-Ki","Kethoth","Mumed","Ramas","So-Kehur","Thazar-De","Urhur"];
const humanMulanFemaleNames = ["Arizima","Chathi","Nephis","Nulara","Murithi","Sefris","Thola","Umara","Zolis"];
const humanMulanLastNames = ["Ankhalab","Anskuld","Fezim","Hahpet","Nathandem","Sepret","Uuthrakt"];

const humanRashemiMaleNames = ["Borivik","Faurgar","Jandar","Kanithar","Madislak","Ralmevik","Shaumar","Vladislak"];
const humanRashemiFemaleNames = ["Fyevarra","Hulmarra","Immith","Imzel","Navarra","Shevarra","Tammith","Yuldra"];
const humanRashemiLastNames = ["Chergoba","Dyernina","Iltazyara","Murnyethara","Stayanoga","Ulmokina"];

const humanShouMaleNames = ["An","Chen","Chi","Fai","Jiang","Jun","Lian","Long","Meng","On","Shan","Shui","Wen"];
const humanShouFemaleNames = ["Bai","Chao","Jia","Lei","Mei","Qiao","Shui","Tai"];
const humanShouLastNames = ["Chien","Huang","Kao","Kung","Lao","Ling","Mei","Pin","Shin","Sum","Tan","Wan"];

//Tethyrian humans take Chondathan names

const humanTuramiMaleNames = ["Anton","Diero","Marcon","Pieron","Rimardo","Romero","Salazar","Umbero"];
const humanTuramiFemaleNames = ["Balama","Dona","Faila","Jalana","Luisa","Marta","Quara","Selise","Vonda"];
const humanTuramiLastNames = ["Agosto","Astorio","Calabra","Domine","Falone","Marivaldi","Pisacar","Ramondo"];

const dwarfMaleNames = ["Adrik","Alberich","Baern","Barendd","Brottor","Bruenor","Dain","Darrak","Delg","Eberk","Einkil","Fargrim","Flint","Gardain","Harbek","Kildrak","Morgan","Orsik","Oskar","Rangrim","Rurik","Taklinn","Thoradin","Thorin","Tordek","Traubon","Travok","Ulfgar","Vondal","Umdal","Thorkon"];
const dwarfFemaleNames = ["Amber","Artin","Audhild","Bardryn","Dagnal","Diesa","Doril","Eldeth","Falkfunn","Finellen","Gunnloda","Gurdis","Helja","Hlin","Kathra","Kristryd","Ilde","Liftrasa","Mardred","Riswynn","Sannl","Torbera","Vistra"];
const dwarfLastNames = ["Balderk","Battlehammer","Braunanvil","Dankil","Fireforge","Frostbeard","Gorunn","Holderhek","Ironfist","Loderr","Lutgehr","Rumnaheim","Strakeln","Torunn","Ungart","Þiknir","the Skull-Piercer"];

const elfChildNames = ["Ara","Bryn","Del","Eryn","Faen","Innil","Lael","Mella","Naill","Naeris","Phann","Rael","Rinn","Sai","Syllin","Thia","Vall"];
const elfMaleNames = ["Adran","Aelar","Aramil","Arannis","Aust","Beiro","Berrian","Carric","Enialis","Erdan","Erevan","Galinndan","Hadarai","Heian","Himo","Immeral","Ivellios","Laucian","Mindartis","Paelias","Peren","Quarion","Riardon","Rolen","Soveliss","Thamior","Tharivol","Theren","Varis","Kastellon"];
const elfFemaleNames = ["Adrie","Althaea","Anastrianna","Andraste","Atinua","Bethrynna","Birel","Caelynn","Drusilla","Enna","Felosial","Ielenia","Jelenneth","Keyleth","Leshanna","Lia","Meriele","Mialee","Naivara","Quelenna","Quillathe","Sariel","Shanairra","Shava","Silaqui","Theirastra","Thia","Vadania","Xanaphia"];
const elfLastNames = ["Amakiir","Amastacia","Galanodel","Holimion","Ilphelkiir","Liadon","Meliamne","Naïlo","Siannodel","Xiloscient","Karpathos"];

const halflingMaleNames = ["Alton","Ander","Cade","Corrin","Eldon","Errich","Finnan","Garret","Lindal","Lyle","Merric","Milo","Osborn","Perrin","Reed","Roscoe","Wellby"];
const halflingFemaleNames = ["Andry","Bree","Callie","Cora","Euphemia","Jillian","Kithri","Lavinia","Lidda","Merla","Nedda","Paela","Portia","Seraphina","Shaena","Trym","Vani","Verna"];
const halflingLastNames = ["Brushgather","Goodbarrel","Greenbottle","High-hill","Hilltopple","Leagallow","Tealeaf","Thorngage","Tosscobble","Underbough"];

const dragonbornMaleNames = ["Arjhan","Balasar","Bharash","Donaar","Ghesh","Heskan","Kriv","Medrash","Mehen","Nadarr","Pandjed","Patrin","Rhogar","Shamash","Shedinn","Tarhun","Torinn","Galin","Arrox","Mythra","Korox"];
const dragonbornFemaleNames = ["Akra","Biri","Daar","Farideh","Harann","Havilar","Jheri","Kava","Korinn","Mishann","Nala","Perra","Raiann","Sora","Surina","Thava","Uadjit"]
const dragonbornChildNames = ["Climber","Earbender","Leaper","Pious","Shieldbiter","Zealous"];
const dragonbornLastNames = ["Clethtinthiallor","Daardendrian","Delmirev","Drachedandion","Fenkenkabradon","Kepeshkmolik","Kerrhylon","Kimbatuul","Linxakasendalor","Myastan","Nemmonis","Norixius","Ophinshtalajiir","Prexijandilin","Shestendeliath","Turnuroth","Verthisathurgiesh","Yarjerit","Chiroc","Malibu"];

const gnomeMaleNames = ["Alston","Alvyn","Boddynock","Brocc","Burgell","Dimble","Eldon","Erky","Fonkin","Frug","Gerbo","Gimble","Glim","Jebeddo","Kellen","Namfoodle","Orryn","Roondar","Seebo","Sindri","Warryn","Wrenn","Zook"];
const gnomeFemaleNames = ["Bimpnottin","Breena","Caramip","Carlin","Donella","Duvamil","Ella","Ellyjobell","Ellywick","Lilli","Loopmottin","Lorilla","Mardnab","Nissa","Nyx","Oda","Orla","Roywyn","Shamil","Tana","Waywocket","Zanna"];
const gnomeLastNames = ["Beren","Daergel","Folkor","Garrick","Nackle","Murnig","Ningel","Raulnor","Scheppen","Timbers","Turen","Knockknees"];
const gnomeNicknames = ["Aleslosh","Ashhearth","Badger","Cloak","Doublelock","Filchbatter","Fnipper","Ku","Nim","Oneshoe","Pock","Sparklegem","Stumbleduck","Slappy","Mimp","Slink","Bubble","Flitterfly","Fibblegrip","Pongle","Quickfoot","Twiddleby","Thumbsy","Twig","Stumpknack","Clickspring","Twang","Fiddlestick","Barrel-Rider","Gaggle","Pip","Pluckey","Tootbottle","Strum","Sticky","Thwumpy","Thwickle","Brambly","Yilo","Wagon-Runner","Bug-Chaser","Cookie","Twink","Flipple","Zoff","Tibbi","Stickwhisker"];

//Half-elves take either elvish or human names

//Half-Orcs take either orcish or human names

const tieflingMaleNames = ["Akmenos","Amnon","Barakas","Damakos","Ekemon","Iados","Kairon","Leucis","Melech","Mordai","Morthos","Pelaios","Skamos","Therai","Thajen","Jerald"];
const tieflingFemaleNames = ["Akta","Anakis","Bryseis","Criella","Damaia","Ea","Kallista","Lerissa","Makaria","Nemeia","Orianna","Phelaia","Rieta","Arnella","Jinx"];
const tieflingLawfulNames = ["Creed","Reverence","Quest","Constance","Ideal","Rule","Rigid","Structure"];
const tieflingChadNames = ["Cool","Glory","Temereity","Chad","Art"];
const tieflingSmartNames = ["Cunning","Invention","Spark","Idea","Creative"];
const tieflingChaoticNames = ["Random","Mischief","Freedom","Rebellion","Gremlin","Dork"];
const tieflingSadNames = ["Sorrow","Dispair","Weary","Mourning","Cry","Nowhere","Grief","Stoic"];
const tieflingStupidNames = ["Hehe","Goof","Moron","Crazy","Impulse","Id","Idiot","Dumbass"];
const tieflingGoodNames = ["Hope","Love","Kindness","Ideal","Open","Poetry"];
const tieflingHornyNames = ["Lust","Desire","Wink","Whisper","Charm","Allure","Smooth","Hotstuff","Fuck","Smash"];
const tieflingEvilNames = ["Torment","Carrion","Fear","Wrath","Cruelty","Selfish","Greed","Anger","Ambition"];
const tieflingNeutralNames = ["Moderation","Temperance","Balance","Equality","Even-Handed","Eh"];
const tieflingLastNames = ["Terias","Mutnon","Achore","Vikos","Srath","Anarch","Baenor","Bikros","Nethaia","Monalla"];


//Aasimar take names from the people they are raised by

const fireGenasiMaleNames = ["أمل ('Amal)","حعين (Hayin)","جهيدم (Jhidam)"];
const fireGenasiFemaleNames = ["يأمل (Yamal)","حلاوة (Halawa)","جهراند (Jahrand)"];
const fireGenasiLastNames = ["نار (Nar)","آتش (Atch)","جمرة (Jamra)","خاکستر (Khakestr)"];

const airGenasiMaleNames = ["رثيري (Rethyri)","مرو (Maruu)","فمز (Famaz)"];
const airGenasiFemaleNames = ["حجير (Hajir)","كيوب (Kyub)","زورود (Zurud)"];
const airGenasiLastNames = ["هواء (Hawa')","هوا (Hwa)","أَجواء ('Ajwa')","سماء (Sama')"];

const waterGenasiMaleNames = ["بلو (Balu)","منده (Mindah)","جهلإم (Jahlim)"];
const waterGenasiFemaleNames = ["جردان (Jardan)","يان Yan","مرح (Marah)"];
const waterGenasiLastNames = ["ماء (Ma')","اب (Ab)","بحر (Bahr)","دریا (Draa)"];

const earthGenasiMaleNames = ["درخأن (Darkhan)","درزخ (Darzakh)","هامان (Haman)"];
const earthGenasiFemaleNames = ["جحيش (Jahish)","لأضية (Ladiya)","ظاهرم (Zahirm)"];
const earthGenasiLastNames = ["أرض ('Ard)","زمین (Zman)","التراب (Alturab)","صحراء (Sahra')"];

//Changeling names

const firbolgMaleNames = ["Clay","Tallus","Chantal","Tellus","Kumal","Jonquil","Yael","Bog","Coriander","Oland"];
const firbolgFemaleNames = ["Jade","Terra","Gaia","Ersa","Omala","Janquil","Bog","Cypress","Leaf","Chulsa"];
const firbolgLastNames = ["Forager","Sol","Porier","Apeldoorn","Dalen","Feldin","Lesena","Fraol","Marith","Pol"];

const koboldMaleNames = ["Ajhan","Blusar","Bhrash","Dronar","Ghush","Heksan","Kruv","Drash","Meen","Nudra","Pjed","Prutan","Rhog","Shmash","Shned","Tarun","Torn","Galn","Arx","Muthra","Krux","Vrik","Brak","Xurk","Rax","Kron","Frit","Grat","Zax","Din","Tik"];
const koboldFemaleNames = ["Arka","Bru","Druh","Friduh","Hrann","Hvillr","Jhur","Kva","Kornn","Shman","Nulah","Pera","Riann","Sor","Srina","Thav","Udjit","Bix","Lin","Sill","Ryn","Kly","Mo","Rif","Sy","Nar","Zor"];

const tabaxiNames = ["Long","Short","Breaking","Tall","Leaping","Falling","Sneaking","Singing","Travelling","Future","Steel","Kallie","Brownie","Buster","Baxter","Kira","Oni","Akuma"];

const tortleMaleNames = ["Tristifer","Shelgon","Muedran","Lorett","Malne","Lumbel","Gandin","Bartigan","Blot","Gorban","Droon","Glorick","Bundus","Tropple","Dromm"];
const tortleFemaleNames = ["Muedrin","Sheffel","Malene","Hatrin","Karinth","Kotta","Grayll","Dramm","Blona","Orli","Plop","Royne","Zorr","Galeen","Loav"];
const tortleLastNames = ["Mudd","Trogrove","Willoe","Sloe","Hartshel","Morlingon","Drumm","Hardback","Estermont","Mudwall","Braykin","Gornim","Gar","Tortician","Fogg","Zooble"];

//Satyrs use Fey names

const feyNames = ["","Mushroom","Daisy","Lily","Amaranth","Qualia","Mystery","Mischief","Magic","Riddle","Giggle","Fibber","Tickle","Dawn","Dusk","Curious","Trick","Tricky","Dance","Trance","Fun","Mirth","Glee","Stubborn","Grin","Smile","Amathyst","Emerald","Crystal","Fungus","Toadstool","Toad","Evergreen","Hopper","Dream","Fiddlerick McSnifficker","Fef're'el","Prance"];

const owlinMaleNames = ["Finrindel","Guardriel","Deiben","Farduran","Hlyn"];
const owlinFemaleNames = ["Roliel","Lerinal","Perrinq","Humily","Yanalyn","Lynrindel"];
const owlinLastNames = ["Corrin","Huuarn","Hardbeak","Glyde","Fint"];

const bugbearMaleNames = ["Gläch","Blarn-Eat","Blarg","Prodak","Rostogg","Valix","Dibrack"];
const bugbearFemaleNames = ["Dorlag","Bunglethung","Darish","Nilly","Gratch","Brell"];

const centaurMaleNames = ["Ratimir","Jim","Glueboy","Reckless","Bucephalus","Vladimir","Yuri","Thunder","Asfaloth","Hasufel","Smoky","Bullseye","Arod","Braston"];
const centaurFemaleNames = ["Jenny","Rainbow","Ayndrea","Meela","Thraela","Ravinya","Olga","Embla","Yulia","Noraphel","Lillix","Hulda","Grayla","Forla","Rain"];
const centaurLastNames = ["Glitterhoof","Tweedmouth","Wylde","Strider","Wind","Prancer","Steel","Firemane","Hotblood","Silver","Colt","Clydesdale","Horse"];

const githyankiMaleNames = ["Jharazi","Saharazi","Zikari","Krai","Jafarai","Nari","Drossi","Rath'lai","Kasheri","Morkai","Shazadi","Kyri","Vkori","Nylathi"];
const githyankiFemaleNames = ["Zeharano","Nathoro","Nabro","Phozho","Marzo","Phylo","Nagormo","Kalo","Mehrano","Jithko","Dralo","Kathko","Laylo","Zirro"];
const githyankiLastNames = ["Krall","Gothro","Scoro","Drask","Ithene","Maryllo","Voss","Brassh","Nahro","Nosho","Jas'kalo","Jharlakk","Zotho"];

const githzeraiMaleNames = ["Arotho","Zraio","Kharao","Merkyro","Thaio","Drogo","Zallo","Klatho","Dasho'ko","Janar'tho","Shortho","Zikko","Karlo"];
const githzeraiFemaleNames = ["Guarani","Jharai","Zhondi","Neeli","Hirodi","Akali","Galdi","Zoni","Kharai","Jinari","Sarai","Zorri","Phalani"];
const githzeraiLastNames = ["Zethlani","Leoni","Krai","Vali","Jeth'li","Morokai","Ketani","Mor'tiin","Kalai","Shani","Zhono","Zholi","Hala'ti"];

const goblinMaleNames = ["Scromch","Blood","Grizzle","Bunk","Yeck","Squeltch","Flim","Lig","Hooch","Ghel","Vor","Azrok","Glot","Kliyuse","Malget","Drakk","Raff"];
const goblinFemaleNames = ["Scrungle","Bone","Bonk","Squeltch","Flam","Yink","Thrick","Nock","Gillmince","Pluck","Thock","Lurkana","Gastra","Verk","Prola","Korda"];

const goliathMaleNames = ["Hogh","Grug","Drev","Kreg","Kregdak","Godok","Throng","Obak"];
const goliathFemaleNames = ["Droz","Grezen","Hrun","Korl","Jaadok","Norlok","Obok"];
const goliathLastNames = ["Cleverhand","Skytouch","Undermountain","Blueskin","Strongarm","Behemothback"];

const lizardfolkMaleNames = ["Zzarizz","Ssrig","Ssikrith","Rakak","Zzorid","Nrath","Orthrok","Zzarnon","Grizzk","Ssrak","Ssulikar","Voss","Rassk","Ssaro","Yorsso","Malassar","Massad","Elssir","Yarssov","Delsso"];
const lizardfolkFemaleNames = ["Sucu","Juro","Slatha","Skraa","Zhathro","Sroko","Zarno","Kiro","Hrani","Oroki","Yissith","Essvara","Ssirine","Mariss","Lasstra","Darssa","Ssyla","Zossha","Felissa","Rassid"];

const orcMaleNames = ["Dench","Feng","Gell","Henk","Holg","Imsh","Keth","Krusk","Mhurren","Ront","Shump","Thokk","Malador"]
const orcFemaleNames = ["Baggi","Emen","Engong","Kansif","Myev","Neega","Ovak","Ownka","Shautha","Sutha","Vola","Volen","Yevelda"]

const tritonFirstNames = ["Dukar","Keros","Vodos","Jhimar","Pythan","Ruthar","Zegen","Jhabur","Sigoz","Lanar"];
const tritonLastNames = ["Phranar","Ghastar","Grithos","Thronos","Derikan","Zohon","Zoko","Threek","Granir"];

const warforgedNames = ["Ghost","Fortschrittlicherohrbiegemaschine","Bender","Scrapper","Scrappie","Clank","Rusty","Steele","Trapper","Hammer","Piledriver","Squeaky"];
const warforgedAcron = ["O.R.C. unit", "O.R.C.", "D.W.A.R.F.", "G.R.U.N.G.", "E.L.F.", "E.L.F.", "H.U.M.A.N."];
const warforgedExpan = ["(Outerplanar Runaway Containment unit)", "(Object Recognition Construct)", "(Durable Wartime Attack and Reconaissance Follower)", "(Garbage and Refuse UNloading Golem)", "(Esoteric Language Filter)", "(Eliminator unit: ", "(Hemoglobin-Using Medical Assistant/Nurse)"];
const lmalefirstnames = ["Lander", "Luth", "Lian", "Long", "Lael", "Laucian", "Lindal", "Lyle", "Leaper", "Leucis", "Lorrett", "Lumbel", "Lig", "Lanar"];
const lfemalefirstnames = ["Lureene", "Lei", "Luisa", "Liftrasa", "Lael", "Leshanna", "Lia", "Lavinia", "Lidda", "Leaper", "Lilli", "Loopmottin", "Lorilla", "Lerissa", "Leaf", "Lin", "Loav", "Lily", "Lerinal", "Lynrindel", "Lillix", "Laylo", "Leoni"];
const flastnames = ["Fezim", "Falone", "Fireforge", "Frostbeard", "Fenkenkabradon", "Folkor", "Forager", "Feldin", "Fraol", "Fogg", "Fint", "Firemane"];

const dohwarMaleNames = ["Agwil","Quann","Benne","Thwil","Stagan","Ogwallo","Holtar","Fadrol","Ouk","Melwyn","Zinko","Skipper","Fillibar","Noryck","Rico","Kliftyn","Dellin","Zakrod","Yelbin"];
const dohwarFemaleNames = ["Enet","Agwan","Agane","Larmi","Drilla","Kitka","Marcedene","Aria","Pelgie","Hilwyn","Zonerelle","Astry","Relki","Zelbar"];
const dohwarLastNames = ["Pennypacker","Coin","Business","Profit","Sale","Bargain","Haggle","Copper","Silver","Gold","Electrum","Platinum","Trade","Revenue","Capital","Investment","Dividend","Asset Synergizer","Asset"];

const vedalkenMaleNames = ["Pende","Forune","Mödo","Üvel","Revé","Möduvel"];
const vedalkenFemaleNames = ["Meun","Slaükaa","Osaa","Iß","Loraa","Çeruvé"];
const vedalkenLastNames = ["Eudicus","Oedion","Uep","Orlemaa"];

const leoninMaleNames = ["Riani","Asume","Umale","Skiri","Kurami","Amoalé"];
const leoninFemaleNames = ["Raya","Umala","Muzé","Mira","Pelana"];
const leoninLastNames = ["Umara","Salaz","Lezir"];

const aarakocraMaleNames = ["Aun","Leashore","Sevadore","Thalor","Marwyn","Arryn","Atlas","Corvus","Cirrus","Owain","Hermes","Jarnathan","Rondor"];
const aarakocraFemaleNames = ["Throcas","Dravanas","Socoros","Lasra","Ariella","Ravenna","Mariel","Eilonwy","Lorelai","Wave","Perin","Tavia","Castaleina"];
const aarakocraLastNames = ["Janam","Soram","Peloras","Talon","Brightwing","Sparrow","Crow","Swan","Larke","Firewind","Laydin","Avian","Sunspear"];

//Fairies use Fae names

const harengonMaleNames = ["Olie","Truodore","Rudofer","Heuwill","Millofer","Gilwinkle"];
const harengonFemaleNames = ["Hinderwind","Alie","Galamine","Millofet","Brave","Nilley"];
const harengonLastNames = ["Thump","Lopear","Fickle","Longtail","Hop","Hollowood","Hatbuckle","Nibbles"];

//Hobgoblins use goblin names

const kenkuNames = ["Tapper","Basher","*Ring*","*Sail Snap*","Clanger","Hammer","Singer","*Chatter*","*Clash*","Wind","Cutter","\"Meat Pies! Two For a Silver! Get \'Em While They\'re Hot!\"","*Stab*","Caw!","*Crunch*","Saw","*Strum*","*Clink*","Whistler","Drummer","*Slap*","*Falling Tree*","*Whinny*","*Cackle*","Screamer","Bell","*Crashing Wave*","*Footfall*","*Door Creak*","Echo"];

const neufolkZurriMaleNames = ["Giovanni","Elio","Luca","Enzo","Mateo","Dante","Lorenzo","Aurelio","Rocco","Leandro","Salvatore"];
const neufolkZurriFemaleNames = ["Ginevra","Beatrice","Greta","Vittoria","Martina","Chiara","Matilde","Ludovica","Azzurra","Anselma","Cinzia"];
const neufolkZurriLastNames = ["Marino","Acone","Acqarone","Bonomo","Bicchieri","De Luca","Episcopo","Esposito","Lamon","Pozzi","Profeta","Ricci","Zino"];

const neufolkGrigiiMaleNames = ["Dave","Craig","Steven","Matthew","Johnathan","Gary","Donald","Connor","Sean","Oisin","Patrick","Cian","Liam","Darragh"];
const neufolkGrigiiFemaleNames = ["Aoife","Ciara","Caoimhe","Niamh","Roisin","Cara","Clodagh","Poppy","Evie","Grace","Anne","Eloise","Eleanor","Lucy","Mae","Daisy","Olive","Edith"];
const neufolkGrigiiLastNames = ["Smith","Jones","Taylor","Brown","Johnson","Davies","Wright","Murphy","Kelly","Byrne","Walsh","O'Brien","O'Connor","O'Sullivan"];

const neufolkRossiMaleNames = ["محمد (Mohammed)","أحمد (Ahmed)","يوسف (Yusef)","مصطفى (Mustafa)","ابراهيم (Ibrahim)","ابو (Abu)","عمر (Omar)"];
const neufolkRossiFemaleNames = ["الاء (Alaa)","شامة (Shamma)","شام (Sham)","غلا (Ghala)","منى (Mona)","هبة (Heba)","مروة (Marwa)","ساره (Sarah)","ايمان (Eman)","فاطمة (Fatima)"];
const neufolkRossiLastNames = ["أباظة (Abaza)","عبد الله (Abdallah)","أبو العافية (Abulafia)","بكر (Bakir)","السراج (Al-Sarraj)","راغب (Ragheb)","الخطيب (Al-Khatib)","عون (Aoun)","ضومط (Doumit)","ضيف الله (Daifallah)"];

const neufolkVioliMaleNames = ["이준 (I-jun)","서준 (Seo-jun)","하준 (Ha-jun)","도윤 (Do-yun)","은우 (Eun-u)","시우 (Si-u)","지호 (Ji-ho)","예준 (Ye-jun)","유준 (Yu-jun)","수호 (Su-jo)"];
const neufolkVioliFemaleNames = ["서아 (Seo-ah)","하윤 (Ha-yoon)","이서 (I-seo)","지안 (Ji-an)","지아 (Jia)","서윤 (Seoyun)","아린 (A-rin)","아윤 (A-Yun)","하린 (Ha-rin)","하은 (Ha-eun)"];
const neufolkVioliLastNames = ["김 (Kim)","이 (Lee)","박 (Bak)","정 (Jeong)","최 (Choe)","조 (Jo)","강 (Gang)","장 (Jang)","윤 (Yun)","임 (Lim)"];

//Yuan-ti use names from their original race

const milifianMaleNames = ["Gug","Freck","Rizz","Rizzo","Gugular","Chug","Chugular"];
const milifianFemaleNames = ["Razz","Frink","Rungle","Grel","Razena"];
const milifianLastNames = ["Grimble","Lumble","Forbin","Dump","Cheese"];

//Driders use elvish names

const hadozeeMaleNames = ["Alfez","Hililliam","Trombert","Jimothy","Keenustus","Johash","Apefred","Vorace","Finston","Malvin"];
const hadozeeFemaleNames = ["Greneta","Amne","Umelia","Fynthia","Dillith","Moodith","Imy","Zylfia","Hattryn","Vae"];
const hadozeeLastNames = ["Howlbert","Alfezson","Frish","Grey","Bananape","Lurchill","Pink","Greaver","Stiff","A'Fulliban"];

const thrikreenUpperFirstNames = ["Gak","Mor","Gol","Kol","Kag","Za","Ga","Ko","Ha","Gre","Sra","Thre","Thor","Loh","Ro","Qo","Ke","Thri","Kre","Zo","Nør"];
const thrikreenLowerFirstNames = ["gak","mor","gol","kol","kag","za","ga","ko","ha","gre","sra","thre","thor","loh","ro","qo","ke","'","thri","kre","en","zo","kle","nør"];
const thrikreenLastNames = ["Gok","Lod","Kag","Zih","Kol","Hoh","Thog","Hath","Gor","Zor","Zim"];

const loxodonMaleNames = ["Bolomf","Kel","Albo","Brasof","Surumah","Geranon","Felahf"];
const loxodonFemaleNames = ["Actel","Moronay","Sheia","Ulenara","Belanel"];
const loxodonLastNames = ["Toron","Nairah","Kallah","Zahur"];

const verdanNames = ["Bronn","Crahma","Dolar","Dreeda","Duglee","Gruvald","Hulm","Jeal","Kalo","Klesh","Korm","Lathi","Ovlig","Paracii","Pils","Praet","Promul","Reezni","Rin","Shylk","Slyra","Sollo","Stalsii","Stromvo","Stussa","Syrkart","Takat","Toit","Tubyna","Varr","Veriga","Wraq","Wural","Wurxee"];

const grungMaleNames = ["Ulp","Gallt","Rort","Plet","Raff","Cathre","Ort","Kermit","Lurken","Ath’lith","Glorm","Jatho","Na’ziko","Kring"];
const grungFemaleNames = ["Koa","Roarp","Gangle","Mika","Talakki","Liga","Garis","Blorn","Ritt","Paka","Lorti","Anga"];
const grungLastNames = ["Umpus","Wort","Klebt","Glaik","Krang","Bogg","Marlo","Dal’akor","Tamimi","Chola","Ribbit","Galata","Tok","Kayn"];

const locathahMaleNames = ["Murlth","Bormel","Gu'Yllin","Morbl","Depf","Gu'il","Klu'Amesh"];
const locathahFemaleNames = ["Squimpus","Gu'Illah","Waul","Edon","Thara'gul","Zarugah"];
const locathahLastNames = ["Gazimpus","Jhath","Sukravesh","Depfedon","Orlemagus","Saragur","Gu'hrugon","C'thru","Iiemalure","Kh'khumal","Veshala"];

const plasmoidNames = ["Gl'oup","Gorlk","Glopp","G'korlp","Pthpthppt","Mlop","P'lok","Gu'lum Plop","K'ptth","Gulm'p"];

const autognomeNames = ["Clickspring","Twizzy","Doohickey","Whizz","Dancer","Clunkie"];

4.1.3. Misc

These are a miscellaneous collection of other lists for random

  • Landmarks
  • Rural Towns
  • Urban Cities
  • Creepy places for warlocks
  • Professions for your parents
  • recurring symbols
  • nouns and adjectives for generating random taverns
  • body parts
  • creatures

These are all mostly used for backstories.

const ruralLandmarks = ["old mill","river","lakeshore","pond"];
const urbanLandmarks = ["general store","docks","castle","tavern"];

const towns = [
  ["Greenest","<a href=\"https://forgottenrealms.fandom.com/wiki/Greenest\">Greenest</a>","plains","Western Heartlands",],
  ["Beregost","<a href=\"https://forgottenrealms.fandom.com/wiki/Beregost\">Beregost</a>","forest","Trade Way"],
  ["Tilverton","<a href=\"https://forgottenrealms.fandom.com/wiki/Tilverton\">Tilverton</a>","mountains","Cormyr"],
  ["Mosstone","<a href=\"https://forgottenrealms.fandom.com/wiki/Mosstone\">Mosstone</a>","forest","Tethyr"],
  ["Trademeet","<a href=\"https://forgottenrealms.fandom.com/wiki/Trademeet\">Trademeet</a>","forest","Amn"],
  ["Han Chao","<a href=\"https://forgottenrealms.fandom.com/wiki/Han_Chao\">Han Chao</a>","mountains","Tabot"],
  ["Horsea","<a href=\"https://forgottenrealms.fandom.com/wiki/Horsea\">Horsea</a>","forest","Calidyrr"],
  ["Shallownet","<a href=\"\">Shallownet</a>","coastal","Zwakke"],
];
const cities = [
  ["Waterdeep","<a href=\"https://forgottenrealms.fandom.com/wiki/Waterdeep\">Waterdeep</a>","plains","Sword Coast"],
  ["Baldur's Gate","<a href=\"https://forgottenrealms.fandom.com/wiki/Baldur's_Gate\">Baldur's Gate</a>","plains","Sword Coast"],
  ["Neverwinter","<a href=\"https://forgottenrealms.fandom.com/wiki/Neverwinter\">Neverwinter</a>","mountains","Sword Coast"],
  ["Elturel","<a href=\"https://forgottenrealms.fandom.com/wiki/Elturel\">Elturel</a>","plains","Western Heartlands"],
  ["Berdusk","<a href=\"https://forgottenrealms.fandom.com/wiki/Berdusk\">Berdusk</a>","plains","Western Heartlands"],
  ["Roalis","<a href=\"\">Roalis</a>","coastal","Zwakke"],
  ["I Lain Othrond","<a href=\"\">I Lain Othrond</a>","coastal","Thege"],
];

<!--"-->
const warlockplaces = ["S̷̞̬̩̙̮̮̟̒̏̐̎̑c̷̛͇̊́́̎̐͗̃͗̃̎̉̅͊̒͛͠a̷̛̟͈̰͙̪̞͎͔̗͋̓̊̉̏̎̈́̌̌̈̓̎̊̊̑̕d̴̨̡̧͎̭͎͎̞̼̙͔̓̈̎ͅȧ̶̢̛̮͕͉̻̙̪̘͙̮̩͂͜͠͝","P̷̧̙̲̫̫̫̾̓͑̋ù̵̢̪̹͉̼͍̝̜̎͒́͒̑̑͌̈̀̀̑͐̿̚̚r̴̠͓̀̓̏̽p̷̨̡̛̻͍̮̮̲͉̺̟̼̒͛͝͝ͅl̵̬̥͚̦̪̙̥̯̘̈́̃̓͒̄͌̚͜ͅͅe̴̡̡̦͖̟̞̳̣̖͙̺͎̖̔̍̇̌͛̃͠͝͝ͅ ̷̠̼̤̣̦͈̺̝̝̻̹̗̈̉̀̈̐̀̾͝ͅR̴͓̱̐͂̾͊́̿͑̏̔̾̐̽͠͝͝͠͠ͅó̸̠̬͇͙̻͋ͅc̴̢̡̙̲̗̥̹͉̟̭͇̹͋͐̑̓͒͌̚͠k̵̲̰͍͔̭̦̈́̾̾͋̅́","U̷͚͕̩̠͗̔̀̂̔̀̃͂̾̊̀͒̏͘͘t̷̺̮̖̞̠̣̤̆̒̀̎͝t̷͓͇͎͎͓̪͔͂͌̃̍͂̆̈́̓͆́̌̚ͅę̶̢̤̩͕̹̙͍͉͙̟̣̹͉̼̑̚r̷̛͈̲͎͇̰̬̼͖̭͔͗̿̋͆͗͑̊́̉͐̇s̵̡̫̖̱̺͇̟̼̬̣̭͇̯̭͑͜e̸̢̝̘͎̲̲͈̝̺͈͈̯̦̫̻͂̓̋̎͆̿́͌̂̕a̸̡̦̩̤̱̠̰̳̓͂͑͛̿̈́͛̆̂̋̄̓̃͑͘","M̵̨͖̠͇̖̣̜̞͎͋͊̕ȏ̶̡̢̨̰͈̖̭̯̭̉̐t̵̤̲̜̮̙̦͚̲̦̼͓͂͠h̷̡̡̭̬͚͖͖͔͈́͌̉̈́͂̾̅̿͊͛̒̅̚e̸̢̩̹̯̤͕̻̣̱͉͎͓̒̌̋̏͂̓̇̎̕͘͝ŗ̸̧͈̮͍̯̲͈̼̖̹̩́͋̓͊͌̃͒̆̾͜͝ͅ ̵̟̤̣̰̹̂͊̒̏̈́̾͊̈͆̒͂͐͗̂̇͆͊o̵̧͙͈̞̳̯̼̓̒̈́̏͗͆̀̉̀͆f̶͉̼̣̺͍͖̬̥̺̼̤̝̤͖̬̋̎̐͗̔̊̕͜͜ ̷̢͚̘̤̣͙̲̰͕̘̟͉̦͎̳͚̄̈́̈͑̐M̵̨̖͖̙̜̦͌͑̚͜͜͠ͅî̸̗͚̬̗͕̾̌̓̑̃̇̑̇̾̕͜͝ͅs̸̢̨̫̮͕̗̭͉̺̥͍͗͒͑̋̎̆̀̔̕͝ţ̴̧́͗̐̑͑̀̎͒̍̎ś̶̨̗̻̤͓̠͍̯̿̀̎́̄͒̚̚"];

const logos = ["crescent moon","wolf head","coiled snake","bloody knife","crying figure","closed eye","eye","bloodshot eye","sleeping owlbear","lightning bolt","spiral"];

const damagetypeselemental = ["fire","lightning","poison","acid","cold"];
const damagetypesphysical = ["slashing","piercing","bludgeoning"];

const wealthyprofessions = ["Noble",
  "Noble",
  "Advisor",
  "Cleric",
  "Adventurer",
  "Spy"];
const urbanprofessions = ["Stonemason",
  "General store merchant",
  "Cheesemaker",
  "Brewer",
  "City guard",
  "Cleric",
  "Alchemist",
  "Magic supply merchant",
  "Performer",
  "Carpenter"];
const ruralprofessions = ["Farmer",
  "General store merchant",
  "Fisher",
  "Hunter",
  "Brewer",
  "Cleric",
  "Cobbler",
  "Carpenter"];

const magicschools = ["evocation",
  "conjuration",
  "divination",
  "abjuration",
  "enchantment",
  "illusion",
  "transmutation"]

const tavernadj = ["Slippery","Drunken","Sour","Lazy","Flaming","Splendid","Black","Red","Blue","Green","Lame","Staggering","Rising","Bigget","Swaggering","Sparkling","Speckled","Lunar","Shivering"];
const tavernnoun = ["Tavern","Duck","Buck","Rabbit","Bunny","Splash","Tankard","Cup","Vagrant","Sun","Moon","Sunset","Moonrise","Nut","King","Queen","Princess","Prince","Wizard","Den","Hive","Hearth","Longhouse","Hen"];

const bodypartsext = ["left cheek","right cheek","left eye","right eye","left arm","right arm","left forarm","right forarm","left hand","right hand","nose","neck","left leg","right leg","left foot","right foot","chest"];

const smallbeasts = ["panther","wolf","bear","snake","wild dog","boar","alligator","crocodile","tiger"];
const bigbeasts = ["displacer beast","owlbear","direwolf","giant snake"];

const offscreentag = "Offscreen";

4.2. Player Struct

This is the variable/data type that holds all the data for the character being made. It's declared globally because I was lazy. I've thought about redoing this in a more general way that would allow for more than one instance of 'player'. That would allow me to do stuff like record a short history of generated characters and perhaps the ability to save ones you like for a short time.

const player = {
  stats: [0,0,0,0,0,0],
  statorder: [5,4,3,2,1,0],
  birthday: 0,
  race: ["<font color='red'>FDEFAULT_RACE</font>",1],
  race2: ["<font color='red'>FDEFAULT_RACE_2</font>",1],
  clas: "<font color='red'>FDEFAULT_CLASS</font>",
  gender: "<font color='red'>FDEFAULT_GENDER</font>",
  fullname: ["<font color='red'>FIRST_NAME</font>","<font color='red'>LAST_NAME</font>","<font color='red'>NICKNAME</font>"],
  locale: "<font color='red'>LOCALE</font>",
  socialclass: "<font color='red'>SOCIAL_CLASS</font>",
  sad: 0,
  adopted: 0,
  adoptedLate: 0,
  parent1:{
    birthday: 0,
    fullname: ["<font color='red'>FIRST_NAME</font>","<font color='red'>LAST_NAME</font>"],
    race: ["<font color='red'>PARENT_1_RACE</font>",1],
    gender: "<font color='red'>PARENT_1_GENDER</font>",
    profession: "<font color='red'>PARENT_1_GENDER</font>",
    dead: "",
  },
  parent2:{
    birthday: 0,
    fullname: ["<font color='red'>FIRST_NAME</font>","<font color='red'>LAST_NAME</font>"],
    race: ["<font color='red'>PARENT_2_RACE</font>",1],
    gender: "<font color='red'>PARENT_2_GENDER</font>",
    profession: "<font color='red'>PARENT_2_GENDER</font>",
    dead: "",
  },
  hometown: "<font color='red'>DEFAULT_TOWN</font>",
  alignment: ["<font color='red'>DEFAULT_LAWFULNESS</font>", "<font color='red'>DEFAULT_GOODNESS</font>"],
  backstory: [[1,"Event 1"],[2,"Event 2"]],
  discapline: "<font color='red'>DISCAPLINE</font>",
};

4.3. Functions

4.3.1. Kowalski

function kowalski(){
  var stattotalk = parseInt(document.getElementById('stattotalinput').value);
  var outputstring = "";
  if(stattotalk < 18){
    stattotalk = 18;
    alert("It is impossible to roll a stat total lower than 18. The stat total has been set to 18.");
    if(confirm("Stat totals less than 36 are very slow to calculate. Do you want to continue?")){
      for(let i = 0; i < 1000; i++){
        generateCharacter(stattotalk);
        outputstring = outputstring + player.clas + "," + player.gender + "," + player.race[0] + "," + player.stats[0] + "," + player.stats[1] + "," + player.stats[2] + "," + player.stats[3] + "," + player.stats[4] + "," + player.stats[5] + "," + player.alignment + "<br>";
      }
    }
  }
  else if(stattotalk > 108){
    stattotalk = 108;
    alert("It is impossible to roll a stat total higher than 108. The stat total has been set to 108.");
    if(confirm("Stat totals less than 36 are very slow to calculate. Do you want to continue?")){
      for(let i = 0; i < 1000; i++){
        var extalignment = document.getElementById("extendedalignment").checked;
        generateCharacter(stattotalk, extalignment);
        outputstring = outputstring + player.clas + "," + player.gender + "," + player.race[0] + "," + player.stats[0] + "," + player.stats[1] + "," + player.stats[2] + "," + player.stats[3] + "," + player.stats[4] + "," + player.stats[5] + "," + player.alignment + "<br>";
      }
    }
  }
  else{
    for(let i = 0; i < 1000; i++){
        var extalignment = document.getElementById("extendedalignment").checked;
      generateCharacter(stattotalk, extalignment);
      outputstring = outputstring + player.clas + "," + player.gender + "," + player.race[0] + "," + player.stats[0] + "," + player.stats[1] + "," + player.stats[2] + "," + player.stats[3] + "," + player.stats[4] + "," + player.stats[5] + "," + player.alignment + "<br>";
    }
  }
  //Output to screen
  document.getElementById("output").innerHTML = outputstring;
}

4.3.2. Button Press

function buttonPress(){
  //get user presets
  var stattotalbp = parseInt(document.getElementById('stattotalinput').value);
  var extalignment = document.getElementById("extendedalignment").checked;

  console.clear();

  if(isNaN(stattotalbp)){
    stattotalbp = 72;
    generateCharacter(stattotalbp, extalignment);
    writeToScreen();
  }
  else if(stattotalbp < 18){
    alert("It is impossible to roll a stat total lower than 18.");
  }
  else if(stattotalbp > 108){
    alert("It is impossible to roll a stat total higher than 108.");
  }
  else{
    generateCharacter(stattotalbp, extalignment);
    writeToScreen();
  }
}

4.3.3. Generate Character

function generateCharacter(stattotalgc, extalign){
  var racepreset = document.getElementById("raceselection").value;
  var genderpreset = document.getElementById("genderselection").value;
  var classpreset = document.getElementById("classselection").value;
  var lawfulnesspreset = document.getElementById("lawfulnessselection").value;
  var goodnesspreset = document.getElementById("goodnessselection").value;
  var maxstatpreset = document.getElementById("maxstat").checked;
  var randomnum = Math.random();
  var randomnum2 = Math.random();
  var birthyear = parseInt(document.getElementById('birthyearfield').value);
  //choose class
  player.clas = "<font color='red'>DEFAULT_CLASS</font>";
  player.stats = [0,0,0,0,0,0];
  if(maxstatpreset == true && classpreset == "Random"){
    while(player.stats[player.statorder[0]] != 18){
      player.stats = rollCharacter(stattotalgc);
      player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
      player.clas = chooseClass(player.statorder[0], player.statorder[1]);
    }
  }
  else if(maxstatpreset == true){
    while(classpreset != player.clas || player.stats[player.statorder[0]] != 18){
      player.stats = rollCharacter(stattotalgc);
      player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
      player.clas = chooseClass(player.statorder[0], player.statorder[1]);
    }
  }
  else if(classpreset == "Random"){
    player.stats = rollCharacter(stattotalgc);
    player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
    player.clas = chooseClass(player.statorder[0], player.statorder[1]);
  }
  else{
    while(classpreset != player.clas){
      player.stats = rollCharacter(stattotalgc);
      player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
      player.clas = chooseClass(player.statorder[0], player.statorder[1]);
    }
  }

  //choose discapline
  if(player.clas == "Wizard"){
    player.discapline = magicschools[randomindex(magicschools.length)];
  }

  //choose race
  if(racepreset == "Random"){
    player.race = racelist[randomindex(racelist.length)];
  }
  else if(is_containedin_("Random",racepreset)){
    if(is_containedin_("Human",racepreset)){
      player.race = humanlist[randomindex(humanlist.length)];
    }
    else if(is_containedin_("Dwarf",racepreset)){
      player.race = dwarflist[randomindex(dwarflist.length)];
    }
    else if(is_containedin_("Elf",racepreset)){
      player.race = elflist[randomindex(elflist.length)];
    }
    else if(is_containedin_("Halfling",racepreset)){
      player.race = halflinglist[randomindex(halflinglist.length)];
    }
    else if(is_containedin_("Dragonborn",racepreset)){
      player.race = dragonbornlist[randomindex(dragonbornlist.length)];
    }
    else if(is_containedin_("Gnome",racepreset)){
      player.race = gnomelist[randomindex(gnomelist.length)];
    }
    else if(is_containedin_("Tiefling",racepreset)){
      player.race = tieflinglist[randomindex(tieflinglist.length)];
    }
    else if(is_containedin_("Aasimar",racepreset)){
      player.race2[1] = randomindex(aasimarlist.length);
      player.race[0] = aasimarlist[player.race2[1]][0];
      player.race[1] = aasimarlist[player.race2[1]][1];
    }
    else if(is_containedin_("Genasi",racepreset)){
      player.race = genasilist[randomindex(genasilist.length)];
    }
    else if(is_containedin_("Neufolk",racepreset)){
      player.race = neufolklist[randomindex(neufolklist.length)];
    }
    else if(is_containedin_("Gith",racepreset)){
      player.race = githlist[randomindex(githlist.length)];
    }
    else{
      //console.log(racepreset);
      for(let i = 0; i < racelist.length; i++){
        if(racepreset == racelist[i][0]){
          player.race = racelist[i]
          break;
        }
      }
    }
  }
  else{
    for(let i = 0; i < racelist.length; i++){
      if(racepreset == racelist[i][0]){
        player.race[0] = racelist[i][0];
        player.race[1] = racelist[i][1];
        break;
      }
    }
  }

  //Choose race2
  if(player.race[0].slice(0,7) == "Aasimar" || player.race[0].slice(0,7) == "Yuan-ti"){
    do{
      player.race2 = chooseRace();
    }while(player.race2[0].slice(0,7) == "Aasimar" || player.race2[0].slice(0,7) == "Yuan-ti" || player.race2[0].slice(0,10) == "Changeling");
    player.race2[0] = "(" + player.race2[0] + ")";
    player.race[1] *= player.race2[1];
  }
  else{
    player.race2[0] = "";
  }

  //choose gender
  if(genderpreset == "Random"){
    player.gender = chooseGender();
  }
  else{
    player.gender = genderpreset;
  }
  //choose alignment
  if(extalign == true){
    if(lawfulnesspreset == "Random"){
      player.alignment[0] = chooseSillyAlignment()[0];
    }
    else{
      player.alignment[0] = lawfulnesspreset;
    }
    if(goodnesspreset == "Random"){
      player.alignment[1] = chooseSillyAlignment()[1];
    }
    else{
      player.alignment[1] = goodnesspreset;
    }
  }
  else{
    if(lawfulnesspreset == "Random"){
      player.alignment[0] = chooseAlignment()[0];
    }
    else{
      player.alignment[0] = lawfulnesspreset;
    }
    if(goodnesspreset == "Random"){
      player.alignment[1] = chooseAlignment()[1];
    }
    else{
      player.alignment[1] = goodnesspreset;
    }
  }
  player.alignment = trueNeutral(player.alignment);
  //choose attributes
  if(player.alignment[0] == "Sad" || Math.random() < 0.065){
    player.sad = 1;
  }
  else{
    player.sad = 0;
  }

  //Adoption
  if((Math.random() < 0.05  || player.race[0].slice(0,10) == "Changeling") && player.race[0].slice(0,9) != "Warforged"){
    player.adopted = 1;
    if(Math.random() < 0.5){
      player.adoptedLate = 1;
    }
    else{
      player.adoptedLate = 0;
    }
  }
  else{
    player.adopted = 0;
  }

  chooseSocialClass();
  chooseLocale();

  //generate parents
  player.parent1.gender = chooseGender();
  if(randomnum < 0.2){
    player.parent2.gender = player.parent1.gender;
  }
  else{
    while(player.parent2.gender == "<font color='red'>PARENT_2_GENDER</font>" || player.parent2.gender == player.parent1.gender){
      player.parent2.gender = chooseGender();
    }
  }
  if(!player.adopted){
    if(player.race[0].slice(0,7) == "Aasimar" || player.race[0].slice(0,7) == "Yuan-ti"){
      player.parent1.race[0] = player.race2[0].substring(1,player.race2[0].length-1);
      player.parent1.race[1] = player.race2[1];
      player.parent2.race[0] = player.race2[0].substring(1,player.race2[0].length-1);
      player.parent2.race[1] = player.race2[1];
    }
    else{
      if(player.race[0] == "Warforged"){
        if(Math.random() < 0.25){
          player.parent1.race = ["Machine", Math.floor(Math.random()*150+50)];
          player.parent2.race = ["N/A", 1];
          player.parent1.gender = "N/A";
          player.parent2.gender = "N/A";
        }
        else{
          player.parent1.race = chooseRace();
          player.parent2.race = chooseRace();
        }
      }
      else{
        player.parent1.race = player.race;
        player.parent2.race = player.race;
      }
    }
  }
  else{
    if(Math.random() < 0.5){
      do{
        player.parent1.race = chooseRace();
      }while(player.parent1.race[0].slice(0,7) == "Aasimar" || player.parent1.race[0].slice(0,10) == "Changeling" || player.parent1.race[0].slice(0,7) == "Yuan-ti");
      player.parent2.race = player.parent1.race;
    }
    else{
      do{
        player.parent1.race = chooseRace();
      }while(player.parent1.race[0].slice(0,7) == "Aasimar" || player.parent1.race[0].slice(0,10) == "Changeling" || player.parent1.race[0].slice(0,7) == "Yuan-ti");
      do{
        player.parent2.race = chooseRace();
      }while(player.parent2.race[0].slice(0,7) == "Aasimar" || player.parent2.race[0].slice(0,10) == "Changeling" || player.parent2.race[0].slice(0,7) == "Yuan-ti");
    }
  }
  // choose parents professions
  if(player.race[0] != "Warforged"){
    player.parent1.profession = randomprofession([player.locale,player.socialclass]);
    player.parent2.profession = randomprofession([player.locale,player.socialclass]);
  }
  else{
    if(player.parent1.race[0] == "Machine"){
      player.parent1.profession = "Machine";
      player.parent2.profession = "N/A";
    }
    else{
      player.parent1.profession = "Inventor";
      player.parent2.profession = "N/A";
    }
  }

  if(player.sad){
    if(Math.random() < 0.5){
      player.parent1.dead = " (dead)";
    }
    else{
      player.parent1.dead = "";
    }
    if(Math.random() < 0.5){
      player.parent2.dead = " (dead)";
    }
    else{
      player.parent2.dead = "";
    }
  }
  else{
    if(Math.random() < 0.015){
      player.parent1.dead = " (dead)";
    }
    else{
      player.parent1.dead = "";
    }
    if(Math.random() < 0.015){
      player.parent2.dead = " (dead)";
    }
    else{
      player.parent2.dead = "";
    }
  }

  player.hometown = cities[randomindex(cities.length)];

  //Naming
  //Parent #1
  if(player.race[0] != "Warforged"){
    player.parent1.fullname = choosename(player.parent1.race[0], player.parent1.gender,player.alignment);
  }
  else{
    if(player.parent1.race[0] == "Machine"){
      player.parent1.fullname = ["Assembling Machine #" + randomindex(125), "", ""];
      player.parent2.fullname = ["N/A", "", ""];
    }
    else{
      player.parent1.fullname = choosename(player.parent1.race[0], player.parent1.gender,player.alignment);
    }
  }
  //Parent #2
  if(player.race[0] != "Warforged"){
    do{
      player.parent2.fullname = choosename(player.parent2.race[0], player.parent2.gender,player.alignment);
    }while(player.parent2.fullname[0] == player.parent1.fullname[0] && player.parent2.fullname[0].slice(-8) != "E</abbr>" && player.parent2.fullname[0].slice(-15) != "E</font></abbr>");
  }
  //player
  if(player.adopted && !player.adoptedLate){
    if(Math.random() < 0.5){
      do{
        player.fullname = choosename(player.parent1.race[0], player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
    else{
      do{
        player.fullname = choosename(player.parent2.race[0], player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
  }
  else{
    if(player.race[0].slice(0,7) == "Aasimar" || player.race[0].slice(0,7) == "Yuan-ti"){
      do{
        player.fullname = choosename(player.race2[0].substring(1,player.race2[0].length-1), player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
    else if(player.race[0].slice(0,10) == "Changeling"){
      if(Math.random() < 0.5){
        do{
          player.fullname = choosename(player.parent1.race[0], player.gender, player.alignment);
        }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
      }
      else{
        do{
          player.fullname = choosename(player.parent2.race[0], player.gender, player.alignment);
        }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
      }
    }
    else{
      do{
        player.fullname = choosename(player.race[0], player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
  }

  //Naming rigamaroll
  if(player.race[0].slice(0,9) != "Warforged"){
    if(Math.random() < 0.85){
      if(Math.random() < 0.5){
        player.parent2.fullname[1] = player.parent1.fullname[1];
      }
      else{
        player.parent1.fullname[1] = player.parent2.fullname[1];
      }
    }
    if(player.parent1.fullname[1] != player.parent2.fullname[1]){
      player.fullname[1] = player.parent1.fullname[1] + "-" + player.parent2.fullname[1];
    }
    else{
      player.fullname[1] = player.parent1.fullname[1];
    }
  }

  //birthday stuff
  if(isNaN(birthyear)){
    birthyear = randomindex(500) + 1250;
  }
  if(birthyear % 400 == 0 || (birthyear % 100 != 0 && birthyear % 4 == 0)){
    player.birthday = dateToDays([1,1,birthyear]) + randomindex(366);
  }
  else{
    player.birthday = dateToDays([1,1,birthyear]) + randomindex(365);
  }
  player.parent1.birthday = player.birthday - yearToDay(0.626785414373 * (player.parent1.race[1]**0.766203192397)) - Math.floor(0.65 * normalyear(0.626785414373 * (player.parent1.race[1]**0.766203192397)));
  player.parent2.birthday = player.birthday - yearToDay(0.626785414373 * (player.parent2.race[1]**0.766203192397)) - Math.floor(0.65 * normalyear(0.626785414373 * (player.parent2.race[1]**0.766203192397)));
}

4.3.4. Is X contained in Y?

function is_containedin_(littlestring,bigstring){
  if(littlestring.length > bigstring.length){
    return 0;
  }
  for(let i = 0; i < bigstring.length-littlestring.length+1; i++){
    for(let j = 0; j < littlestring.length; j++){
      if(littlestring[j] != bigstring[i+j]){
        break;
      }
      if(j == littlestring.length-1){
        return i+1;
      }
    }
  }
  return 0;
}

4.3.5. Dates

  1. Date to Formatted Date (dateToDATE)
    function dateToDATE(datevar){
      var ththing = "<sup>";  //ya know, the th thing
      var outputvar = "";  //output to be returned
      var monname = "";  //name of the month
    
      if(datevar[0] % 100 >= 9 && datevar[0] % 100 <= 20){
        ththing += "th";
      }
      else if(datevar[0] % 10 == 1){
        ththing += "st";
      }
      else if(datevar[0] % 10 == 2){
        ththing += "nd";
      }
      else if(datevar[0] % 10 == 3){
        ththing += "rd";
      }
      else{
        ththing += "th";
      }
      ththing += "</sup>";
    
      if(datevar[1] == 1){
        monname = "January";
      }
      else if(datevar[1] == 2){
        monname = "February";
      }
      else if(datevar[1] == 3){
        monname = "March";
      }
      else if(datevar[1] == 4){
        monname = "April";
      }
      else if(datevar[1] == 5){
        monname = "May";
      }
      else if(datevar[1] == 6){
        monname = "June";
      }
      else if(datevar[1] == 7){
        monname = "July";
      }
      else if(datevar[1] == 8){
        monname = "August";
      }
      else if(datevar[1] == 9){
        monname = "September";
      }
      else if(datevar[1] == 10){
        monname = "October";
      }
      else if(datevar[1] == 11){
        monname = "November";
      }
      else if(datevar[1] == 12){
        monname = "December";
      }
      else{
        monname = "INVALID_MONTH";
      }
    
      outputvar += datevar[0] + ththing + " ";
      outputvar += monname + " ";
      outputvar += datevar[2];
    
      return outputvar;
    
    }
    
  2. Days to Date (daysToDate)
    function daysToDate(longdays){
      var datevar = [0,0,0];
      var daysinmonths = [31,28,31,30,31,30,31,31,30,31,30,31];
      var leapdaysinmonths = [31,29,31,30,31,30,31,31,30,31,30,31];
    
      //years
      //400s chunk
      datevar[2] += Math.floor(longdays / 146097) * 400;
      longdays = longdays % 146097;
      //100s chunk
      if(longdays >= 36525){
        datevar[2] += 100;
        longdays -= 36525;
        datevar[2] += Math.floor(longdays / 36524) * 100;
        longdays = longdays % 36524;
      }
      //4s chunk
      if(datevar[2] % 400 != 0){
        if(longdays >= 1460){
          datevar[2] += 4;
          longdays -= 1460;
          datevar[2] += Math.floor(longdays / 1461) * 4;
          longdays = longdays % 1461;
        }
      }
      else{
        if(longdays >= 1461){
          datevar[2] += Math.floor(longdays / 1461) * 4;
          longdays = longdays % 1461;
        }
      }
      //1s chunk
      for(let i = 0; i < 4; i++){
        if(datevar[2] % 400 == 0 || (datevar[2] % 100 != 0 && datevar[2] % 4 == 0)){
          if(longdays >= 366){
            datevar[2]++;
            longdays -= 366;
          }
          else{
            break;
          }
        }
        else{
          if(longdays >= 365){
            datevar[2]++;
            longdays -= 365;
          }
          else{
            break;
          }
        }
      }
    
      //months
      if(datevar[2] % 400 == 0 || (datevar[2] % 100 != 0 && datevar[2] % 4 == 0)){
        for(let i = 0; i < 12; i++){
          if(leapdaysinmonths[i] > longdays){
            break;
          }
          datevar[1]++;
          longdays -= leapdaysinmonths[i];
        }
      }
      else{
        for(let i = 0; i < 12; i++){
          if(daysinmonths[i] > longdays){
            break;
          }
          datevar[1]++;
          longdays -= daysinmonths[i];
        }
      }
      datevar[1]++;
    
      //days
      datevar[0] = longdays + 1;
    
      return datevar;
    }
    
  3. Date to Days (dateToDays)
    function dateToDays(datevar){
      var longdays = 0;
      var daysinmonths = [31,28,31,30,31,30,31,31,30,31,30,31];
      var leapdaysinmonths = [31,29,31,30,31,30,31,31,30,31,30,31];
      var orgyear = datevar[2]; //original year value that will not be edited
    
      datevar[0] -= 1;
      datevar[1] -= 1;
    
      //years
      //400s chunk
      longdays += Math.floor(datevar[2] / 400) * 146097;
      datevar[2] = datevar[2] % 400;
      //100s chunk
      if(datevar[2] >= 100){
        longdays += 36525;
        datevar[2] -= 100;
      }
      longdays += Math.floor(datevar[2] / 100) * 36524;
      datevar[2] = datevar[2] % 100;
      //4s chunk
      if(datevar[2] > 3 && (orgyear - datevar[2]) % 400 != 0){
        longdays += 1460;
        datevar[2] -= 4;
      }
      longdays += Math.floor(datevar[2] / 4) * 1461;
      datevar[2] = datevar[2] % 4;
      //1s chunk
      if(datevar[2] > 0 && (orgyear % 100 > 3 || orgyear % 400 <= 3)){
        longdays += 366;
        datevar[2]--;
      }
      longdays += datevar[2] * 365;
    
      //months
      if(orgyear % 400 == 0 || (orgyear % 100 != 0 && orgyear % 4 == 0)){
        for(let i = 0; i < datevar[1]; i++){
          longdays += leapdaysinmonths[i];
        }
      }
      else{
        for(let i = 0; i < datevar[1]; i++){
          longdays += daysinmonths[i];
        }
      }
    
      //days
      longdays += datevar[0];
    
      return longdays;
    }
    
  4. Year to Days (yearToDay)
    function yearToDay(years){
      return Math.floor(years * 365.2425);
    }
    

4.3.6. Randomness

  1. Normal Distribution
    function normaldist(maxnum){
      var summation = 0;
      var iterations = 5;
      for(let i = 0; i < iterations; i++){
        summation += Math.random();
      }
      return Math.floor(summation * maxnum / iterations);
    }
    
  2. Normally Distributed Year
    function normalyear(years){
      return normaldist(365*2*years);
    }
    
  3. Random Index
    function randomindex(length){
      return Math.floor(length * Math.random());
    }
    

4.3.7. Choose Functions

  1. Choose Social Class
    function chooseSocialClass(){
      var randomnum = Math.random();
    
      if(randomnum < 0.15){
        player.socialclass = "wealthy";
      }
      else{
        player.socialclass = "poor";
      }
    }
    
  2. Choose Locale
    function chooseLocale(){
      var randomnum = Math.random();
    
      if(player.socialclass == "wealthy"){
        player.locale = "urban";
      }
      else{
        if(randomnum < 1/4.63){
          player.locale = "urban";
        }
        else{
          player.locale = "rural";
        }
      }
    }
    
  3. Choose Race
    function chooseRace(){
      return racelist[randomindex(racelist.length)];
    }
    
  4. Choose Profession (randomprofession)
    function randomprofession(section){
      var randomnum = Math.random();
      var randomnum2 = Math.random();
      if(section[1] == "wealthy"){
        return wealthyprofessions[randomindex(wealthyprofessions.length)];
      }
      else if(section[0] == "urban"){
        return urbanprofessions[randomindex(urbanprofessions.length)];
      }
      else if(section[0] == "rural"){
        return ruralprofessions[randomindex(ruralprofessions.length)];
      }
      else{
        return "idk what this locale/social class is";
      }
    }
    
  5. Choose Gender
    function chooseGender(){
      var randomnum = Math.random();
      if(randomnum < 0.49){
        return "F";
      }
      else if(randomnum < 0.98){
        return "M";
      }
      else{
        return "NB";
      }
    }
    
  6. Choose Name
    function choosename(race, gender, alignment){
      var randomnum = Math.random();
      var alignmenttag = "";
    
      if(race == "Drider"){
        race = "Elf";
      }
      if(race.slice(0,8) == "Half-Elf"){
        if(Math.random() < 0.5){
          race = humanlist[randomindex(humanlist.length)][0];
        }
        else{
          race = "Elf";
        }
      }
      else if(race == "Half-Orc"){
        if(Math.random() < 0.5){
          race = humanlist[randomindex(humanlist.length)][0];
        }
        else{
          race = "Orc";
        }
      }
      if(race == "Human (Tethyrian)"){
        race = "Human (Chondathan)";
      }
      else if(race.slice(0,3) == "Elf"){
        race = "Elf";
      }
      else if(race.slice(0,5) == "Dwarf"){
        race = "Dwarf";
      }
      else if(race.slice(0,8) == "Halfling"){
        race = "Halfling";
      }
      else if(race.slice(0,5) == "Gnome"){
        race = "Gnome";
      }
      else if(race.slice(0,10) == "Dragonborn"){
        race = "Dragonborn";
      }
      else if(race.slice(0,7) == "Aasimar"){
        race = "Aasimar";
      }
      else if(race == "Satyr" || race == "Fairy"){
        race = "Fey";
      }
      else if(race.slice(0,8) == "Tiefling"){
        if(Math.random() < 0.5){
          race = "Tiefling";
        }
        else{
          if(Math.random() < 0.5){
            race = "Tiefling";
            alignmenttag = " (" + alignment[0] + ")";
          }
          else{
            race = "Tiefling";
            alignmenttag = " (" + alignment[1] + ")";
          }
        }
      }
    
      var output = ["<abbr title=\"" + race + alignmenttag + "\">","<abbr title=\"" + race + "\">","<abbr title=\"" + race + "\">"];
      race += alignmenttag;
    
      if(gender == "NB"){
        if(Math.random() < 0.5){
          gender = "M";
        }
        else{
          gender = "F";
        }
      }
    
      if(race.slice(0,5) == "Human"){
        if(race.slice(7,16) == "Calishite"){
          if(gender == "M"){
            output[0] += humanCalishiteMaleNames[randomindex(humanCalishiteMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanCalishiteFemaleNames[randomindex(humanCalishiteFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanCalishiteLastNames[randomindex(humanCalishiteLastNames.length)];
        }
        else if(race.slice(7,17) == "Chondathan"){
          if(gender == "M"){
            output[0] += humanChondathanMaleNames[randomindex(humanChondathanMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanChondathanFemaleNames[randomindex(humanChondathanFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanChondathanLastNames[randomindex(humanChondathanLastNames.length)];
        }
        else if(race.slice(7,14) == "Damaran"){
          if(gender == "M"){
            output[0] += humanDamaranMaleNames[randomindex(humanDamaranMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanDamaranFemaleNames[randomindex(humanDamaranFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanDamaranLastNames[randomindex(humanDamaranLastNames.length)];
        }
        else if(race.slice(7,15) == "Illuskan"){
          if(gender == "M"){
            output[0] += humanIlluskanMaleNames[randomindex(humanIlluskanMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanIlluskanFemaleNames[randomindex(humanIlluskanFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanIlluskanLastNames[randomindex(humanIlluskanLastNames.length)];
        }
        else if(race.slice(7,12) == "Mulan"){
          if(gender == "M"){
            output[0] += humanMulanMaleNames[randomindex(humanMulanMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanMulanFemaleNames[randomindex(humanMulanFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanMulanLastNames[randomindex(humanMulanLastNames.length)];
        }
        else if(race.slice(7,14) == "Rashemi"){
          if(gender == "M"){
            output[0] += humanRashemiMaleNames[randomindex(humanRashemiMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanRashemiFemaleNames[randomindex(humanRashemiFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanRashemiLastNames[randomindex(humanRashemiLastNames.length)];
        }
        else if(race.slice(7,11) == "Shou"){
          if(gender == "M"){
            output[0] += humanShouMaleNames[randomindex(humanShouMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanShouFemaleNames[randomindex(humanShouFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanShouLastNames[randomindex(humanShouLastNames.length)];
        }
        else if(race.slice(7,13) == "Turami"){
          if(gender == "M"){
            output[0] += humanTuramiMaleNames[randomindex(humanTuramiMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += humanTuramiFemaleNames[randomindex(humanTuramiFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += humanTuramiLastNames[randomindex(humanTuramiLastNames.length)];
        }
      }
      else if(race.slice(0,5) == "Dwarf"){
        if(gender == "M"){
          output[0] += dwarfMaleNames[randomindex(dwarfMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += dwarfFemaleNames[randomindex(dwarfFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += dwarfLastNames[randomindex(dwarfLastNames.length)];
      }
      else if(race.slice(0,3) == "Elf"){
        if(gender == "M"){
          output[0] += elfMaleNames[randomindex(elfMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += elfFemaleNames[randomindex(elfFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += elfLastNames[randomindex(elfLastNames.length)];
      }
      else if(race.slice(0,8) == "Halfling"){
        if(gender == "M"){
          output[0] += halflingMaleNames[randomindex(halflingMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += halflingFemaleNames[randomindex(halflingFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += halflingLastNames[randomindex(halflingLastNames.length)];
      }
      else if(race.slice(0,10) == "Dragonborn"){
        if(gender == "M"){
          output[0] += dragonbornMaleNames[randomindex(dragonbornMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += dragonbornFemaleNames[randomindex(dragonbornFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += dragonbornLastNames[randomindex(dragonbornLastNames.length)];
      }
      else if(race.slice(0,5) == "Gnome"){
        if(gender == "M"){
          output[0] += gnomeMaleNames[randomindex(gnomeMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += gnomeFemaleNames[randomindex(gnomeFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
          output[1] += "LASTNAMER SCREWED UP";
        }
    
        output[1] += gnomeLastNames[randomindex(gnomeLastNames.length)];
    
        var nicknamenum = randomindex(6);
        for(let i = 0; i < nicknamenum; i++){
          output[2] += gnomeNicknames[randomindex(gnomeNicknames.length)] + " ";
        }
      }
      else if(race.slice(0,6) == "Kobold"){
        if(gender == "M"){
          output[0] += koboldMaleNames[randomindex(koboldMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += koboldFemaleNames[randomindex(koboldFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += "";
      }
      else if(race.slice(0,3) == "Orc"){
        if(gender == "M"){
          output[0] += orcMaleNames[randomindex(orcMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += orcFemaleNames[randomindex(orcFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
      }
      else if(race.slice(0,8) == "Tiefling"){
        if(is_containedin_("Lawful",race)){
          output[0] += tieflingLawfulNames[randomindex(tieflingLawfulNames.length)];
        }
        else if(is_containedin_("Chad",race)){
          output[0] += tieflingChadNames[randomindex(tieflingChadNames.length)];
        }
        else if(is_containedin_("Smart",race)){
          output[0] += tieflingSmartNames[randomindex(tieflingSmartNames.length)];
        }
        else if(is_containedin_("Chaotic",race)){
          output[0] += tieflingChaoticNames[randomindex(tieflingChaoticNames.length)];
        }
        else if(is_containedin_("Sad",race)){
          output[0] += tieflingSadNames[randomindex(tieflingSadNames.length)];
        }
        else if(is_containedin_("Stupid",race)){
          output[0] += tieflingStupidNames[randomindex(tieflingStupidNames.length)];
        }
        else if(is_containedin_("Good",race)){
          output[0] += tieflingGoodNames[randomindex(tieflingGoodNames.length)];
        }
        else if(is_containedin_("Horny",race)){
          output[0] += tieflingHornyNames[randomindex(tieflingHornyNames.length)];
        }
        else if(is_containedin_("Evil",race)){
          output[0] += tieflingEvilNames[randomindex(tieflingEvilNames.length)];
        }
        else if(is_containedin_("Neutral",race)){
          output[0] += tieflingNeutralNames[randomindex(tieflingNeutralNames.length)];
        }
        else{
          if(gender == "M"){
            output[0] += tieflingMaleNames[randomindex(orcMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += tieflingFemaleNames[randomindex(orcFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
        }
        output[1] += tieflingLastNames[randomindex(tieflingLastNames.length)];
      }
      else if(race == "Fire Genasi"){
        if(gender == "M"){
          output[0] += fireGenasiMaleNames[randomindex(fireGenasiMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += fireGenasiFemaleNames[randomindex(fireGenasiFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += fireGenasiLastNames[randomindex(fireGenasiLastNames.length)];
      }
      else if(race.slice(0,7) == "Firbolg"){
        if(gender == "M"){
          output[0] += firbolgMaleNames[randomindex(firbolgMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += firbolgFemaleNames[randomindex(firbolgFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += firbolgLastNames[randomindex(firbolgLastNames.length)];
      }
      else if(race == "Air Genasi"){
        if(gender == "M"){
          output[0] += airGenasiMaleNames[randomindex(airGenasiMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += airGenasiFemaleNames[randomindex(airGenasiFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += airGenasiLastNames[randomindex(airGenasiLastNames.length)];
      }
      else if(race == "Water Genasi"){
        if(gender == "M"){
          output[0] += waterGenasiMaleNames[randomindex(waterGenasiMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += waterGenasiFemaleNames[randomindex(waterGenasiFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += waterGenasiLastNames[randomindex(waterGenasiLastNames.length)];
      }
      else if(race == "Earth Genasi"){
        if(gender == "M"){
          output[0] += earthGenasiMaleNames[randomindex(earthGenasiMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += earthGenasiFemaleNames[randomindex(earthGenasiFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += earthGenasiLastNames[randomindex(earthGenasiLastNames.length)];
      }
      else if(race.slice(0,6) == "Tabaxi"){
        if(ischild){
          output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " Kit";
        }
        else{
          ischild = Math.random();
          if(ischild < 0.5){
            output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " Paw";
          }
          else if(ischild < 0.99){
            output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " " + tabaxiNames[randomindex(tabaxiNames.length)];
          }
          else{
            output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " Star";
          }
        }
      }
      else if(race.slice(0,6) == "Tortle"){
        if(gender == "M"){
          output[0] += tortleMaleNames[randomindex(tortleMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += tortleFemaleNames[randomindex(tortleFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += tortleLastNames[randomindex(tortleLastNames.length)];
      }
      else if(race == "Fey"){
        output[0] += feyNames[randomindex(feyNames.length)];
      }
      else if(race.slice(0,5) == "Owlin"){
        if(gender == "M"){
          output[0] += owlinMaleNames[randomindex(owlinMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += owlinFemaleNames[randomindex(owlinFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += owlinLastNames[randomindex(owlinLastNames.length)];
      }
      else if(race.slice(0,7) == "Bugbear"){
        if(gender == "M"){
          output[0] += bugbearMaleNames[randomindex(bugbearMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += bugbearFemaleNames[randomindex(bugbearFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
      }
      else if(race == "Centaur"){
        if(gender == "M"){
          output[0] += centaurMaleNames[randomindex(centaurMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += centaurFemaleNames[randomindex(centaurFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += centaurLastNames[randomindex(centaurLastNames.length)];
      }
      else if(race.slice(0,4) == "Gith"){
        if(race.slice(4,9) == "yanki"){
          if(gender == "M"){
            output[0] += githyankiMaleNames[randomindex(githyankiMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += githyankiFemaleNames[randomindex(githyankiFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += githyankiLastNames[randomindex(githyankiLastNames.length)];
        }
        else if(race.slice(4,9) == "zerai"){
          if(gender == "M"){
            output[0] += githzeraiMaleNames[randomindex(githzeraiMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += githzeraiFemaleNames[randomindex(githzeraiFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += githzeraiLastNames[randomindex(githzeraiLastNames.length)];
        }
        else{
          output[0] +="UNKNOWN_GITH";
          output[1] +="UNKNOWN_GITH";
        }
      }
      else if(is_containedin_("oblin",race)){
        if(gender == "M"){
          output[0] += goblinMaleNames[randomindex(orcMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += goblinFemaleNames[randomindex(orcFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
      }
      else if(race == "Goliath"){
        if(gender == "M"){
          output[0] += goliathMaleNames[randomindex(goliathMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += goliathFemaleNames[randomindex(goliathFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += goliathLastNames[randomindex(goliathLastNames.length)];
      }
      else if(race == "Lizardfolk"){
        if(gender == "M"){
          output[0] += lizardfolkMaleNames[randomindex(lizardfolkMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += lizardfolkFemaleNames[randomindex(lizardfolkFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
      }
      else if(race == "Triton"){
        output[0] += tritonFirstNames[randomindex(tritonFirstNames.length)];
        output[1] += tritonLastNames[randomindex(tritonLastNames.length)];
      }
      else if(race == "Warforged"){
        if(Math.random() < 0.5){
          output[0] += warforgedNames[randomindex(warforgedNames.length)];
        }
        else{
          var acroindex = randomindex(warforgedAcron.length);
          output[0] += warforgedAcron[acroindex];
          output[1] += warforgedExpan[acroindex];
          if(is_containedin_("Elimin", output[1])){
            if(Math.random() < 0.5){
              output[1] += lmalefirstnames[randomindex(lmalefirstnames.length)] + " " + flastnames[randomindex(flastnames.length)];
            }
            else{
              output[1] += lfemalefirstnames[randomindex(lfemalefirstnames.length)] + " " + flastnames[randomindex(flastnames.length)];
            }
            output[1] += ")";
          }
        }
      }
      else if(race == "Dohwar"){
        if(gender == "M"){
          output[0] += dohwarMaleNames[randomindex(dohwarMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += dohwarFemaleNames[randomindex(dohwarFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += dohwarLastNames[randomindex(dohwarLastNames.length)];
      }
      else if(race == "Vedalken"){
        if(gender == "M"){
          output[0] += vedalkenMaleNames[randomindex(vedalkenMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += vedalkenFemaleNames[randomindex(vedalkenFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += vedalkenLastNames[randomindex(vedalkenLastNames.length)];
      }
      else if(race == "Leonin"){
        if(gender == "M"){
          output[0] += leoninMaleNames[randomindex(leoninMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += leoninFemaleNames[randomindex(leoninFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += leoninLastNames[randomindex(leoninLastNames.length)];
      }
      else if(race == "Aarakocra"){
        if(gender == "M"){
          output[0] += aarakocraMaleNames[randomindex(aarakocraMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += aarakocraFemaleNames[randomindex(aarakocraFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += aarakocraLastNames[randomindex(aarakocraLastNames.length)];
      }
      else if(race == "Harengon"){
        if(gender == "M"){
          output[0] += harengonMaleNames[randomindex(harengonMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += harengonFemaleNames[randomindex(harengonFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += harengonLastNames[randomindex(harengonLastNames.length)];
      }
      else if(is_containedin_("Neufolk",race)){
        if(is_containedin_("Verdi",race) || is_containedin_("Zurri",race)){
          if(gender == "M"){
            output[0] += neufolkZurriMaleNames[randomindex(neufolkZurriMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += neufolkZurriFemaleNames[randomindex(neufolkZurriFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += neufolkZurriLastNames[randomindex(neufolkZurriLastNames.length)];
        }
        else if(is_containedin_("Grigii",race)){
          if(gender == "M"){
            output[0] += neufolkGrigiiMaleNames[randomindex(neufolkGrigiiMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += neufolkGrigiiFemaleNames[randomindex(neufolkGrigiiFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += neufolkGrigiiLastNames[randomindex(neufolkGrigiiLastNames.length)];
        }
        else if(is_containedin_("Rossi",race)){
          if(gender == "M"){
            output[0] += neufolkRossiMaleNames[randomindex(neufolkRossiMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += neufolkRossiFemaleNames[randomindex(neufolkRossiFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += neufolkRossiLastNames[randomindex(neufolkRossiLastNames.length)];
        }
        else if(is_containedin_("Violi",race)){
          if(gender == "M"){
            output[0] += neufolkVioliMaleNames[randomindex(neufolkVioliMaleNames.length)];
          }
          else if(gender == "F"){
            output[0] += neufolkVioliFemaleNames[randomindex(neufolkVioliFemaleNames.length)];
          }
          else{
            output[0] += "GENDER SCREWED UP";
          }
          output[1] += neufolkVioliLastNames[randomindex(neufolkVioliLastNames.length)];
        }
        else{
          output[0] += "UNKOWN NEUFOLK";
          output[1] += "UNKOWN NEUFOLK";
        }
      }
      else if(race == "Milifian"){
        if(gender == "M"){
          output[0] += milifianMaleNames[randomindex(milifianMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += milifianFemaleNames[randomindex(milifianFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += milifianLastNames[randomindex(milifianLastNames.length)];
      }
      else if(race == "Hadozee"){
        if(gender == "M"){
          output[0] += hadozeeMaleNames[randomindex(hadozeeMaleNames.length)];
          output[2] += hadozeeMaleNames[randomindex(hadozeeMaleNames.length)] + " ";
        }
        else if(gender == "F"){
          output[0] += hadozeeFemaleNames[randomindex(hadozeeFemaleNames.length)];
          output[2] += hadozeeFemaleNames[randomindex(hadozeeFemaleNames.length)] + " ";
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += hadozeeLastNames[randomindex(hadozeeLastNames.length)];
      }
      else if(race == "Thri-kreen"){
        output[0] += thrikreenUpperFirstNames[randomindex(thrikreenUpperFirstNames.length)];
        for(let i = 0; i< randomindex(3)+2; i++){
          output[0] += thrikreenLowerFirstNames[randomindex(thrikreenLowerFirstNames.length)];
        }
        output[1] += thrikreenLastNames[randomindex(thrikreenLastNames.length)];
      }
      else if(race == "Kenku"){
        output[0] += kenkuNames[randomindex(kenkuNames.length)];
      }
      else if(race == "Loxodon"){
        if(gender == "M"){
          output[0] += loxodonMaleNames[randomindex(loxodonMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += loxodonFemaleNames[randomindex(loxodonFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += loxodonLastNames[randomindex(loxodonLastNames.length)];
      }
      else if(race == "Verdan"){
        output[0] += verdanNames[randomindex(verdanNames.length)];
      }
      else if(race == "Plasmoid"){
        output[0] += plasmoidNames[randomindex(plasmoidNames.length)];
      }
      else if(race == "Grung"){
        if(gender == "M"){
          output[0] += grungMaleNames[randomindex(grungMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += grungFemaleNames[randomindex(grungFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += grungLastNames[randomindex(grungLastNames.length)];
      }
      else if(race == "Locathah"){
        if(gender == "M"){
          output[0] += locathahMaleNames[randomindex(locathahMaleNames.length)];
        }
        else if(gender == "F"){
          output[0] += locathahFemaleNames[randomindex(locathahFemaleNames.length)];
        }
        else{
          output[0] += "GENDER SCREWED UP";
        }
        output[1] += locathahLastNames[randomindex(locathahLastNames.length)];
      }
      else if(race == "Autognome"){
        output[0] += autognomeNames[randomindex(autognomeNames.length)];
      }
      //choosenamebottom
      else{
        output[0] += "<font color='red'>FIRST_NAME</font>";
        output[1] += "<font color='red'>LAST_NAME</font>";  
      }
    
      output[0] += "</abbr>";
      output[1] += "</abbr>";
      output[2] += "</abbr>";
      return output;
    }
    
  7. Choose Class
    function chooseClass(topstat, secstat){
      var randomnum = Math.random();
      //Highest stat STR
      if(topstat == 0){
        //STR --> DEX
        if(secstat == 1){
          return "Fighter";
        }
        //STR --> CON
        else if(secstat == 2){
          if(randomnum < 0.5){
            return "Fighter";
          }
          else{
            return "Barbarian";
          }
        }
        //STR --> INT
        else if(secstat == 3){
          if(randomnum < 0.98){
            return "Fighter";
          }
          else{
            return "Wizard";
          }
        }
        //STR --> WIS
        else if(secstat == 4){
          if(randomnum < 0.75){
            return "Ranger";
          }
          else{
            return "Fighter";
          }
        }
        //STR --> CHA
        else if(secstat == 5){
          if(randomnum < 0.8){
            return "Paladin";
          }
          else{
            return "Fighter";
          }
        }
        else{
          alert("ERROR: Something went wrong with secstat. topstat = 0");
        }
      }
      //Highest stat DEX
      else if(topstat == 1){
        //DEX --> STR
        if(secstat == 0){
          if(randomnum < 0.75){
            return "Fighter";
          }
          else{
            return "Rogue";
          }
        }
        //DEX --> CON
        else if(secstat == 2){
          return "Rogue";
        }
        //DEX --> INT
        else if(secstat == 3){
          return "Rogue";
        }
        //DEX --> WIS
        else if(secstat == 4){
          if(randomnum < 0.3){
            return "Monk";
          }
          else if(randomnum < 0.6){
            return "Ranger";
          }
          else if(randomnum < 0.9){
            return "Druid";
          }
          else{
            return "Rogue";
          }
        }
        //DEX --> CHA
        else if(secstat == 5){
          if(randomnum < 0.3){
            return "Rogue";
          }
          else if(randomnum < 0.6){
            return "Sorcerer";
          }
          else if(randomnum < 0.9){
            return "Warlock";
          }
          else{
            return "Bard";
          }
        }
        else{
          alert("ERROR: Something went wrong with secstat. topstat = 1");
        }
      }
      //Highest stat CON
      else if(topstat == 2){
        //CON --> STR
        if(secstat == 0){
          return "Barbarian";
        }
        //CON --> DEX
        else if(secstat == 1){
          return "Rogue";
        }
        //CON --> INT
        else if(secstat == 3){
          return "Wizard";
        }
        //CON --> WIS
        else if(secstat == 4){
          return "Cleric";
        }
        //CON --> CHA
        else if(secstat == 5){
          return "Sorcerer";
        }
        else{
          alert("ERROR: Something went wrong with secstat. topstat = 2");
        }
      }
      //Highest stat INT
      else if(topstat == 3){
        //INT --> STR
        if(secstat == 0){
          return "Artificer";
        }
        //INT --> DEX
        else if(secstat == 1){
          if(randomnum < 0.5){
            return "Wizard";
          }
          else{
            return "Artificer";
          }
        }
        //INT --> CON
        else if(secstat == 2){
          if(randomnum < 0.66){
            return "Wizard";
          }
          else{
            return "Artificer";
          }
        }
        //INT --> WIS
        else if(secstat == 4){
          return "Wizard";
        }
        //INT --> CHA
        else if(secstat == 5){
          return "Wizard";
        }
        else{
          alert("ERROR: Something went wrong with secstat. topstat = 3");
        }
      }
      //Highest stat WIS
      else if(topstat == 4){
        //WIS --> STR
        if(secstat == 0){
          if(randomnum < 0.75){
            return "Ranger";
          }
          else{
            return "Cleric";
          }
        }
        //WIS --> DEX
        else if(secstat == 1){
          if(randomnum < 0.75){
            return "Monk";
          }
          else{
            return "Ranger";
          }
        }
        //WIS --> CON
        else if(secstat == 2){
          if(randomnum < 0.45){
            return "Cleric";
          }
          else if(randomnum < 0.9){
            return "Druid";
          }
          else{
            return "Ranger";
          }
        }
        //WIS --> INT
        else if(secstat == 3){
          if(randomnum < 0.8){
            return "Cleric";
          }
          else{
            return "Druid";
          }
        }
        //WIS --> CHA
        else if(secstat == 5){
          return "Cleric";
        }
        else{
          alert("ERROR: Something went wrong with secstat, topstat = 4");
        }
      }
      //Highest stat CHA
      else if(topstat == 5){
        //CHA --> STR
        if(secstat == 0){
          if(randomnum < 0.4){
            return "Paladin";
          }
          else if(randomnum < 0.8){
            return "Bard";
          }
          else{
            return "Warlock";
          }
        }
        //CHA --> DEX
        else if(secstat == 1){
          if(randomnum < 0.5){
            return "Bard";
          }
          else{
            return "Sorcerer";
          }
        }
        //CHA --> CON
        else if(secstat == 2){
          if(randomnum < 0.33){
            return "Warlock";
          }
          else if(randomnum < 0.66){
            return "Bard";
          }
          else{
            return "Sorcerer";
          }
        }
        //CHA --> INT
        else if(secstat == 3){
          if(randomnum < 0.45){
            return "Warlock";
          }
          else if(randomnum < 0.9){
            return "Sorcerer";
          }
          else{
            return "Bard";
          }
        }
        //CHA --> WIS
        else if(secstat == 4){
          return "Warlock";
        }
        else{
          alert("ERROR: Something went wrong with secstat. topstat = 5");
        }
      }
      else{
        return "ERROR: Something went wrong with topstat";
      }
    }
    

4.3.8. Text Manipulation

  1. Capitalize
    function cap(strin){
      strin = strin[0].toUpperCase() + strin.slice(1-strin.length);
      return strin;
    }
    
  2. Subjective Pronoun
    Gender Word
    Male He
    Female She
    Nonbinary They
    function sub(gender){
      if(gender == "M"){
        return "he";
      }
      else if(gender == "F"){
        return "she";
      }
      else if(gender == "NB"){
        return "they";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  3. Objective Pronoun
    function obj(gender){
      if(gender == "M"){
        return "him";
      }
      else if(gender == "F"){
        return "her";
      }
      else if(gender == "NB"){
        return "them";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  4. Posessive Pronoun
    function pos(gender){
      if(gender == "M"){
        return "his";
      }
      else if(gender == "F"){
        return "her";
      }
      else if(gender == "NB"){
        return "their";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  5. Is Conjugation
    function is(gender){
      if(gender == "M"){
        return "is";
      }
      else if(gender == "F"){
        return "is";
      }
      else if(gender == "NB"){
        return "are";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  6. Has Conjugation
    function has(gender){
      if(gender == "M"){
        return "has";
      }
      else if(gender == "F"){
        return "has";
      }
      else if(gender == "NB"){
        return "have";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  7. Was Conjugation
    function was(gender){
      if(gender == "M"){
        return "was";
      }
      else if(gender == "F"){
        return "was";
      }
      else if(gender == "NB"){
        return "were";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  8. Verb Conjugation
    function ess(gender){
      if(gender == "M"){
        return "s";
      }
      else if(gender == "F"){
        return "s";
      }
      else if(gender == "NB"){
        return "";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  9. Kid Word
    function kidword(gender){
      if(gender == "M"){
        return "boy";
      }
      else if(gender == "F"){
        return "girl";
      }
      else if(gender == "NB"){
        return "kid";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  10. Adult Word
    function adultword(gender){
      if(gender == "M"){
        return "man";
      }
      else if(gender == "F"){
        return "woman";
      }
      else if(gender == "NB"){
        return "person";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  11. Parent Word
    function parent(gender){
      if(gender == "M"){
        return "father";
      }
      else if(gender == "F"){
        return "mother";
      }
      else if(gender == "NB"){
        return "parent";
      }
      else{
        return "<font color='red'>ERROR</font>";
      }
    }
    
  12. Format Name
    function formname(namearray){
      return namearray[0] + " " + namearray[1];
    }
    

4.3.9. Birth

  1. Type
    function birthtype(race){
      if(race == "Aarakocra" || race == "Thri-kreen" || is_containedin_("Dragonborn",race) || race == "Dohwar" || race == "Kenku" || race == "Tortle" || race == "Lizardfolk"){
        return "hatched";
      }
      else if(race == "Warforged" || race == "Autognome"){
        return "assembled";
      }
      else if(race == "Plasmoid"){
        return "split";
      }
      else{
        return "born";
      }
    }
    
  2. Phrase
    function birthphrase(race){
      if(race == "Aarakocra" || race == "Thri-kreen" || is_containedin_("Dragonborn",race) || race == "Dohwar" || race == "Kenku" || race == "Tortle" || race == "Lizardfolk"){
        return "hatched by";
      }
      else if(race == "Warforged" || race == "Autognome"){
        return "assembled by";
      }
      else if(race == "Plasmoid"){
        return "split from";
      }
      else{
        return "born to";
      }
    }
    
  3. Adjective
    function birthadj(race){
      if(race == "Aarakocra" || race == "Thri-kreen" || is_containedin_("Dragonborn",race) || race == "Dohwar" || race == "Kenku" || race == "Tortle" || race == "Lizardfolk"){
        return "hatch";
      }
      else if(race == "Warforged" || race == "Autognome"){
        return "assemble";
      }
      else if(race == "Plasmoid"){
        return "split";
      }
      else{
        return "birth";
      }
    }
    

4.3.10. Backstory

function backstory(){
  var b_story = "Backstory (wip):<br>";                   //stores the long backstory formatting string
  var tablarray = [];                           //an array that holds the contents of the backstory table
  var possibclas = [];                          //an array that holds possible backstory paths the player could take and their weights
  var bslist = [];                            //an array that holds the backstory paths the player will go down
  var weightot = 0;                             //keeps track of the total of weights from paths in possibs
  var pathselector = 0;                           //stores the random selection for each backstory path
  var adoptiondate = 0;                           //date of the players adoptiong, if applicable
  var recurringsymbol = logos[randomindex(logos.length)];         //for keeping track of a recurring symbol in the backstory
  var mentor = [["FIRST_NAME","LAST_NAME"],chooseGender(),chooseAlignment()];         //Players mentor
  mentor[0] = choosename(chooseRace()[0],mentor[1],mentor[2]);
  while(mentor[0] == "<font color='red'>FIRST_NAME</font>"){
    mentor[0] = choosename(chooseRace()[0],mentor[1],mentor[2]);
  }
  tavern = "The "+tavernadj[randomindex(tavernadj.length)]+" "+tavernnoun[randomindex(tavernnoun.length)];
  var namestolen = 2;                           //Players name stolen    0 = name needs to be stolen
  var namestolenp1 = 2;                           //Parent 1s name stolen  1 = name already stolen
  var namestolenp2 = 2;                           //Parent 2s name stolen  2 = name not stolen
  var shortestindex = [0,player.birthday + 36525];            //forgot what this is for. its in the sorting phase somewhere
  var holdingvar = [];                          //for holding a table row in the sorting phase
  var currentdate = player.birthday;                    //for keeping track of dates in ordered events
  var maturage = 0.626785414373 * (player.race[1]**0.766203192397);      //age of maturity
  var normaturage = maturage / (0.626785414373 * (humanlist[0][1]**0.766203192397));  //age of maturity normalized to human development

  //write backstory events and dates in a 2d array
  tablarray.push([player.birthday,player.fullname[0] + " is " + birthtype(player.race[0]) + "."]);
  tablarray.push([dateToDays([daysToDate(player.birthday)[0],daysToDate(player.birthday)[1],daysToDate(player.birthday)[2]+Math.floor(maturage)]),"<font color=#C5C59C>" + player.fullname[0] + " becomes an adult.</font>"]);
  tablarray.push([dateToDays([daysToDate(player.birthday)[0],daysToDate(player.birthday)[1],daysToDate(player.birthday)[2]+Math.floor(player.race[1])]),"<font color=#C5C59C>" + player.fullname[0] + " reaches " + pos(player.gender) + " life expectancy.</font>"]);

  //console.log(dateToDATE(daysToDate(player.birthday)));
  //console.log(dateToDATE([daysToDate(player.birthday)[0],daysToDate(player.birthday)[1],daysToDate(player.birthday)[2]+Math.floor(maturage)]));

  //ordering test
  //for(let i = 0; i < 10; i++){
  //  tablarray.push([player.birthday + randomindex(1000),"event " + i]);
  //}

  //Name-stealing prep
  if(player.fullname[0] == "<abbr title=\"Fey\"></abbr>"){
    namestolen = 0;
  }
  if(player.parent1.fullname[0] == "<abbr title=\"Fey\"></abbr>"){
    namestolenp1 = 0;
  }
  if(player.parent2.fullname[0] == "<abbr title=\"Fey\"></abbr>"){
    namestolenp2 = 0;
  }

  //adoption
  if(player.adopted){
    if(!player.adoptedLate){
      adoptiondate = player.birthday + normaldist(365*3);
    }
    else{
      adoptiondate = player.birthday + normalyear(10);
    }
  }
  if(player.adopted){
    if(!player.adoptedLate){
      tablarray.push([adoptiondate,player.fullname[0] + " is adopted by " + formname(player.parent1.fullname) + " and " + formname(player.parent2.fullname) + "."]);
    }
    else{
      tablarray.push([adoptiondate,player.fullname[0] + " is adopted by " + formname(player.parent1.fullname) + " and " + formname(player.parent2.fullname) + "."]);
    }
  }

  //kill single parent
  if(player.parent1.dead != player.parent2.dead){
    if(player.parent1.dead == " (dead)"){
      if(player.locale == "urban"){
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(366*12.5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent1.fullname[0] + ", hitting " + obj(player.parent1.gender) + " in the neck and killing " + obj(player.parent1.gender) + " while " + sub(player.parent1.gender) + " " + was(player.parent1.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent1.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent1.fullname[0] + ", hitting " + obj(player.parent1.gender) + " in the neck and killing " + obj(player.parent1.gender) + " while " + sub(player.parent1.gender) + " " + was(player.parent1.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent1.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent1.fullname[0] + ", hitting " + obj(player.parent1.gender) + " in the neck and killing " + obj(player.parent1.gender) + " while " + sub(player.parent1.gender) + " " + was(player.parent1.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent1.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
      }
      else{  //rural
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(365*12.5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent1.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent1.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent1.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
      }
    }
    else{  //parent 2 is dead
      if(player.locale == "urban"){
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(366*12.5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent2.fullname[0] + ", hitting " + obj(player.parent2.gender) + " in the neck and killing " + obj(player.parent2.gender) + " while " + sub(player.parent2.gender) + " " + was(player.parent2.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent2.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent2.fullname[0] + ", hitting " + obj(player.parent2.gender) + " in the neck and killing " + obj(player.parent2.gender) + " while " + sub(player.parent2.gender) + " " + was(player.parent2.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent2.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent2.fullname[0] + ", hitting " + obj(player.parent2.gender) + " in the neck and killing " + obj(player.parent2.gender) + " while " + sub(player.parent2.gender) + " " + was(player.parent2.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent2.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
      }
      else{  //rural
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(365*12.5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent2.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent2.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent2.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
      }
    }
  }


  //parent profession stuff

  //highest stat stuff
  if(player.statorder[0] == 0){    //strength
    currentdate = player.birthday + yearToDay(12) + normalyear(4);
    if(player.alignment[1] == "Stupid" && Math.random() < 0.5){
      tablarray.push([currentdate,"A rock, about the size of a bowling ball, catches " + player.fullname[0] + "'s eye. It vaguely resembled a smiley-face, so " + sub(player.gender) + " carried it home."]);
      currentdate += normalyear(0.7);
      tablarray.push([currentdate,"Carrying the rock with " + obj(player.gender) + " at all times, caused " + player.fullname[0] + " to build muscle and get stronger than " + pos(player.gender) + " peers."]);
    }
    else if(player.alignment[0]){
    }
  }
  else if(player.statorder[0] = 1){  //dexterity
  }
  else if(player.statorder[0] = 2){  //constitution
  }
  else if(player.statorder[0] = 3){  //intelligence
  }
  else if(player.statorder[0] = 4){  //wisdom
  }
  else{          //charisma
  }

  //class stuff
  if(player.clas == "Artificer"){
    possibclas.push(["Artificer_default",1]);
    if(player.alignment[1] == "Stupid" || player.stats[4] < 10){
      possibclas.push["Artificer_binney",10];
      // 
    }
  }
  else if(player.clas == "Barbarian"){
    possibclas.push(["Barbarian_default",1]);
    if(player.alignment[1] == "Good" || player.alignment[1] == "Stupid"){
      possibclas.push(["Barbarian_mythra",10]);
      // grows up in a remote village, chopping trees
      // parents talk to the player and tell them it is time to find themselves by going on a quest
      // the player decides to prove themself by defeating a very powerful creature (subjective)
    }
  }
  else if(player.clas == "Bard"){
    possibclas.push(["Bard_default",1]);
    // 
    if(player.alignment[1] != "Good" && player.alignment[1] != "Stupid" && player.socialclass == "poor"){
      if(player.alignment[1] == "Evil"){
        possibclas.push(["Bard_scammer",10]);
        // player is starving and is forced to steal bread. they lie to the baker, telling them a very wealthy person will arrive soon. the baker starts baking more breads and the player steals what they can while the bakers back is turned.
        // the player tells a similar lie to get better food
        // the player does it again to get fine clothes (random color/style)
        // lies to get fine jewelery (similarly random)
        // lies to get an audience with the mayor or whatever and convinces them that the bakers bakery is rightfully theirs and so aquires the deed
        // the player kicks the baker out of thier home/workplace with the power of the city guard behind them
      }
      else{
        possibclas.push(["Bard_charlatan"],10);
        // is a nonmagical illusionist
        // a wizard notices the players skill and mistakes it for arcane talent
        // the player attends wizard school, faking their way through
        // the player realizes that their pure charisma is able to conjure magic even though their technique sucks
      }
    }
    if(player.sad == 1){
      possibclas.push(["Bard_distraction",10]);
    }
    if(player.stats[0] < 10 || player.stats[2] < 10){
      possibclas.push(["Bard_old_adventurer",10]);
    }
  }
  else if(player.clas == "Cleric"){
    possibclas.push(["Cleric_default",1]);
    if(player.alignment[0] == "Lawful" && player.alignment[1] == "Good" && player.parent1.profession != "Cleric" && player.parent1.profession != "Cleric"){
      possibclas.push(["Cleric_found_god",10]);
    }
  }
  else if(player.clas == "Druid"){
    possibclas.push(["Druid_default",1]);
  }
  else if(player.clas == "Fighter"){
    possibclas.push(["Fighter_default",1]);
  }
  else if(player.clas == "Monk"){
    possibclas.push(["Monk_default",1]);
    if(player.socialclass == "wealthy"){
      if(player.sad == 1){
        possibclas.push(["Monk_sad_batman",10]);
      }
      else{
        possibclas.push(["Monk_batman",10]);
      }
    }
  }
  else if(player.clas == "Paladin"){
    possibclas.push(["Paladin_default",1]);
    if(player.parent1.dead == " (dead)" || player.parent2.dead == " (dead)"){
      possibclas.push(["Paladin_revenge",10]);
    }
  }
  else if(player.clas == "Ranger"){
    possibclas.push(["Ranger_default",1]);
    if(player.sad == 1){
      if(player.parent1.dead == 1 || player.parent2.dead == 1){
        possibclas.push(["Ranger_sad_parent",10]);
      }
      else{
        possibclas.push(["Ranger_sad_pet",10]);
      }
    }
  }
  else if(player.clas == "Rogue"){
    possibclas.push(["Rogue_default",1]);
    if(player.socialclass == "wealthy"){
      if(player.sad == 1){
        possibclas.push(["Rogue_sad_batman",10]);
      }
      else{
        possibclas.push(["Rogue_batman",10]);
      }
    }
  }
  else if(player.clas == "Sorcerer"){
    if(daysToDate(player.birthday)[1] == 2 && daysToDate(player.birthday)[0] == 29){
      //Leap day sorcerer
      possibclas.push(["Sorcerer_leap",100]);
    }
    else if(daysToDate(player.birthday)[1] <= 2 || daysToDate(player.birthday)[1] == 12){
      //Winter sorcerer
      possibclas.push(["Sorcerer_winter",1]);
    }
    else if(daysToDate(player.birthday)[1] <= 5){
      //Spring sorcerer
      possibclas.push(["Sorcerer_Spring",1]);
    }
    else if(daysToDate(player.birthday)[1] <= 8){
      //Summer sorcerer
      possibclas.push(["Sorcerer_Summer",1]);
    }
    else if(daysToDate(player.birthday)[1] <= 11){
      //Autumn sorcerer
      possibclas.push(["Sorcerer_autumn",1]);
    }
    else{
      possibclas.push(["Sorcerer_default",1]);
    }
  }
  else if(player.clas == "Warlock"){
    possibclas.push(["Warlock_default",1]);
  }
  else if(player.clas == "Wizard"){
    //Defalut wizard
    possibclas.push(["Wizard_default",1]);
    //Charlatan wizard
    if(statRank(5,player.statorder) < 2 && player.alignment[1] == "Evil"){
      possibclas.push(["Wizard_charlatan",10]);
    }
    if(player.alignment[0] == "Smart" || player.stats[3] == 18){
      //Insane wizard
      if(player.alignment[1] == "Stupid" || statRank(4,player.statorder) >= 4){
        possibclas.push(["Wizard_insane",10]);
        // goes to wizard school
        // gets into trouble experimenting
        // accidentally traps roommate in (now) sentient magic item
        // gets kicked out of wizard school
      }
      //Genius wizard
      possibclas.push(["Wizard_genius",10]);
      // is spotted by an older wizard who sees potential in the player
      // goes to wizard school and knocks it out of the park
      // invents womething extraordinary, now people are after the player for the details
    }
    if(player.race[0] != "Yuan-ti" && player.stats[4] < 8 && player.alignment[1] != "Evil"){
      possibclas.push(["Wizard_truman",7]);
    }
    //Dumb-Luck wizard
    if(player.alignment[1] == "Stupid" && player.stats[3] < 10){
      possibclas.push(["Wizard_dumb-luck",10]);
    }
    //Altruist wizard
    if(player.alignment[1] == "Good"){
      possibclas.push(["Wizard_altruist",10]);
    }
  }
  else{
    possibclas.push(["What_class_default",1]);
  }

  //decide backstory paths
  //class
  for(let i = 0; i < possibclas.length; i++){
    weightot += possibclas[i][1];    //sum the weights
  }
  pathselector = randomindex(weightot);
  console.log(possibclas);
  console.log("Total of Weights = " + weightot);
  console.log("Path Selector =  " + pathselector);
  for(let i = 0; i < possibclas.length; i++){
    pathselector -= possibclas[i][1];
    console.log("Path Selector =  " + pathselector);
    if(pathselector <= 0){
      bslist.push(possibclas[i]);
      break;
    }
  }

  console.log(bslist);

  //expand class backstory paths to events
          tablarray.push([player.birthday+1,bslist[0][0] + " backstory"]);
          if(player.clas == "Artificer"){
    if(bslist[0][0] == "Artificer_default"){
      currentdate = Math.round(player.birthday+(((6*365)+normalyear(8))*normaturage));
      tablarray.push([currentdate,mentor[0][0]+" "+mentor[0][1]+", a local smith and tinker, teaches "+player.fullname[0]+" how to make tiny <a href=\"https://www.dndbeyond.com/species/18-gnome#RockGnome\">clockwork devices</a> and finds "+sub(player.gender)+" "+has(player.gender)+" a knack for it."]);
      currentdate += normaldist(400);
      tablarray.push([currentdate,mentor[0][0]+" continues to teach "+player.fullname[0]+" about smithing and artificing and shows "+obj(player.gender)+" how to use basic magic to send short messages telepathically."]);
      currentdate += normaldist(400);
      if(player.locale == "rural"){
        tablarray.push([currentdate,mentor[0][0]+" asks "+player.fullname[0]+" to help "+obj(mentor[1])+" design and build a bridge just outside "+player.hometown[0]+". "+player.fullname[0]+" feel"+ess(player.gender)+" excited and a bit nervous at the thought of undertaking such a large project."]);
        currentdate += normaldist(45);
        tablarray.push([currentdate,player.fullname[0]+" helps "+mentor[0][0]+" build a bridge just outside "+player.hometown[0]+". "+cap(sub(player.gender))+" feel"+ess(player.gender)+" emboldened upon completing such a large project."]);
      }
      else{
        tablarray.push([currentdate,mentor[0][0]+" asks "+player.fullname[0]+" to help "+obj(mentor[1])+" design and build a crane for stacking crates in a warehouse on the outskirts of "+player.hometown[0]+". "+player.fullname[0]+" is excited and a bit nervous at the thought of undertaking such a large project."]);
        currentdate += normaldist(60);
        tablarray.push([currentdate,player.fullname[0]+" and "+mentor[0][0]+" complete construction on the crane. "+player.fullname[0]+" feel"+ess(player.gender)+" satisfied with having completed such a large and complex project."]);
      }
      currentdate += normalyear(3.5);
      tablarray.push([currentdate,player.fullname[0]+" begins feeling comfortable combining "+pos(player.gender)+" mundane creations with magic on "+pos(player.gender)+" own."]);
    }
  }
  else if(player.clas == "Barbarian"){
    if(bslist[0][0] == "Barbarian_default"){
      currentdate = Math.round(player.birthday+((4*365)+normalyear(4)));
      if(player.locale == "urban"){
        tablarray.push([currentdate,player.fullname[0]+" begins to explore parts of "+player.hometown[0]+" "+pos(player.gender)+" parents told "+obj(player.gender)+" not to go."]);
        currentdate += normaldist(14);
        tablarray.push([currentdate,"A fight breaks out in the "+tavern+", a local tavern, while "+player.fullname[0]+" is there. "+cap(sub(player.gender))+" is hit by a thrown tankard, staggers back and is deeply cut by a stray sword blade across "+pos(player.gender)+" "+bodypartsext[randomindex(bodypartsext.length)]+"."]);
        if(player.parent1.dead != " (dead)" && player.parent2 != " (dead)"){
          tablarray.push([currentdate,player.parent1.fullname[0]+" notices "+player.fullname[0]+"\'s wound and dresses it."]);
        }
        else if(player.parent1.dead == " (dead)"){
          tablarray.push([currentdate,player.parent2.fullname[0]+" notices "+player.fullname[0]+"\'s wound and dresses it."]);
        }
        else if(player.parent2.dead == " (dead)"){
          tablarray.push([currentdate,player.parent1.fullname[0]+" notices "+player.fullname[0]+"\'s wound and dresses it."]);
        }
        else{
          tablarray.push([currentdate,player.fullname[0]+"\'s isn't noticed by anyone because "+sub(player.gender)+" is an orphan."]);
        }
        currentdate += 1;
        tablarray.push([currentdate,player.fullname[0]+" is walking through the city when "+sub(player.gender)+" is stopped by an imposing-looking "+adultword(mentor[1])+". "+mentor[2][1]]);
      }
      else{
        tablarray.push([currentdate,player.fullname[0]+" wanders into the wilderness surrounding "+player.hometown[0]+", in search of adventures like in the stories "+sub(player.gender)+" was told by "+pos(player.gender)+" parents."]);
        currentdate += normaldist(28);
        tablarray.push([currentdate,"Having explored outside of town for several days, "+player.fullname[0]+" is suddenly tackled to the ground by a large "+smallbeasts[randomindex(smallbeasts.length)]+". Mere seconds later, the beast itself is tackled by a "+adultword(mentor[1])+" with an imposing figure. "+player.fullname[0]+" could do nothing but watch with amazement while the unfamiliar "+adultword(mentor[1])+" wrestled "+pos(mentor[1])+" opponent into submission. After the ordeal was over, the "+adultword(mentor[1])+" approached "+player.fullname[0]+".<br>Strange "+adultword(mentor[1])+": That was a close one. I'm "+mentor[0][0]+" "+mentor[0][1]+". Who might you be?<br>"+player.fullname[0]+": uh uhh "+player.fullname[0]+", "+player.fullname[0]+" "+player.fullname[1]+".<br>"+mentor[0][0]+": And where are you from, little "+player.fullname[0]+"?<br>"+player.fullname[0]+": Uh, I'm f-from "+player.hometown[0]+".<br>"+mentor[0][0]+": You're a bit far from home, aren't you? Let's get you back where you belong."]);
        currentdate += 2;
        if(player.parent1.dead != " (dead)" && player.parent2 != " (dead)"){
          tablarray.push([currentdate,"Upon "+player.fullname[0]+" being returned to "+pos(player.gender)+" home in "+player.hometown[0]+", "+player.parent2.fullname[0]+" and "+player.parent1.fullname[0]+" are incredibly relieved to see that their "+kidword(player.gender)+" is safe."]);
        }
        else if(player.parent1.dead != " (dead)"){
          tablarray.push([currentdate,"Upon "+player.fullname[0]+" being returned to "+pos(player.gender)+" home in "+player.hometown[0]+", "+player.parent1.fullname[0]+" is incredibly relieved to see that "+pos(player.parent1.gender)+" "+kidword(player.gender)+" is safe."]);
        }
        else if(player.parent2.dead != " (dead)"){
          tablarray.push([currentdate,"Upon "+player.fullname[0]+" being returned to "+pos(player.gender)+" home in "+player.hometown[0]+", "+player.parent2.fullname[0]+" is incredibly relieved to see that "+pos(player.parent2.gender)+" "+kidword(player.gender)+" is safe."]);
        }
        else{
            tablarray.push([currentdate,"After being led aimlessly through town, "+mentor[0][0]+" realizes that "+player.fullname[0]+" doesn't have parents to be returned to and decides to take"+obj(player.gender)+" under "+pos(mentor[1])+" wing."]);
        }
      }
    }
  }

  //sort array by date
  for(let i = 0; i < tablarray.length; i++){
    shortestindex[1] = tablarray[i][0] + 1000000;
    for(let j = i; j < tablarray.length; j++){
      if(shortestindex[1] > tablarray[j][0]){
        shortestindex = [j,tablarray[j][0]];
      }
    }
    holdingvar = tablarray[i];
    tablarray[i] = tablarray[shortestindex[0]];
    tablarray[shortestindex[0]] = holdingvar;
  }
  //convert array to table
  b_story += "<table>";

  for(let i = 0; i < tablarray.length; i++){
    b_story += "<tr>";
    b_story += "<th>";
    b_story += dateToDATE(daysToDate(tablarray[i][0]));
    b_story += "</th>";
    b_story += "<th>";
    b_story += tablarray[i][1];
    b_story += "</th>";
    b_story += "</tr>";
  }

  b_story += "</table>";

  player.backstory = tablarray;
  return b_story;
}

4.3.11. True Neutral

function trueNeutral(inputalignment){
  //True Neutral
  if(inputalignment[0] == "Neutral" && inputalignment[1] == "Neutral"){
    inputalignment[0] = "True";
  }
  return inputalignment;
}

4.3.12. Alignment

  1. Regular (chooseAlignment)
    function chooseAlignment(){
      var randomnum = Math.random();
      localalignment = ["", ""];
      //Lawfulness
      if(randomnum < 1/3){
        localalignment[0] = "Lawful";
      }
      else if(randomnum < 2/3){
        localalignment[0] = "Neutral";
      }  
      else{
        localalignment[0] = "Chaotic";
      }
      //Goodness
      randomnum = Math.random();
      if(randomnum < 0.48){
        localalignment[1] = "Good";
      }
      else if(randomnum < 0.96){
        localalignment[1] = "Neutral";
      }
      else{
        localalignment[1] = "Evil";
      }
      return localalignment
    }
    
  2. Silly (chooseSillyAlignment)
    function chooseSillyAlignment(){
      var randomnum = Math.random();
      localsillyalignment = ["", ""];
      //Lawfulness
      if(randomnum < 1/6){
        localsillyalignment[0] = "Lawful";
      }
      else if(randomnum < 2/6){
        localsillyalignment[0] = "Chad";
      }  
      else if(randomnum < 3/6){
        localsillyalignment[0] = "Neutral";
      }  
      else if(randomnum < 4/6){
        localsillyalignment[0] = "Smart";
      }  
      else if(randomnum < 5/6){
        localsillyalignment[0] = "Chaotic";
      }  
      else{
        localsillyalignment[0] = "Sad";
      }
      //Goodness
      randomnum = Math.random();
      if(randomnum < 1/5){
        localsillyalignment[1] = "Stupid";
      }
      else if(randomnum < 2/5){
        localsillyalignment[1] = "Good";
      }
      else if(randomnum < 3/5){
        localsillyalignment[1] = "Neutral";
      }
      else if(randomnum < 4/5){
        localsillyalignment[1] = "Horny";
      }
      else{
        localsillyalignment[1] = "Evil";
      }
      return localsillyalignment
    }
    

4.3.13. Roll Character

function rollCharacter(total){
  var statvar = [0,0,0,0,0,0];
  statvar[0] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[1] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[2] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[3] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[4] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[5] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  var statstorage = [0,0,0,0,0,0];
  while(statvar[0]+statvar[1]+statvar[2]+statvar[3]+statvar[4]+statvar[5] != total){
    statvar[0] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[1] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[2] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[3] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[4] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[5] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  }  
  return statvar;
}

4.3.14. Rank Stats

function rankStats(stat0, stat1, stat2, stat3, stat4, stat5){
  var statstorage = [stat0, stat1, stat2, stat3, stat4, stat5];
  var outputarray = [0,0,0,0,0,0];
  var maxstat = 0;
  //rank stats
  for(let i = 0; i < 6; i++){
    maxstat = Math.max(statstorage[0], statstorage[1], statstorage[2], statstorage[3], statstorage[4], statstorage[5]);
    for(let j = 0; j < 6; j++){
      if(statstorage[j] == maxstat){
        outputarray[i] = j;
        statstorage[j] = 0;
        break;
      }
    }
  }
  return outputarray;
}

4.3.15. Statrank

function statRank(statindex, storder){
  var index = 0;
  for(let i = 0; i < 6; i++){
    if(statindex == storder[i]){
      index = i;
      break;
    }
  }
  return index;
}

4.3.16. Display (writeToScreen)

function writeToScreen(){
  //Output to screen
  outputstring = "<div class=\"floatbox\">"
  outputstring = outputstring + "<table>" +
  "<tr>" + "<th>" + "Strength" + "</th>" + "<th>" + player.stats[0] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Dexterity" + "</th>" + "<th>" + player.stats[1] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Constitution" + "</th>" + "<th>" + player.stats[2] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Intelligence" + "</th>" + "<th>" + player.stats[3] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Wisdom" + "</th>" + "<th>" + player.stats[4] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Charisma" + "</th>" + "<th>" + player.stats[5] + "</th>" + "</tr>" + 
  "</table>";
  outputstring = outputstring + "</div>";
  outputstring = outputstring + "<hr>";
  outputstring = outputstring + "<div class=\"floatbox\">"
  outputstring = outputstring + "<table>" + 
  "<tr>" + "<th>" + "Info." + "</th>" + "<th>" + "Player" + "</th>" + "<th>" + "Parent #1" + "</th>" + "<th>" + "Parent #2" + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Name" + "</th>" + "<th>" + player.fullname[0] + " " + player.fullname[2] + player.fullname[1] + "</th>" + "<th>" + player.parent1.fullname[0] + " " + player.parent1.fullname[2] + player.parent1.fullname[1] + player.parent1.dead + "</th>" + "<th>" + player.parent2.fullname[0] + " " + player.parent2.fullname[2] + player.parent2.fullname[1] + player.parent2.dead + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Race" + "</th>" + "<th>" + player.race[0] + player.race2[0] + "</th>" + "<th>" + player.parent1.race[0] + "</th>" + "<th>" + player.parent2.race[0] + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Gender" + "</th>" + "<th>" + player.gender + "</th>" + "<th>" + player.parent1.gender + "</th>" + "<th>" + player.parent2.gender + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Class/Profession" + "</th>" + "<th>" + player.clas + "</th>" + "<th>" + player.parent1.profession + "</th>" + "<th>" + player.parent2.profession + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Alignment" + "</th>" + "<th>" + player.alignment[0] + " " + player.alignment[1] + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Hometown" + "</th>" + "<th>" + player.hometown[1]+ "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Birthdate" + "</th>" + "<th>" + dateToDATE(daysToDate(player.birthday)) + "</th>" + "<th>" + dateToDATE(daysToDate(player.parent1.birthday)) + "</th>" + "<th>" + dateToDATE(daysToDate(player.parent2.birthday)) + "</th>" + "</tr>" + 
    "</table>";
    //outputstring = "STR = " + player.stats[0] + "<br>DEX = " + player.stats[1] + "<br>CON = " + player.stats[2] + "<br>INT = " + player.stats[3] + "<br>WIS = " + player.stats[4] + "<br>CHA = " + player.stats[5] + "<br><br>Name: " + player.fullname[0] + " " + player.fullname[1] + "<br><br>Gender: " + player.gender + "<br>Race: " + player.race[0] + "<br>Class: " + player.clas + "<br>Alignment: " + player.alignment[0] + " " + player.alignment[1];
    outputstring = outputstring + "</div>";
    outputstring = outputstring + "<div class=\"bottombox\">";
    outputstring = outputstring + "<hr>";
    outputstring = outputstring + backstory();
    outputstring = outputstring + "</div>";
    document.getElementById("characteroutput").innerHTML = outputstring;
}

4.4. Complete Program

const racelist = [["Human (Calishite)",80],
  ["Human (Calishite)",80],
  ["Human (Chondathan)",80],
  ["Human (Chondathan)",80],
  ["Human (Damaran)",80],
  ["Human (Damaran)",80],
  ["Human (Illuskan)",80],
  ["Human (Illuskan)",80],
  ["Human (Mulan)",80],
  ["Human (Mulan)",80],
  ["Human (Rashemi)",80],
  ["Human (Rashemi)",80],
  ["Human (Shou)",80],
  ["Human (Shou)",80],
  ["Human (Tethyrian)",80],
  ["Human (Tethyrian)",80],
  ["Human (Turami)",80],
  ["Human (Turami)",80],
  ["Dwarf (Hill)",350],
  ["Dwarf (Hill)",350],
  ["Dwarf (Hill)",350],
  ["Dwarf (Hill)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Duergar)",350],
  ["Dwarf (Duergar)",350],
  ["Dwarf (Duergar)",350],
  ["Dwarf (Duergar)",350],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Lightfoot)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Halfling (Stout)",150],
  ["Elf (Wood)",750],
  ["Elf (Wood)",750],
  ["Elf (High)",750],
  ["Elf (High)",750],
  ["Elf (Drow)",750],
  ["Elf (Drow)",750],
  ["Elf (Sea)",750],
  ["Elf (Sea)",750],
  ["Elf (Eladrin)",750],
  ["Elf (Eladrin)",750],
  ["Dragonborn (Black)",80],
  ["Dragonborn (Blue)",80],
  ["Dragonborn (Green)",80],
  ["Dragonborn (Red)",80],
  ["Dragonborn (White)",80],
  ["Dragonborn (Brass)",80],
  ["Dragonborn (Bronze)",80],
  ["Dragonborn (Copper)",80],
  ["Dragonborn (Gold)",80],
  ["Dragonborn (Silver)",80],
  ["Gnome (Forest)",350],
  ["Gnome (Forest)",350],
  ["Gnome (Forest)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Deep)",350],
  ["Gnome (Deep)",350],
  ["Gnome (Deep)",350],
  ["Tiefling (Baalzebul)",150],
  ["Tiefling (Dispater)",150],
  ["Tiefling (Fierna)",150],
  ["Tiefling (Glasya)",150],
  ["Tiefling (Levistus)",150],
  ["Tiefling (Mammon)",150],
  ["Tiefling (Mephistopheles)",150],
  ["Tiefling (Zariel)",150],
  ["Aasimar (Scourge)",2],
  ["Aasimar (Scourge)",2],
  ["Aasimar (Protector)",2],
  ["Aasimar (Protector)",2],
  ["Aasimar (Fallen)",2],
  ["Aasimar (Fallen)",2],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Firbolg",500],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Kobold",70],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tabaxi",80],
  ["Tortle",500],
  ["Tortle",500],
  ["Tortle",500],
  ["Tortle",500],
  ["Tortle",500],
  ["Satyr",50],
  ["Satyr",80],
  ["Satyr",80],
  ["Satyr",80],
  ["Satyr",750],
  ["Neufolk (Verdi)",80],
  ["Neufolk (Zurri)",80],
  ["Neufolk (Grigii)",80],
  ["Neufolk (Rossi)",80],
  ["Neufolk (Violi)",80],
  ["Owlin",100],
  ["Owlin",100],
  ["Owlin",100],
  ["Owlin",100],
  ["Half-Elf (High)",180],
  ["Half-Elf (Wood)",180],
  ["Half-Elf (Sea)",180],
  ["Half-Elf (Wood)",180],
  ["Half-Orc",71],
  ["Half-Orc",71],
  ["Half-Orc",71],
  ["Half-Orc",71],
  ["Bugbear",80],
  ["Bugbear",80],
  ["Bugbear",80],
  ["Bugbear",80],
  ["Centaur",80],
  ["Centaur",80],
  ["Centaur",80],
  ["Centaur",500],
  ["Githyanki",96],
  ["Githyanki",96],
  ["Githzerai",100],
  ["Githzerai",100],
  ["Goblin",50],
  ["Goblin",50],
  ["Goblin",50],
  ["Goblin",50],
  ["Goliath",80],
  ["Goliath",80],
  ["Goliath",808],
  ["Lizardfolk",75],
  ["Lizardfolk",75],
  ["Lizardfolk",75],
  ["Orc",50],
  ["Orc",50],
  ["Orc",50],
  ["Triton",200],
  ["Triton",200],
  ["Triton",200],
  ["Warforged",50],
  ["Warforged",50],
  ["Warforged",50],
  ["Dohwar",65],
  ["Dohwar",65],
  ["Dohwar",65],
  ["Vedalken",375],
  ["Vedalken",375],
  ["Vedalken",375],
  ["Leonin",80],
  ["Leonin",80],
  ["Leonin",80],
  ["Aarakocra",30],
  ["Aarakocra",30],
  ["Aarakocra",30],
  ["Fire Genasi",120],
  ["Fire Genasi",120],
  ["Air Genasi",120],
  ["Air Genasi",120],
  ["Water Genasi",120],
  ["Water Genasi",120],
  ["Earth Genasi",120],
  ["Earth Genasi",120],
  ["Changeling",80],
  ["Changeling",80],
  ["Fairy",80],
  ["Fairy",240],
  ["Harengon",75],
  ["Harengon",75],
  ["Hobgoblin",50],
  ["Kenku",60],
  ["Yuan-ti",1.1],
  ["Milifian",56],
  ["Drider",750],
  ["Hadozee",60],
  ["Thri-kreen",90],
  ["Loxodon",450],
  ["Verdan",180],
  ["Grung",50],
  ["Locathah",80],
  ["Plasmoid",120],
  ["Autognome",50]];

const humanlist = [["Human (Calishite)",80],
  ["Human (Chondathan)",80],
  ["Human (Damaran)",80],
  ["Human (Illuskan)",80],
  ["Human (Mulan)",80],
  ["Human (Rashemi)",80],
  ["Human (Shou)",80],
  ["Human (Tethyrian)",80],
  ["Human (Turami)",80]];

const dwarflist = [["Dwarf (Hill)",350],
  ["Dwarf (Mountain)",350],
  ["Dwarf (Duergar)",350]];

const elflist = [["Elf (Wood)",750],
  ["Elf (High)",750],
  ["Elf (Drow)",750],
  ["Elf (Sea)",750],
  ["Elf (Eladrin)",750]];

const halflinglist = [["Halfling (Lightfoot)",150],
  ["Halfling (Stout)",150]];

const dragonbornlist = [["Dragonborn (Black)",80],
  ["Dragonborn (Blue)",80],
  ["Dragonborn (Green)",80],
  ["Dragonborn (Red)",80],
  ["Dragonborn (White)",80],
  ["Dragonborn (Brass)",80],
  ["Dragonborn (Bronze)",80],
  ["Dragonborn (Copper)",80],
  ["Dragonborn (Gold)",80],
  ["Dragonborn (Silver)",80]];

const gnomelist = [["Gnome (Forest)",350],
  ["Gnome (Rock)",350],
  ["Gnome (Deep)",350]];

const tieflinglist = [["Tiefling (Baalzebul)",150],
  ["Tiefling (Dispater)",150],
  ["Tiefling (Fierna)",150],
  ["Tiefling (Glasya)",150],
  ["Tiefling (Levistus)",150],
  ["Tiefling (Mammon)",150],
  ["Tiefling (Mephistopheles)",150],
  ["Tiefling (Zariel)",150]];

const aasimarlist = [["Aasimar (Scourge)",2],
  ["Aasimar (Protector)",2],
  ["Aasimar (Fallen)",2]];

const genasilist = [["Fire Genasi",120],
  ["Air Genasi",120],
  ["Water Genasi",120],
  ["Earth Genasi",120]];

const neufolklist = [["Neufolk (Verdi)",80],
  ["Neufolk (Zurri)",80],
  ["Neufolk (Grigii)",80],
  ["Neufolk (Rossi)",80],
  ["Neufolk (Violi)",80]];

const githlist = [["Githyanki",96],
  ["Githzerai",100]];
const humanCalishiteMaleNames = ["Aseir","Bardeid","Haseid","Khemed","Mehmen","Sudeiman","Zasheir"];
const humanCalishiteFemaleNames = ["Atala","Ceidil","Hama","Jasmal","Meilil","Seipora","Yasheira","Zasheida"];
const humanCalishiteLastNames = ["Basha","Dumein","Jassan","Khalid","Mostana","Pashar","Rein"];

const humanChondathanMaleNames = ["Darvin","Dorn","Evendur","Gorstag","Grim","Helm","Malark","Morn","Randal","Stedd"];
const humanChondathanFemaleNames = ["Arveene","Esvele","Jhessail","Kerri","Lureene","Miri","Rowan","Shandri","Tessele","Thespa"];
const humanChondathanLastNames = ["Amblecrown","Buckman","Dundragon","Evenwood","Greycastle","Tallstag","Hormir","Pennypacker"];

const humanDamaranMaleNames = ["Bor","Fodel","Glar","Grigor","Igan","Ivor","Kosef","Mival","Orel","Pavel","Sergor"];
const humanDamaranFemaleNames = ["Alethra","Kara","Katernin","Mara","Natali","Olma","Tana","Zora"];
const humanDamaranLastNames = ["Bersk","Chernin","Dotsk","Kulenov","Marsk","Nemetsk","Shemov","Starag"];

const humanIlluskanMaleNames = ["Ander","Blath","Bran","Frath","Geth","Lander","Luth","Malcer","Stor","Taman","Urth"];
const humanIlluskanFemaleNames = ["Amafrey","Betha","Cefrey","Kethra","Mara","Olga","Silifrey","Westra"];
const humanIlluskanLastNames = ["Brightwood","Helder","Hornraven","Lackman","Stormwind","Windrivver"];

const humanMulanMaleNames = ["Aoth","Bareris","Ehput-Ki","Kethoth","Mumed","Ramas","So-Kehur","Thazar-De","Urhur"];
const humanMulanFemaleNames = ["Arizima","Chathi","Nephis","Nulara","Murithi","Sefris","Thola","Umara","Zolis"];
const humanMulanLastNames = ["Ankhalab","Anskuld","Fezim","Hahpet","Nathandem","Sepret","Uuthrakt"];

const humanRashemiMaleNames = ["Borivik","Faurgar","Jandar","Kanithar","Madislak","Ralmevik","Shaumar","Vladislak"];
const humanRashemiFemaleNames = ["Fyevarra","Hulmarra","Immith","Imzel","Navarra","Shevarra","Tammith","Yuldra"];
const humanRashemiLastNames = ["Chergoba","Dyernina","Iltazyara","Murnyethara","Stayanoga","Ulmokina"];

const humanShouMaleNames = ["An","Chen","Chi","Fai","Jiang","Jun","Lian","Long","Meng","On","Shan","Shui","Wen"];
const humanShouFemaleNames = ["Bai","Chao","Jia","Lei","Mei","Qiao","Shui","Tai"];
const humanShouLastNames = ["Chien","Huang","Kao","Kung","Lao","Ling","Mei","Pin","Shin","Sum","Tan","Wan"];

//Tethyrian humans take Chondathan names

const humanTuramiMaleNames = ["Anton","Diero","Marcon","Pieron","Rimardo","Romero","Salazar","Umbero"];
const humanTuramiFemaleNames = ["Balama","Dona","Faila","Jalana","Luisa","Marta","Quara","Selise","Vonda"];
const humanTuramiLastNames = ["Agosto","Astorio","Calabra","Domine","Falone","Marivaldi","Pisacar","Ramondo"];

const dwarfMaleNames = ["Adrik","Alberich","Baern","Barendd","Brottor","Bruenor","Dain","Darrak","Delg","Eberk","Einkil","Fargrim","Flint","Gardain","Harbek","Kildrak","Morgan","Orsik","Oskar","Rangrim","Rurik","Taklinn","Thoradin","Thorin","Tordek","Traubon","Travok","Ulfgar","Vondal","Umdal","Thorkon"];
const dwarfFemaleNames = ["Amber","Artin","Audhild","Bardryn","Dagnal","Diesa","Doril","Eldeth","Falkfunn","Finellen","Gunnloda","Gurdis","Helja","Hlin","Kathra","Kristryd","Ilde","Liftrasa","Mardred","Riswynn","Sannl","Torbera","Vistra"];
const dwarfLastNames = ["Balderk","Battlehammer","Braunanvil","Dankil","Fireforge","Frostbeard","Gorunn","Holderhek","Ironfist","Loderr","Lutgehr","Rumnaheim","Strakeln","Torunn","Ungart","Þiknir","the Skull-Piercer"];

const elfChildNames = ["Ara","Bryn","Del","Eryn","Faen","Innil","Lael","Mella","Naill","Naeris","Phann","Rael","Rinn","Sai","Syllin","Thia","Vall"];
const elfMaleNames = ["Adran","Aelar","Aramil","Arannis","Aust","Beiro","Berrian","Carric","Enialis","Erdan","Erevan","Galinndan","Hadarai","Heian","Himo","Immeral","Ivellios","Laucian","Mindartis","Paelias","Peren","Quarion","Riardon","Rolen","Soveliss","Thamior","Tharivol","Theren","Varis","Kastellon"];
const elfFemaleNames = ["Adrie","Althaea","Anastrianna","Andraste","Atinua","Bethrynna","Birel","Caelynn","Drusilla","Enna","Felosial","Ielenia","Jelenneth","Keyleth","Leshanna","Lia","Meriele","Mialee","Naivara","Quelenna","Quillathe","Sariel","Shanairra","Shava","Silaqui","Theirastra","Thia","Vadania","Xanaphia"];
const elfLastNames = ["Amakiir","Amastacia","Galanodel","Holimion","Ilphelkiir","Liadon","Meliamne","Naïlo","Siannodel","Xiloscient","Karpathos"];

const halflingMaleNames = ["Alton","Ander","Cade","Corrin","Eldon","Errich","Finnan","Garret","Lindal","Lyle","Merric","Milo","Osborn","Perrin","Reed","Roscoe","Wellby"];
const halflingFemaleNames = ["Andry","Bree","Callie","Cora","Euphemia","Jillian","Kithri","Lavinia","Lidda","Merla","Nedda","Paela","Portia","Seraphina","Shaena","Trym","Vani","Verna"];
const halflingLastNames = ["Brushgather","Goodbarrel","Greenbottle","High-hill","Hilltopple","Leagallow","Tealeaf","Thorngage","Tosscobble","Underbough"];

const dragonbornMaleNames = ["Arjhan","Balasar","Bharash","Donaar","Ghesh","Heskan","Kriv","Medrash","Mehen","Nadarr","Pandjed","Patrin","Rhogar","Shamash","Shedinn","Tarhun","Torinn","Galin","Arrox","Mythra","Korox"];
const dragonbornFemaleNames = ["Akra","Biri","Daar","Farideh","Harann","Havilar","Jheri","Kava","Korinn","Mishann","Nala","Perra","Raiann","Sora","Surina","Thava","Uadjit"]
const dragonbornChildNames = ["Climber","Earbender","Leaper","Pious","Shieldbiter","Zealous"];
const dragonbornLastNames = ["Clethtinthiallor","Daardendrian","Delmirev","Drachedandion","Fenkenkabradon","Kepeshkmolik","Kerrhylon","Kimbatuul","Linxakasendalor","Myastan","Nemmonis","Norixius","Ophinshtalajiir","Prexijandilin","Shestendeliath","Turnuroth","Verthisathurgiesh","Yarjerit","Chiroc","Malibu"];

const gnomeMaleNames = ["Alston","Alvyn","Boddynock","Brocc","Burgell","Dimble","Eldon","Erky","Fonkin","Frug","Gerbo","Gimble","Glim","Jebeddo","Kellen","Namfoodle","Orryn","Roondar","Seebo","Sindri","Warryn","Wrenn","Zook"];
const gnomeFemaleNames = ["Bimpnottin","Breena","Caramip","Carlin","Donella","Duvamil","Ella","Ellyjobell","Ellywick","Lilli","Loopmottin","Lorilla","Mardnab","Nissa","Nyx","Oda","Orla","Roywyn","Shamil","Tana","Waywocket","Zanna"];
const gnomeLastNames = ["Beren","Daergel","Folkor","Garrick","Nackle","Murnig","Ningel","Raulnor","Scheppen","Timbers","Turen","Knockknees"];
const gnomeNicknames = ["Aleslosh","Ashhearth","Badger","Cloak","Doublelock","Filchbatter","Fnipper","Ku","Nim","Oneshoe","Pock","Sparklegem","Stumbleduck","Slappy","Mimp","Slink","Bubble","Flitterfly","Fibblegrip","Pongle","Quickfoot","Twiddleby","Thumbsy","Twig","Stumpknack","Clickspring","Twang","Fiddlestick","Barrel-Rider","Gaggle","Pip","Pluckey","Tootbottle","Strum","Sticky","Thwumpy","Thwickle","Brambly","Yilo","Wagon-Runner","Bug-Chaser","Cookie","Twink","Flipple","Zoff","Tibbi","Stickwhisker"];

//Half-elves take either elvish or human names

//Half-Orcs take either orcish or human names

const tieflingMaleNames = ["Akmenos","Amnon","Barakas","Damakos","Ekemon","Iados","Kairon","Leucis","Melech","Mordai","Morthos","Pelaios","Skamos","Therai","Thajen","Jerald"];
const tieflingFemaleNames = ["Akta","Anakis","Bryseis","Criella","Damaia","Ea","Kallista","Lerissa","Makaria","Nemeia","Orianna","Phelaia","Rieta","Arnella","Jinx"];
const tieflingLawfulNames = ["Creed","Reverence","Quest","Constance","Ideal","Rule","Rigid","Structure"];
const tieflingChadNames = ["Cool","Glory","Temereity","Chad","Art"];
const tieflingSmartNames = ["Cunning","Invention","Spark","Idea","Creative"];
const tieflingChaoticNames = ["Random","Mischief","Freedom","Rebellion","Gremlin","Dork"];
const tieflingSadNames = ["Sorrow","Dispair","Weary","Mourning","Cry","Nowhere","Grief","Stoic"];
const tieflingStupidNames = ["Hehe","Goof","Moron","Crazy","Impulse","Id","Idiot","Dumbass"];
const tieflingGoodNames = ["Hope","Love","Kindness","Ideal","Open","Poetry"];
const tieflingHornyNames = ["Lust","Desire","Wink","Whisper","Charm","Allure","Smooth","Hotstuff","Fuck","Smash"];
const tieflingEvilNames = ["Torment","Carrion","Fear","Wrath","Cruelty","Selfish","Greed","Anger","Ambition"];
const tieflingNeutralNames = ["Moderation","Temperance","Balance","Equality","Even-Handed","Eh"];
const tieflingLastNames = ["Terias","Mutnon","Achore","Vikos","Srath","Anarch","Baenor","Bikros","Nethaia","Monalla"];


//Aasimar take names from the people they are raised by

const fireGenasiMaleNames = ["أمل ('Amal)","حعين (Hayin)","جهيدم (Jhidam)"];
const fireGenasiFemaleNames = ["يأمل (Yamal)","حلاوة (Halawa)","جهراند (Jahrand)"];
const fireGenasiLastNames = ["نار (Nar)","آتش (Atch)","جمرة (Jamra)","خاکستر (Khakestr)"];

const airGenasiMaleNames = ["رثيري (Rethyri)","مرو (Maruu)","فمز (Famaz)"];
const airGenasiFemaleNames = ["حجير (Hajir)","كيوب (Kyub)","زورود (Zurud)"];
const airGenasiLastNames = ["هواء (Hawa')","هوا (Hwa)","أَجواء ('Ajwa')","سماء (Sama')"];

const waterGenasiMaleNames = ["بلو (Balu)","منده (Mindah)","جهلإم (Jahlim)"];
const waterGenasiFemaleNames = ["جردان (Jardan)","يان Yan","مرح (Marah)"];
const waterGenasiLastNames = ["ماء (Ma')","اب (Ab)","بحر (Bahr)","دریا (Draa)"];

const earthGenasiMaleNames = ["درخأن (Darkhan)","درزخ (Darzakh)","هامان (Haman)"];
const earthGenasiFemaleNames = ["جحيش (Jahish)","لأضية (Ladiya)","ظاهرم (Zahirm)"];
const earthGenasiLastNames = ["أرض ('Ard)","زمین (Zman)","التراب (Alturab)","صحراء (Sahra')"];

//Changeling names

const firbolgMaleNames = ["Clay","Tallus","Chantal","Tellus","Kumal","Jonquil","Yael","Bog","Coriander","Oland"];
const firbolgFemaleNames = ["Jade","Terra","Gaia","Ersa","Omala","Janquil","Bog","Cypress","Leaf","Chulsa"];
const firbolgLastNames = ["Forager","Sol","Porier","Apeldoorn","Dalen","Feldin","Lesena","Fraol","Marith","Pol"];

const koboldMaleNames = ["Ajhan","Blusar","Bhrash","Dronar","Ghush","Heksan","Kruv","Drash","Meen","Nudra","Pjed","Prutan","Rhog","Shmash","Shned","Tarun","Torn","Galn","Arx","Muthra","Krux","Vrik","Brak","Xurk","Rax","Kron","Frit","Grat","Zax","Din","Tik"];
const koboldFemaleNames = ["Arka","Bru","Druh","Friduh","Hrann","Hvillr","Jhur","Kva","Kornn","Shman","Nulah","Pera","Riann","Sor","Srina","Thav","Udjit","Bix","Lin","Sill","Ryn","Kly","Mo","Rif","Sy","Nar","Zor"];

const tabaxiNames = ["Long","Short","Breaking","Tall","Leaping","Falling","Sneaking","Singing","Travelling","Future","Steel","Kallie","Brownie","Buster","Baxter","Kira","Oni","Akuma"];

const tortleMaleNames = ["Tristifer","Shelgon","Muedran","Lorett","Malne","Lumbel","Gandin","Bartigan","Blot","Gorban","Droon","Glorick","Bundus","Tropple","Dromm"];
const tortleFemaleNames = ["Muedrin","Sheffel","Malene","Hatrin","Karinth","Kotta","Grayll","Dramm","Blona","Orli","Plop","Royne","Zorr","Galeen","Loav"];
const tortleLastNames = ["Mudd","Trogrove","Willoe","Sloe","Hartshel","Morlingon","Drumm","Hardback","Estermont","Mudwall","Braykin","Gornim","Gar","Tortician","Fogg","Zooble"];

//Satyrs use Fey names

const feyNames = ["","Mushroom","Daisy","Lily","Amaranth","Qualia","Mystery","Mischief","Magic","Riddle","Giggle","Fibber","Tickle","Dawn","Dusk","Curious","Trick","Tricky","Dance","Trance","Fun","Mirth","Glee","Stubborn","Grin","Smile","Amathyst","Emerald","Crystal","Fungus","Toadstool","Toad","Evergreen","Hopper","Dream","Fiddlerick McSnifficker","Fef're'el","Prance"];

const owlinMaleNames = ["Finrindel","Guardriel","Deiben","Farduran","Hlyn"];
const owlinFemaleNames = ["Roliel","Lerinal","Perrinq","Humily","Yanalyn","Lynrindel"];
const owlinLastNames = ["Corrin","Huuarn","Hardbeak","Glyde","Fint"];

const bugbearMaleNames = ["Gläch","Blarn-Eat","Blarg","Prodak","Rostogg","Valix","Dibrack"];
const bugbearFemaleNames = ["Dorlag","Bunglethung","Darish","Nilly","Gratch","Brell"];

const centaurMaleNames = ["Ratimir","Jim","Glueboy","Reckless","Bucephalus","Vladimir","Yuri","Thunder","Asfaloth","Hasufel","Smoky","Bullseye","Arod","Braston"];
const centaurFemaleNames = ["Jenny","Rainbow","Ayndrea","Meela","Thraela","Ravinya","Olga","Embla","Yulia","Noraphel","Lillix","Hulda","Grayla","Forla","Rain"];
const centaurLastNames = ["Glitterhoof","Tweedmouth","Wylde","Strider","Wind","Prancer","Steel","Firemane","Hotblood","Silver","Colt","Clydesdale","Horse"];

const githyankiMaleNames = ["Jharazi","Saharazi","Zikari","Krai","Jafarai","Nari","Drossi","Rath'lai","Kasheri","Morkai","Shazadi","Kyri","Vkori","Nylathi"];
const githyankiFemaleNames = ["Zeharano","Nathoro","Nabro","Phozho","Marzo","Phylo","Nagormo","Kalo","Mehrano","Jithko","Dralo","Kathko","Laylo","Zirro"];
const githyankiLastNames = ["Krall","Gothro","Scoro","Drask","Ithene","Maryllo","Voss","Brassh","Nahro","Nosho","Jas'kalo","Jharlakk","Zotho"];

const githzeraiMaleNames = ["Arotho","Zraio","Kharao","Merkyro","Thaio","Drogo","Zallo","Klatho","Dasho'ko","Janar'tho","Shortho","Zikko","Karlo"];
const githzeraiFemaleNames = ["Guarani","Jharai","Zhondi","Neeli","Hirodi","Akali","Galdi","Zoni","Kharai","Jinari","Sarai","Zorri","Phalani"];
const githzeraiLastNames = ["Zethlani","Leoni","Krai","Vali","Jeth'li","Morokai","Ketani","Mor'tiin","Kalai","Shani","Zhono","Zholi","Hala'ti"];

const goblinMaleNames = ["Scromch","Blood","Grizzle","Bunk","Yeck","Squeltch","Flim","Lig","Hooch","Ghel","Vor","Azrok","Glot","Kliyuse","Malget","Drakk","Raff"];
const goblinFemaleNames = ["Scrungle","Bone","Bonk","Squeltch","Flam","Yink","Thrick","Nock","Gillmince","Pluck","Thock","Lurkana","Gastra","Verk","Prola","Korda"];

const goliathMaleNames = ["Hogh","Grug","Drev","Kreg","Kregdak","Godok","Throng","Obak"];
const goliathFemaleNames = ["Droz","Grezen","Hrun","Korl","Jaadok","Norlok","Obok"];
const goliathLastNames = ["Cleverhand","Skytouch","Undermountain","Blueskin","Strongarm","Behemothback"];

const lizardfolkMaleNames = ["Zzarizz","Ssrig","Ssikrith","Rakak","Zzorid","Nrath","Orthrok","Zzarnon","Grizzk","Ssrak","Ssulikar","Voss","Rassk","Ssaro","Yorsso","Malassar","Massad","Elssir","Yarssov","Delsso"];
const lizardfolkFemaleNames = ["Sucu","Juro","Slatha","Skraa","Zhathro","Sroko","Zarno","Kiro","Hrani","Oroki","Yissith","Essvara","Ssirine","Mariss","Lasstra","Darssa","Ssyla","Zossha","Felissa","Rassid"];

const orcMaleNames = ["Dench","Feng","Gell","Henk","Holg","Imsh","Keth","Krusk","Mhurren","Ront","Shump","Thokk","Malador"]
const orcFemaleNames = ["Baggi","Emen","Engong","Kansif","Myev","Neega","Ovak","Ownka","Shautha","Sutha","Vola","Volen","Yevelda"]

const tritonFirstNames = ["Dukar","Keros","Vodos","Jhimar","Pythan","Ruthar","Zegen","Jhabur","Sigoz","Lanar"];
const tritonLastNames = ["Phranar","Ghastar","Grithos","Thronos","Derikan","Zohon","Zoko","Threek","Granir"];

const warforgedNames = ["Ghost","Fortschrittlicherohrbiegemaschine","Bender","Scrapper","Scrappie","Clank","Rusty","Steele","Trapper","Hammer","Piledriver","Squeaky"];
const warforgedAcron = ["O.R.C. unit", "O.R.C.", "D.W.A.R.F.", "G.R.U.N.G.", "E.L.F.", "E.L.F.", "H.U.M.A.N."];
const warforgedExpan = ["(Outerplanar Runaway Containment unit)", "(Object Recognition Construct)", "(Durable Wartime Attack and Reconaissance Follower)", "(Garbage and Refuse UNloading Golem)", "(Esoteric Language Filter)", "(Eliminator unit: ", "(Hemoglobin-Using Medical Assistant/Nurse)"];
const lmalefirstnames = ["Lander", "Luth", "Lian", "Long", "Lael", "Laucian", "Lindal", "Lyle", "Leaper", "Leucis", "Lorrett", "Lumbel", "Lig", "Lanar"];
const lfemalefirstnames = ["Lureene", "Lei", "Luisa", "Liftrasa", "Lael", "Leshanna", "Lia", "Lavinia", "Lidda", "Leaper", "Lilli", "Loopmottin", "Lorilla", "Lerissa", "Leaf", "Lin", "Loav", "Lily", "Lerinal", "Lynrindel", "Lillix", "Laylo", "Leoni"];
const flastnames = ["Fezim", "Falone", "Fireforge", "Frostbeard", "Fenkenkabradon", "Folkor", "Forager", "Feldin", "Fraol", "Fogg", "Fint", "Firemane"];

const dohwarMaleNames = ["Agwil","Quann","Benne","Thwil","Stagan","Ogwallo","Holtar","Fadrol","Ouk","Melwyn","Zinko","Skipper","Fillibar","Noryck","Rico","Kliftyn","Dellin","Zakrod","Yelbin"];
const dohwarFemaleNames = ["Enet","Agwan","Agane","Larmi","Drilla","Kitka","Marcedene","Aria","Pelgie","Hilwyn","Zonerelle","Astry","Relki","Zelbar"];
const dohwarLastNames = ["Pennypacker","Coin","Business","Profit","Sale","Bargain","Haggle","Copper","Silver","Gold","Electrum","Platinum","Trade","Revenue","Capital","Investment","Dividend","Asset Synergizer","Asset"];

const vedalkenMaleNames = ["Pende","Forune","Mödo","Üvel","Revé","Möduvel"];
const vedalkenFemaleNames = ["Meun","Slaükaa","Osaa","Iß","Loraa","Çeruvé"];
const vedalkenLastNames = ["Eudicus","Oedion","Uep","Orlemaa"];

const leoninMaleNames = ["Riani","Asume","Umale","Skiri","Kurami","Amoalé"];
const leoninFemaleNames = ["Raya","Umala","Muzé","Mira","Pelana"];
const leoninLastNames = ["Umara","Salaz","Lezir"];

const aarakocraMaleNames = ["Aun","Leashore","Sevadore","Thalor","Marwyn","Arryn","Atlas","Corvus","Cirrus","Owain","Hermes","Jarnathan","Rondor"];
const aarakocraFemaleNames = ["Throcas","Dravanas","Socoros","Lasra","Ariella","Ravenna","Mariel","Eilonwy","Lorelai","Wave","Perin","Tavia","Castaleina"];
const aarakocraLastNames = ["Janam","Soram","Peloras","Talon","Brightwing","Sparrow","Crow","Swan","Larke","Firewind","Laydin","Avian","Sunspear"];

//Fairies use Fae names

const harengonMaleNames = ["Olie","Truodore","Rudofer","Heuwill","Millofer","Gilwinkle"];
const harengonFemaleNames = ["Hinderwind","Alie","Galamine","Millofet","Brave","Nilley"];
const harengonLastNames = ["Thump","Lopear","Fickle","Longtail","Hop","Hollowood","Hatbuckle","Nibbles"];

//Hobgoblins use goblin names

const kenkuNames = ["Tapper","Basher","*Ring*","*Sail Snap*","Clanger","Hammer","Singer","*Chatter*","*Clash*","Wind","Cutter","\"Meat Pies! Two For a Silver! Get \'Em While They\'re Hot!\"","*Stab*","Caw!","*Crunch*","Saw","*Strum*","*Clink*","Whistler","Drummer","*Slap*","*Falling Tree*","*Whinny*","*Cackle*","Screamer","Bell","*Crashing Wave*","*Footfall*","*Door Creak*","Echo"];

const neufolkZurriMaleNames = ["Giovanni","Elio","Luca","Enzo","Mateo","Dante","Lorenzo","Aurelio","Rocco","Leandro","Salvatore"];
const neufolkZurriFemaleNames = ["Ginevra","Beatrice","Greta","Vittoria","Martina","Chiara","Matilde","Ludovica","Azzurra","Anselma","Cinzia"];
const neufolkZurriLastNames = ["Marino","Acone","Acqarone","Bonomo","Bicchieri","De Luca","Episcopo","Esposito","Lamon","Pozzi","Profeta","Ricci","Zino"];

const neufolkGrigiiMaleNames = ["Dave","Craig","Steven","Matthew","Johnathan","Gary","Donald","Connor","Sean","Oisin","Patrick","Cian","Liam","Darragh"];
const neufolkGrigiiFemaleNames = ["Aoife","Ciara","Caoimhe","Niamh","Roisin","Cara","Clodagh","Poppy","Evie","Grace","Anne","Eloise","Eleanor","Lucy","Mae","Daisy","Olive","Edith"];
const neufolkGrigiiLastNames = ["Smith","Jones","Taylor","Brown","Johnson","Davies","Wright","Murphy","Kelly","Byrne","Walsh","O'Brien","O'Connor","O'Sullivan"];

const neufolkRossiMaleNames = ["محمد (Mohammed)","أحمد (Ahmed)","يوسف (Yusef)","مصطفى (Mustafa)","ابراهيم (Ibrahim)","ابو (Abu)","عمر (Omar)"];
const neufolkRossiFemaleNames = ["الاء (Alaa)","شامة (Shamma)","شام (Sham)","غلا (Ghala)","منى (Mona)","هبة (Heba)","مروة (Marwa)","ساره (Sarah)","ايمان (Eman)","فاطمة (Fatima)"];
const neufolkRossiLastNames = ["أباظة (Abaza)","عبد الله (Abdallah)","أبو العافية (Abulafia)","بكر (Bakir)","السراج (Al-Sarraj)","راغب (Ragheb)","الخطيب (Al-Khatib)","عون (Aoun)","ضومط (Doumit)","ضيف الله (Daifallah)"];

const neufolkVioliMaleNames = ["이준 (I-jun)","서준 (Seo-jun)","하준 (Ha-jun)","도윤 (Do-yun)","은우 (Eun-u)","시우 (Si-u)","지호 (Ji-ho)","예준 (Ye-jun)","유준 (Yu-jun)","수호 (Su-jo)"];
const neufolkVioliFemaleNames = ["서아 (Seo-ah)","하윤 (Ha-yoon)","이서 (I-seo)","지안 (Ji-an)","지아 (Jia)","서윤 (Seoyun)","아린 (A-rin)","아윤 (A-Yun)","하린 (Ha-rin)","하은 (Ha-eun)"];
const neufolkVioliLastNames = ["김 (Kim)","이 (Lee)","박 (Bak)","정 (Jeong)","최 (Choe)","조 (Jo)","강 (Gang)","장 (Jang)","윤 (Yun)","임 (Lim)"];

//Yuan-ti use names from their original race

const milifianMaleNames = ["Gug","Freck","Rizz","Rizzo","Gugular","Chug","Chugular"];
const milifianFemaleNames = ["Razz","Frink","Rungle","Grel","Razena"];
const milifianLastNames = ["Grimble","Lumble","Forbin","Dump","Cheese"];

//Driders use elvish names

const hadozeeMaleNames = ["Alfez","Hililliam","Trombert","Jimothy","Keenustus","Johash","Apefred","Vorace","Finston","Malvin"];
const hadozeeFemaleNames = ["Greneta","Amne","Umelia","Fynthia","Dillith","Moodith","Imy","Zylfia","Hattryn","Vae"];
const hadozeeLastNames = ["Howlbert","Alfezson","Frish","Grey","Bananape","Lurchill","Pink","Greaver","Stiff","A'Fulliban"];

const thrikreenUpperFirstNames = ["Gak","Mor","Gol","Kol","Kag","Za","Ga","Ko","Ha","Gre","Sra","Thre","Thor","Loh","Ro","Qo","Ke","Thri","Kre","Zo","Nør"];
const thrikreenLowerFirstNames = ["gak","mor","gol","kol","kag","za","ga","ko","ha","gre","sra","thre","thor","loh","ro","qo","ke","'","thri","kre","en","zo","kle","nør"];
const thrikreenLastNames = ["Gok","Lod","Kag","Zih","Kol","Hoh","Thog","Hath","Gor","Zor","Zim"];

const loxodonMaleNames = ["Bolomf","Kel","Albo","Brasof","Surumah","Geranon","Felahf"];
const loxodonFemaleNames = ["Actel","Moronay","Sheia","Ulenara","Belanel"];
const loxodonLastNames = ["Toron","Nairah","Kallah","Zahur"];

const verdanNames = ["Bronn","Crahma","Dolar","Dreeda","Duglee","Gruvald","Hulm","Jeal","Kalo","Klesh","Korm","Lathi","Ovlig","Paracii","Pils","Praet","Promul","Reezni","Rin","Shylk","Slyra","Sollo","Stalsii","Stromvo","Stussa","Syrkart","Takat","Toit","Tubyna","Varr","Veriga","Wraq","Wural","Wurxee"];

const grungMaleNames = ["Ulp","Gallt","Rort","Plet","Raff","Cathre","Ort","Kermit","Lurken","Ath’lith","Glorm","Jatho","Na’ziko","Kring"];
const grungFemaleNames = ["Koa","Roarp","Gangle","Mika","Talakki","Liga","Garis","Blorn","Ritt","Paka","Lorti","Anga"];
const grungLastNames = ["Umpus","Wort","Klebt","Glaik","Krang","Bogg","Marlo","Dal’akor","Tamimi","Chola","Ribbit","Galata","Tok","Kayn"];

const locathahMaleNames = ["Murlth","Bormel","Gu'Yllin","Morbl","Depf","Gu'il","Klu'Amesh"];
const locathahFemaleNames = ["Squimpus","Gu'Illah","Waul","Edon","Thara'gul","Zarugah"];
const locathahLastNames = ["Gazimpus","Jhath","Sukravesh","Depfedon","Orlemagus","Saragur","Gu'hrugon","C'thru","Iiemalure","Kh'khumal","Veshala"];

const plasmoidNames = ["Gl'oup","Gorlk","Glopp","G'korlp","Pthpthppt","Mlop","P'lok","Gu'lum Plop","K'ptth","Gulm'p"];

const autognomeNames = ["Clickspring","Twizzy","Doohickey","Whizz","Dancer","Clunkie"];
const ruralLandmarks = ["old mill","river","lakeshore","pond"];
const urbanLandmarks = ["general store","docks","castle","tavern"];

const towns = [
  ["Greenest","<a href=\"https://forgottenrealms.fandom.com/wiki/Greenest\">Greenest</a>","plains","Western Heartlands",],
  ["Beregost","<a href=\"https://forgottenrealms.fandom.com/wiki/Beregost\">Beregost</a>","forest","Trade Way"],
  ["Tilverton","<a href=\"https://forgottenrealms.fandom.com/wiki/Tilverton\">Tilverton</a>","mountains","Cormyr"],
  ["Mosstone","<a href=\"https://forgottenrealms.fandom.com/wiki/Mosstone\">Mosstone</a>","forest","Tethyr"],
  ["Trademeet","<a href=\"https://forgottenrealms.fandom.com/wiki/Trademeet\">Trademeet</a>","forest","Amn"],
  ["Han Chao","<a href=\"https://forgottenrealms.fandom.com/wiki/Han_Chao\">Han Chao</a>","mountains","Tabot"],
  ["Horsea","<a href=\"https://forgottenrealms.fandom.com/wiki/Horsea\">Horsea</a>","forest","Calidyrr"],
  ["Shallownet","<a href=\"\">Shallownet</a>","coastal","Zwakke"],
];
const cities = [
  ["Waterdeep","<a href=\"https://forgottenrealms.fandom.com/wiki/Waterdeep\">Waterdeep</a>","plains","Sword Coast"],
  ["Baldur's Gate","<a href=\"https://forgottenrealms.fandom.com/wiki/Baldur's_Gate\">Baldur's Gate</a>","plains","Sword Coast"],
  ["Neverwinter","<a href=\"https://forgottenrealms.fandom.com/wiki/Neverwinter\">Neverwinter</a>","mountains","Sword Coast"],
  ["Elturel","<a href=\"https://forgottenrealms.fandom.com/wiki/Elturel\">Elturel</a>","plains","Western Heartlands"],
  ["Berdusk","<a href=\"https://forgottenrealms.fandom.com/wiki/Berdusk\">Berdusk</a>","plains","Western Heartlands"],
  ["Roalis","<a href=\"\">Roalis</a>","coastal","Zwakke"],
  ["I Lain Othrond","<a href=\"\">I Lain Othrond</a>","coastal","Thege"],
];

<!--"-->
const warlockplaces = ["S̷̞̬̩̙̮̮̟̒̏̐̎̑c̷̛͇̊́́̎̐͗̃͗̃̎̉̅͊̒͛͠a̷̛̟͈̰͙̪̞͎͔̗͋̓̊̉̏̎̈́̌̌̈̓̎̊̊̑̕d̴̨̡̧͎̭͎͎̞̼̙͔̓̈̎ͅȧ̶̢̛̮͕͉̻̙̪̘͙̮̩͂͜͠͝","P̷̧̙̲̫̫̫̾̓͑̋ù̵̢̪̹͉̼͍̝̜̎͒́͒̑̑͌̈̀̀̑͐̿̚̚r̴̠͓̀̓̏̽p̷̨̡̛̻͍̮̮̲͉̺̟̼̒͛͝͝ͅl̵̬̥͚̦̪̙̥̯̘̈́̃̓͒̄͌̚͜ͅͅe̴̡̡̦͖̟̞̳̣̖͙̺͎̖̔̍̇̌͛̃͠͝͝ͅ ̷̠̼̤̣̦͈̺̝̝̻̹̗̈̉̀̈̐̀̾͝ͅR̴͓̱̐͂̾͊́̿͑̏̔̾̐̽͠͝͝͠͠ͅó̸̠̬͇͙̻͋ͅc̴̢̡̙̲̗̥̹͉̟̭͇̹͋͐̑̓͒͌̚͠k̵̲̰͍͔̭̦̈́̾̾͋̅́","U̷͚͕̩̠͗̔̀̂̔̀̃͂̾̊̀͒̏͘͘t̷̺̮̖̞̠̣̤̆̒̀̎͝t̷͓͇͎͎͓̪͔͂͌̃̍͂̆̈́̓͆́̌̚ͅę̶̢̤̩͕̹̙͍͉͙̟̣̹͉̼̑̚r̷̛͈̲͎͇̰̬̼͖̭͔͗̿̋͆͗͑̊́̉͐̇s̵̡̫̖̱̺͇̟̼̬̣̭͇̯̭͑͜e̸̢̝̘͎̲̲͈̝̺͈͈̯̦̫̻͂̓̋̎͆̿́͌̂̕a̸̡̦̩̤̱̠̰̳̓͂͑͛̿̈́͛̆̂̋̄̓̃͑͘","M̵̨͖̠͇̖̣̜̞͎͋͊̕ȏ̶̡̢̨̰͈̖̭̯̭̉̐t̵̤̲̜̮̙̦͚̲̦̼͓͂͠h̷̡̡̭̬͚͖͖͔͈́͌̉̈́͂̾̅̿͊͛̒̅̚e̸̢̩̹̯̤͕̻̣̱͉͎͓̒̌̋̏͂̓̇̎̕͘͝ŗ̸̧͈̮͍̯̲͈̼̖̹̩́͋̓͊͌̃͒̆̾͜͝ͅ ̵̟̤̣̰̹̂͊̒̏̈́̾͊̈͆̒͂͐͗̂̇͆͊o̵̧͙͈̞̳̯̼̓̒̈́̏͗͆̀̉̀͆f̶͉̼̣̺͍͖̬̥̺̼̤̝̤͖̬̋̎̐͗̔̊̕͜͜ ̷̢͚̘̤̣͙̲̰͕̘̟͉̦͎̳͚̄̈́̈͑̐M̵̨̖͖̙̜̦͌͑̚͜͜͠ͅî̸̗͚̬̗͕̾̌̓̑̃̇̑̇̾̕͜͝ͅs̸̢̨̫̮͕̗̭͉̺̥͍͗͒͑̋̎̆̀̔̕͝ţ̴̧́͗̐̑͑̀̎͒̍̎ś̶̨̗̻̤͓̠͍̯̿̀̎́̄͒̚̚"];

const logos = ["crescent moon","wolf head","coiled snake","bloody knife","crying figure","closed eye","eye","bloodshot eye","sleeping owlbear","lightning bolt","spiral"];

const damagetypeselemental = ["fire","lightning","poison","acid","cold"];
const damagetypesphysical = ["slashing","piercing","bludgeoning"];

const wealthyprofessions = ["Noble",
  "Noble",
  "Advisor",
  "Cleric",
  "Adventurer",
  "Spy"];
const urbanprofessions = ["Stonemason",
  "General store merchant",
  "Cheesemaker",
  "Brewer",
  "City guard",
  "Cleric",
  "Alchemist",
  "Magic supply merchant",
  "Performer",
  "Carpenter"];
const ruralprofessions = ["Farmer",
  "General store merchant",
  "Fisher",
  "Hunter",
  "Brewer",
  "Cleric",
  "Cobbler",
  "Carpenter"];

const magicschools = ["evocation",
  "conjuration",
  "divination",
  "abjuration",
  "enchantment",
  "illusion",
  "transmutation"]

const tavernadj = ["Slippery","Drunken","Sour","Lazy","Flaming","Splendid","Black","Red","Blue","Green","Lame","Staggering","Rising","Bigget","Swaggering","Sparkling","Speckled","Lunar","Shivering"];
const tavernnoun = ["Tavern","Duck","Buck","Rabbit","Bunny","Splash","Tankard","Cup","Vagrant","Sun","Moon","Sunset","Moonrise","Nut","King","Queen","Princess","Prince","Wizard","Den","Hive","Hearth","Longhouse","Hen"];

const bodypartsext = ["left cheek","right cheek","left eye","right eye","left arm","right arm","left forarm","right forarm","left hand","right hand","nose","neck","left leg","right leg","left foot","right foot","chest"];

const smallbeasts = ["panther","wolf","bear","snake","wild dog","boar","alligator","crocodile","tiger"];
const bigbeasts = ["displacer beast","owlbear","direwolf","giant snake"];

const offscreentag = "Offscreen";
const player = {
  stats: [0,0,0,0,0,0],
  statorder: [5,4,3,2,1,0],
  birthday: 0,
  race: ["<font color='red'>FDEFAULT_RACE</font>",1],
  race2: ["<font color='red'>FDEFAULT_RACE_2</font>",1],
  clas: "<font color='red'>FDEFAULT_CLASS</font>",
  gender: "<font color='red'>FDEFAULT_GENDER</font>",
  fullname: ["<font color='red'>FIRST_NAME</font>","<font color='red'>LAST_NAME</font>","<font color='red'>NICKNAME</font>"],
  locale: "<font color='red'>LOCALE</font>",
  socialclass: "<font color='red'>SOCIAL_CLASS</font>",
  sad: 0,
  adopted: 0,
  adoptedLate: 0,
  parent1:{
    birthday: 0,
    fullname: ["<font color='red'>FIRST_NAME</font>","<font color='red'>LAST_NAME</font>"],
    race: ["<font color='red'>PARENT_1_RACE</font>",1],
    gender: "<font color='red'>PARENT_1_GENDER</font>",
    profession: "<font color='red'>PARENT_1_GENDER</font>",
    dead: "",
  },
  parent2:{
    birthday: 0,
    fullname: ["<font color='red'>FIRST_NAME</font>","<font color='red'>LAST_NAME</font>"],
    race: ["<font color='red'>PARENT_2_RACE</font>",1],
    gender: "<font color='red'>PARENT_2_GENDER</font>",
    profession: "<font color='red'>PARENT_2_GENDER</font>",
    dead: "",
  },
  hometown: "<font color='red'>DEFAULT_TOWN</font>",
  alignment: ["<font color='red'>DEFAULT_LAWFULNESS</font>", "<font color='red'>DEFAULT_GOODNESS</font>"],
  backstory: [[1,"Event 1"],[2,"Event 2"]],
  discapline: "<font color='red'>DISCAPLINE</font>",
};
function kowalski(){
  var stattotalk = parseInt(document.getElementById('stattotalinput').value);
  var outputstring = "";
  if(stattotalk < 18){
    stattotalk = 18;
    alert("It is impossible to roll a stat total lower than 18. The stat total has been set to 18.");
    if(confirm("Stat totals less than 36 are very slow to calculate. Do you want to continue?")){
      for(let i = 0; i < 1000; i++){
        generateCharacter(stattotalk);
        outputstring = outputstring + player.clas + "," + player.gender + "," + player.race[0] + "," + player.stats[0] + "," + player.stats[1] + "," + player.stats[2] + "," + player.stats[3] + "," + player.stats[4] + "," + player.stats[5] + "," + player.alignment + "<br>";
      }
    }
  }
  else if(stattotalk > 108){
    stattotalk = 108;
    alert("It is impossible to roll a stat total higher than 108. The stat total has been set to 108.");
    if(confirm("Stat totals less than 36 are very slow to calculate. Do you want to continue?")){
      for(let i = 0; i < 1000; i++){
        var extalignment = document.getElementById("extendedalignment").checked;
        generateCharacter(stattotalk, extalignment);
        outputstring = outputstring + player.clas + "," + player.gender + "," + player.race[0] + "," + player.stats[0] + "," + player.stats[1] + "," + player.stats[2] + "," + player.stats[3] + "," + player.stats[4] + "," + player.stats[5] + "," + player.alignment + "<br>";
      }
    }
  }
  else{
    for(let i = 0; i < 1000; i++){
        var extalignment = document.getElementById("extendedalignment").checked;
      generateCharacter(stattotalk, extalignment);
      outputstring = outputstring + player.clas + "," + player.gender + "," + player.race[0] + "," + player.stats[0] + "," + player.stats[1] + "," + player.stats[2] + "," + player.stats[3] + "," + player.stats[4] + "," + player.stats[5] + "," + player.alignment + "<br>";
    }
  }
  //Output to screen
  document.getElementById("output").innerHTML = outputstring;
}
function buttonPress(){
  //get user presets
  var stattotalbp = parseInt(document.getElementById('stattotalinput').value);
  var extalignment = document.getElementById("extendedalignment").checked;

  console.clear();

  if(isNaN(stattotalbp)){
    stattotalbp = 72;
    generateCharacter(stattotalbp, extalignment);
    writeToScreen();
  }
  else if(stattotalbp < 18){
    alert("It is impossible to roll a stat total lower than 18.");
  }
  else if(stattotalbp > 108){
    alert("It is impossible to roll a stat total higher than 108.");
  }
  else{
    generateCharacter(stattotalbp, extalignment);
    writeToScreen();
  }
}
function generateCharacter(stattotalgc, extalign){
  var racepreset = document.getElementById("raceselection").value;
  var genderpreset = document.getElementById("genderselection").value;
  var classpreset = document.getElementById("classselection").value;
  var lawfulnesspreset = document.getElementById("lawfulnessselection").value;
  var goodnesspreset = document.getElementById("goodnessselection").value;
  var maxstatpreset = document.getElementById("maxstat").checked;
  var randomnum = Math.random();
  var randomnum2 = Math.random();
  var birthyear = parseInt(document.getElementById('birthyearfield').value);
  //choose class
  player.clas = "<font color='red'>DEFAULT_CLASS</font>";
  player.stats = [0,0,0,0,0,0];
  if(maxstatpreset == true && classpreset == "Random"){
    while(player.stats[player.statorder[0]] != 18){
      player.stats = rollCharacter(stattotalgc);
      player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
      player.clas = chooseClass(player.statorder[0], player.statorder[1]);
    }
  }
  else if(maxstatpreset == true){
    while(classpreset != player.clas || player.stats[player.statorder[0]] != 18){
      player.stats = rollCharacter(stattotalgc);
      player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
      player.clas = chooseClass(player.statorder[0], player.statorder[1]);
    }
  }
  else if(classpreset == "Random"){
    player.stats = rollCharacter(stattotalgc);
    player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
    player.clas = chooseClass(player.statorder[0], player.statorder[1]);
  }
  else{
    while(classpreset != player.clas){
      player.stats = rollCharacter(stattotalgc);
      player.statorder = rankStats(player.stats[0], player.stats[1], player.stats[2], player.stats[3], player.stats[4], player.stats[5]);
      player.clas = chooseClass(player.statorder[0], player.statorder[1]);
    }
  }

  //choose discapline
  if(player.clas == "Wizard"){
    player.discapline = magicschools[randomindex(magicschools.length)];
  }

  //choose race
  if(racepreset == "Random"){
    player.race = racelist[randomindex(racelist.length)];
  }
  else if(is_containedin_("Random",racepreset)){
    if(is_containedin_("Human",racepreset)){
      player.race = humanlist[randomindex(humanlist.length)];
    }
    else if(is_containedin_("Dwarf",racepreset)){
      player.race = dwarflist[randomindex(dwarflist.length)];
    }
    else if(is_containedin_("Elf",racepreset)){
      player.race = elflist[randomindex(elflist.length)];
    }
    else if(is_containedin_("Halfling",racepreset)){
      player.race = halflinglist[randomindex(halflinglist.length)];
    }
    else if(is_containedin_("Dragonborn",racepreset)){
      player.race = dragonbornlist[randomindex(dragonbornlist.length)];
    }
    else if(is_containedin_("Gnome",racepreset)){
      player.race = gnomelist[randomindex(gnomelist.length)];
    }
    else if(is_containedin_("Tiefling",racepreset)){
      player.race = tieflinglist[randomindex(tieflinglist.length)];
    }
    else if(is_containedin_("Aasimar",racepreset)){
      player.race2[1] = randomindex(aasimarlist.length);
      player.race[0] = aasimarlist[player.race2[1]][0];
      player.race[1] = aasimarlist[player.race2[1]][1];
    }
    else if(is_containedin_("Genasi",racepreset)){
      player.race = genasilist[randomindex(genasilist.length)];
    }
    else if(is_containedin_("Neufolk",racepreset)){
      player.race = neufolklist[randomindex(neufolklist.length)];
    }
    else if(is_containedin_("Gith",racepreset)){
      player.race = githlist[randomindex(githlist.length)];
    }
    else{
      //console.log(racepreset);
      for(let i = 0; i < racelist.length; i++){
        if(racepreset == racelist[i][0]){
          player.race = racelist[i]
          break;
        }
      }
    }
  }
  else{
    for(let i = 0; i < racelist.length; i++){
      if(racepreset == racelist[i][0]){
        player.race[0] = racelist[i][0];
        player.race[1] = racelist[i][1];
        break;
      }
    }
  }

  //Choose race2
  if(player.race[0].slice(0,7) == "Aasimar" || player.race[0].slice(0,7) == "Yuan-ti"){
    do{
      player.race2 = chooseRace();
    }while(player.race2[0].slice(0,7) == "Aasimar" || player.race2[0].slice(0,7) == "Yuan-ti" || player.race2[0].slice(0,10) == "Changeling");
    player.race2[0] = "(" + player.race2[0] + ")";
    player.race[1] *= player.race2[1];
  }
  else{
    player.race2[0] = "";
  }

  //choose gender
  if(genderpreset == "Random"){
    player.gender = chooseGender();
  }
  else{
    player.gender = genderpreset;
  }
  //choose alignment
  if(extalign == true){
    if(lawfulnesspreset == "Random"){
      player.alignment[0] = chooseSillyAlignment()[0];
    }
    else{
      player.alignment[0] = lawfulnesspreset;
    }
    if(goodnesspreset == "Random"){
      player.alignment[1] = chooseSillyAlignment()[1];
    }
    else{
      player.alignment[1] = goodnesspreset;
    }
  }
  else{
    if(lawfulnesspreset == "Random"){
      player.alignment[0] = chooseAlignment()[0];
    }
    else{
      player.alignment[0] = lawfulnesspreset;
    }
    if(goodnesspreset == "Random"){
      player.alignment[1] = chooseAlignment()[1];
    }
    else{
      player.alignment[1] = goodnesspreset;
    }
  }
  player.alignment = trueNeutral(player.alignment);
  //choose attributes
  if(player.alignment[0] == "Sad" || Math.random() < 0.065){
    player.sad = 1;
  }
  else{
    player.sad = 0;
  }

  //Adoption
  if((Math.random() < 0.05  || player.race[0].slice(0,10) == "Changeling") && player.race[0].slice(0,9) != "Warforged"){
    player.adopted = 1;
    if(Math.random() < 0.5){
      player.adoptedLate = 1;
    }
    else{
      player.adoptedLate = 0;
    }
  }
  else{
    player.adopted = 0;
  }

  chooseSocialClass();
  chooseLocale();

  //generate parents
  player.parent1.gender = chooseGender();
  if(randomnum < 0.2){
    player.parent2.gender = player.parent1.gender;
  }
  else{
    while(player.parent2.gender == "<font color='red'>PARENT_2_GENDER</font>" || player.parent2.gender == player.parent1.gender){
      player.parent2.gender = chooseGender();
    }
  }
  if(!player.adopted){
    if(player.race[0].slice(0,7) == "Aasimar" || player.race[0].slice(0,7) == "Yuan-ti"){
      player.parent1.race[0] = player.race2[0].substring(1,player.race2[0].length-1);
      player.parent1.race[1] = player.race2[1];
      player.parent2.race[0] = player.race2[0].substring(1,player.race2[0].length-1);
      player.parent2.race[1] = player.race2[1];
    }
    else{
      if(player.race[0] == "Warforged"){
        if(Math.random() < 0.25){
          player.parent1.race = ["Machine", Math.floor(Math.random()*150+50)];
          player.parent2.race = ["N/A", 1];
          player.parent1.gender = "N/A";
          player.parent2.gender = "N/A";
        }
        else{
          player.parent1.race = chooseRace();
          player.parent2.race = chooseRace();
        }
      }
      else{
        player.parent1.race = player.race;
        player.parent2.race = player.race;
      }
    }
  }
  else{
    if(Math.random() < 0.5){
      do{
        player.parent1.race = chooseRace();
      }while(player.parent1.race[0].slice(0,7) == "Aasimar" || player.parent1.race[0].slice(0,10) == "Changeling" || player.parent1.race[0].slice(0,7) == "Yuan-ti");
      player.parent2.race = player.parent1.race;
    }
    else{
      do{
        player.parent1.race = chooseRace();
      }while(player.parent1.race[0].slice(0,7) == "Aasimar" || player.parent1.race[0].slice(0,10) == "Changeling" || player.parent1.race[0].slice(0,7) == "Yuan-ti");
      do{
        player.parent2.race = chooseRace();
      }while(player.parent2.race[0].slice(0,7) == "Aasimar" || player.parent2.race[0].slice(0,10) == "Changeling" || player.parent2.race[0].slice(0,7) == "Yuan-ti");
    }
  }
  // choose parents professions
  if(player.race[0] != "Warforged"){
    player.parent1.profession = randomprofession([player.locale,player.socialclass]);
    player.parent2.profession = randomprofession([player.locale,player.socialclass]);
  }
  else{
    if(player.parent1.race[0] == "Machine"){
      player.parent1.profession = "Machine";
      player.parent2.profession = "N/A";
    }
    else{
      player.parent1.profession = "Inventor";
      player.parent2.profession = "N/A";
    }
  }

  if(player.sad){
    if(Math.random() < 0.5){
      player.parent1.dead = " (dead)";
    }
    else{
      player.parent1.dead = "";
    }
    if(Math.random() < 0.5){
      player.parent2.dead = " (dead)";
    }
    else{
      player.parent2.dead = "";
    }
  }
  else{
    if(Math.random() < 0.015){
      player.parent1.dead = " (dead)";
    }
    else{
      player.parent1.dead = "";
    }
    if(Math.random() < 0.015){
      player.parent2.dead = " (dead)";
    }
    else{
      player.parent2.dead = "";
    }
  }

  player.hometown = cities[randomindex(cities.length)];

  //Naming
  //Parent #1
  if(player.race[0] != "Warforged"){
    player.parent1.fullname = choosename(player.parent1.race[0], player.parent1.gender,player.alignment);
  }
  else{
    if(player.parent1.race[0] == "Machine"){
      player.parent1.fullname = ["Assembling Machine #" + randomindex(125), "", ""];
      player.parent2.fullname = ["N/A", "", ""];
    }
    else{
      player.parent1.fullname = choosename(player.parent1.race[0], player.parent1.gender,player.alignment);
    }
  }
  //Parent #2
  if(player.race[0] != "Warforged"){
    do{
      player.parent2.fullname = choosename(player.parent2.race[0], player.parent2.gender,player.alignment);
    }while(player.parent2.fullname[0] == player.parent1.fullname[0] && player.parent2.fullname[0].slice(-8) != "E</abbr>" && player.parent2.fullname[0].slice(-15) != "E</font></abbr>");
  }
  //player
  if(player.adopted && !player.adoptedLate){
    if(Math.random() < 0.5){
      do{
        player.fullname = choosename(player.parent1.race[0], player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
    else{
      do{
        player.fullname = choosename(player.parent2.race[0], player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
  }
  else{
    if(player.race[0].slice(0,7) == "Aasimar" || player.race[0].slice(0,7) == "Yuan-ti"){
      do{
        player.fullname = choosename(player.race2[0].substring(1,player.race2[0].length-1), player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
    else if(player.race[0].slice(0,10) == "Changeling"){
      if(Math.random() < 0.5){
        do{
          player.fullname = choosename(player.parent1.race[0], player.gender, player.alignment);
        }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
      }
      else{
        do{
          player.fullname = choosename(player.parent2.race[0], player.gender, player.alignment);
        }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
      }
    }
    else{
      do{
        player.fullname = choosename(player.race[0], player.gender,player.alignment);
      }while((player.fullname[0] == player.parent1.fullname[0] || player.fullname[0] == player.parent2.fullname[0]) && player.fullname[0].slice(-8) != "E</abbr>" && player.fullname[0].slice(-15) != "E</font></abbr>");
    }
  }

  //Naming rigamaroll
  if(player.race[0].slice(0,9) != "Warforged"){
    if(Math.random() < 0.85){
      if(Math.random() < 0.5){
        player.parent2.fullname[1] = player.parent1.fullname[1];
      }
      else{
        player.parent1.fullname[1] = player.parent2.fullname[1];
      }
    }
    if(player.parent1.fullname[1] != player.parent2.fullname[1]){
      player.fullname[1] = player.parent1.fullname[1] + "-" + player.parent2.fullname[1];
    }
    else{
      player.fullname[1] = player.parent1.fullname[1];
    }
  }

  //birthday stuff
  if(isNaN(birthyear)){
    birthyear = randomindex(500) + 1250;
  }
  if(birthyear % 400 == 0 || (birthyear % 100 != 0 && birthyear % 4 == 0)){
    player.birthday = dateToDays([1,1,birthyear]) + randomindex(366);
  }
  else{
    player.birthday = dateToDays([1,1,birthyear]) + randomindex(365);
  }
  player.parent1.birthday = player.birthday - yearToDay(0.626785414373 * (player.parent1.race[1]**0.766203192397)) - Math.floor(0.65 * normalyear(0.626785414373 * (player.parent1.race[1]**0.766203192397)));
  player.parent2.birthday = player.birthday - yearToDay(0.626785414373 * (player.parent2.race[1]**0.766203192397)) - Math.floor(0.65 * normalyear(0.626785414373 * (player.parent2.race[1]**0.766203192397)));
}
function is_containedin_(littlestring,bigstring){
  if(littlestring.length > bigstring.length){
    return 0;
  }
  for(let i = 0; i < bigstring.length-littlestring.length+1; i++){
    for(let j = 0; j < littlestring.length; j++){
      if(littlestring[j] != bigstring[i+j]){
        break;
      }
      if(j == littlestring.length-1){
        return i+1;
      }
    }
  }
  return 0;
}
function dateToDATE(datevar){
  var ththing = "<sup>";  //ya know, the th thing
  var outputvar = "";  //output to be returned
  var monname = "";  //name of the month

  if(datevar[0] % 100 >= 9 && datevar[0] % 100 <= 20){
    ththing += "th";
  }
  else if(datevar[0] % 10 == 1){
    ththing += "st";
  }
  else if(datevar[0] % 10 == 2){
    ththing += "nd";
  }
  else if(datevar[0] % 10 == 3){
    ththing += "rd";
  }
  else{
    ththing += "th";
  }
  ththing += "</sup>";

  if(datevar[1] == 1){
    monname = "January";
  }
  else if(datevar[1] == 2){
    monname = "February";
  }
  else if(datevar[1] == 3){
    monname = "March";
  }
  else if(datevar[1] == 4){
    monname = "April";
  }
  else if(datevar[1] == 5){
    monname = "May";
  }
  else if(datevar[1] == 6){
    monname = "June";
  }
  else if(datevar[1] == 7){
    monname = "July";
  }
  else if(datevar[1] == 8){
    monname = "August";
  }
  else if(datevar[1] == 9){
    monname = "September";
  }
  else if(datevar[1] == 10){
    monname = "October";
  }
  else if(datevar[1] == 11){
    monname = "November";
  }
  else if(datevar[1] == 12){
    monname = "December";
  }
  else{
    monname = "INVALID_MONTH";
  }

  outputvar += datevar[0] + ththing + " ";
  outputvar += monname + " ";
  outputvar += datevar[2];

  return outputvar;

}
function daysToDate(longdays){
  var datevar = [0,0,0];
  var daysinmonths = [31,28,31,30,31,30,31,31,30,31,30,31];
  var leapdaysinmonths = [31,29,31,30,31,30,31,31,30,31,30,31];

  //years
  //400s chunk
  datevar[2] += Math.floor(longdays / 146097) * 400;
  longdays = longdays % 146097;
  //100s chunk
  if(longdays >= 36525){
    datevar[2] += 100;
    longdays -= 36525;
    datevar[2] += Math.floor(longdays / 36524) * 100;
    longdays = longdays % 36524;
  }
  //4s chunk
  if(datevar[2] % 400 != 0){
    if(longdays >= 1460){
      datevar[2] += 4;
      longdays -= 1460;
      datevar[2] += Math.floor(longdays / 1461) * 4;
      longdays = longdays % 1461;
    }
  }
  else{
    if(longdays >= 1461){
      datevar[2] += Math.floor(longdays / 1461) * 4;
      longdays = longdays % 1461;
    }
  }
  //1s chunk
  for(let i = 0; i < 4; i++){
    if(datevar[2] % 400 == 0 || (datevar[2] % 100 != 0 && datevar[2] % 4 == 0)){
      if(longdays >= 366){
        datevar[2]++;
        longdays -= 366;
      }
      else{
        break;
      }
    }
    else{
      if(longdays >= 365){
        datevar[2]++;
        longdays -= 365;
      }
      else{
        break;
      }
    }
  }

  //months
  if(datevar[2] % 400 == 0 || (datevar[2] % 100 != 0 && datevar[2] % 4 == 0)){
    for(let i = 0; i < 12; i++){
      if(leapdaysinmonths[i] > longdays){
        break;
      }
      datevar[1]++;
      longdays -= leapdaysinmonths[i];
    }
  }
  else{
    for(let i = 0; i < 12; i++){
      if(daysinmonths[i] > longdays){
        break;
      }
      datevar[1]++;
      longdays -= daysinmonths[i];
    }
  }
  datevar[1]++;

  //days
  datevar[0] = longdays + 1;

  return datevar;
}
function dateToDays(datevar){
  var longdays = 0;
  var daysinmonths = [31,28,31,30,31,30,31,31,30,31,30,31];
  var leapdaysinmonths = [31,29,31,30,31,30,31,31,30,31,30,31];
  var orgyear = datevar[2]; //original year value that will not be edited

  datevar[0] -= 1;
  datevar[1] -= 1;

  //years
  //400s chunk
  longdays += Math.floor(datevar[2] / 400) * 146097;
  datevar[2] = datevar[2] % 400;
  //100s chunk
  if(datevar[2] >= 100){
    longdays += 36525;
    datevar[2] -= 100;
  }
  longdays += Math.floor(datevar[2] / 100) * 36524;
  datevar[2] = datevar[2] % 100;
  //4s chunk
  if(datevar[2] > 3 && (orgyear - datevar[2]) % 400 != 0){
    longdays += 1460;
    datevar[2] -= 4;
  }
  longdays += Math.floor(datevar[2] / 4) * 1461;
  datevar[2] = datevar[2] % 4;
  //1s chunk
  if(datevar[2] > 0 && (orgyear % 100 > 3 || orgyear % 400 <= 3)){
    longdays += 366;
    datevar[2]--;
  }
  longdays += datevar[2] * 365;

  //months
  if(orgyear % 400 == 0 || (orgyear % 100 != 0 && orgyear % 4 == 0)){
    for(let i = 0; i < datevar[1]; i++){
      longdays += leapdaysinmonths[i];
    }
  }
  else{
    for(let i = 0; i < datevar[1]; i++){
      longdays += daysinmonths[i];
    }
  }

  //days
  longdays += datevar[0];

  return longdays;
}
function normaldist(maxnum){
  var summation = 0;
  var iterations = 5;
  for(let i = 0; i < iterations; i++){
    summation += Math.random();
  }
  return Math.floor(summation * maxnum / iterations);
}
function normalyear(years){
  return normaldist(365*2*years);
}
function yearToDay(years){
  return Math.floor(years * 365.2425);
}
function chooseSocialClass(){
  var randomnum = Math.random();

  if(randomnum < 0.15){
    player.socialclass = "wealthy";
  }
  else{
    player.socialclass = "poor";
  }
}
function chooseLocale(){
  var randomnum = Math.random();

  if(player.socialclass == "wealthy"){
    player.locale = "urban";
  }
  else{
    if(randomnum < 1/4.63){
      player.locale = "urban";
    }
    else{
      player.locale = "rural";
    }
  }
}
function chooseRace(){
  return racelist[randomindex(racelist.length)];
}
function randomindex(length){
  return Math.floor(length * Math.random());
}
function cap(strin){
  strin = strin[0].toUpperCase() + strin.slice(1-strin.length);
  return strin;
}
function sub(gender){
  if(gender == "M"){
    return "he";
  }
  else if(gender == "F"){
    return "she";
  }
  else if(gender == "NB"){
    return "they";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function obj(gender){
  if(gender == "M"){
    return "him";
  }
  else if(gender == "F"){
    return "her";
  }
  else if(gender == "NB"){
    return "them";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function pos(gender){
  if(gender == "M"){
    return "his";
  }
  else if(gender == "F"){
    return "her";
  }
  else if(gender == "NB"){
    return "their";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function is(gender){
  if(gender == "M"){
    return "is";
  }
  else if(gender == "F"){
    return "is";
  }
  else if(gender == "NB"){
    return "are";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function was(gender){
  if(gender == "M"){
    return "was";
  }
  else if(gender == "F"){
    return "was";
  }
  else if(gender == "NB"){
    return "were";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function has(gender){
  if(gender == "M"){
    return "has";
  }
  else if(gender == "F"){
    return "has";
  }
  else if(gender == "NB"){
    return "have";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function ess(gender){
  if(gender == "M"){
    return "s";
  }
  else if(gender == "F"){
    return "s";
  }
  else if(gender == "NB"){
    return "";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function kidword(gender){
  if(gender == "M"){
    return "boy";
  }
  else if(gender == "F"){
    return "girl";
  }
  else if(gender == "NB"){
    return "kid";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function adultword(gender){
  if(gender == "M"){
    return "man";
  }
  else if(gender == "F"){
    return "woman";
  }
  else if(gender == "NB"){
    return "person";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function parent(gender){
  if(gender == "M"){
    return "father";
  }
  else if(gender == "F"){
    return "mother";
  }
  else if(gender == "NB"){
    return "parent";
  }
  else{
    return "<font color='red'>ERROR</font>";
  }
}
function birthtype(race){
  if(race == "Aarakocra" || race == "Thri-kreen" || is_containedin_("Dragonborn",race) || race == "Dohwar" || race == "Kenku" || race == "Tortle" || race == "Lizardfolk"){
    return "hatched";
  }
  else if(race == "Warforged" || race == "Autognome"){
    return "assembled";
  }
  else if(race == "Plasmoid"){
    return "split";
  }
  else{
    return "born";
  }
}
function birthphrase(race){
  if(race == "Aarakocra" || race == "Thri-kreen" || is_containedin_("Dragonborn",race) || race == "Dohwar" || race == "Kenku" || race == "Tortle" || race == "Lizardfolk"){
    return "hatched by";
  }
  else if(race == "Warforged" || race == "Autognome"){
    return "assembled by";
  }
  else if(race == "Plasmoid"){
    return "split from";
  }
  else{
    return "born to";
  }
}
function birthadj(race){
  if(race == "Aarakocra" || race == "Thri-kreen" || is_containedin_("Dragonborn",race) || race == "Dohwar" || race == "Kenku" || race == "Tortle" || race == "Lizardfolk"){
    return "hatch";
  }
  else if(race == "Warforged" || race == "Autognome"){
    return "assemble";
  }
  else if(race == "Plasmoid"){
    return "split";
  }
  else{
    return "birth";
  }
}
function randomprofession(section){
  var randomnum = Math.random();
  var randomnum2 = Math.random();
  if(section[1] == "wealthy"){
    return wealthyprofessions[randomindex(wealthyprofessions.length)];
  }
  else if(section[0] == "urban"){
    return urbanprofessions[randomindex(urbanprofessions.length)];
  }
  else if(section[0] == "rural"){
    return ruralprofessions[randomindex(ruralprofessions.length)];
  }
  else{
    return "idk what this locale/social class is";
  }
}
function formname(namearray){
  return namearray[0] + " " + namearray[1];
}
function backstory(){
  var b_story = "Backstory (wip):<br>";                   //stores the long backstory formatting string
  var tablarray = [];                           //an array that holds the contents of the backstory table
  var possibclas = [];                          //an array that holds possible backstory paths the player could take and their weights
  var bslist = [];                            //an array that holds the backstory paths the player will go down
  var weightot = 0;                             //keeps track of the total of weights from paths in possibs
  var pathselector = 0;                           //stores the random selection for each backstory path
  var adoptiondate = 0;                           //date of the players adoptiong, if applicable
  var recurringsymbol = logos[randomindex(logos.length)];         //for keeping track of a recurring symbol in the backstory
  var mentor = [["FIRST_NAME","LAST_NAME"],chooseGender(),chooseAlignment()];         //Players mentor
  mentor[0] = choosename(chooseRace()[0],mentor[1],mentor[2]);
  while(mentor[0] == "<font color='red'>FIRST_NAME</font>"){
    mentor[0] = choosename(chooseRace()[0],mentor[1],mentor[2]);
  }
  tavern = "The "+tavernadj[randomindex(tavernadj.length)]+" "+tavernnoun[randomindex(tavernnoun.length)];
  var namestolen = 2;                           //Players name stolen    0 = name needs to be stolen
  var namestolenp1 = 2;                           //Parent 1s name stolen  1 = name already stolen
  var namestolenp2 = 2;                           //Parent 2s name stolen  2 = name not stolen
  var shortestindex = [0,player.birthday + 36525];            //forgot what this is for. its in the sorting phase somewhere
  var holdingvar = [];                          //for holding a table row in the sorting phase
  var currentdate = player.birthday;                    //for keeping track of dates in ordered events
  var maturage = 0.626785414373 * (player.race[1]**0.766203192397);      //age of maturity
  var normaturage = maturage / (0.626785414373 * (humanlist[0][1]**0.766203192397));  //age of maturity normalized to human development

  //write backstory events and dates in a 2d array
  tablarray.push([player.birthday,player.fullname[0] + " is " + birthtype(player.race[0]) + "."]);
  tablarray.push([dateToDays([daysToDate(player.birthday)[0],daysToDate(player.birthday)[1],daysToDate(player.birthday)[2]+Math.floor(maturage)]),"<font color=#C5C59C>" + player.fullname[0] + " becomes an adult.</font>"]);
  tablarray.push([dateToDays([daysToDate(player.birthday)[0],daysToDate(player.birthday)[1],daysToDate(player.birthday)[2]+Math.floor(player.race[1])]),"<font color=#C5C59C>" + player.fullname[0] + " reaches " + pos(player.gender) + " life expectancy.</font>"]);

  //console.log(dateToDATE(daysToDate(player.birthday)));
  //console.log(dateToDATE([daysToDate(player.birthday)[0],daysToDate(player.birthday)[1],daysToDate(player.birthday)[2]+Math.floor(maturage)]));

  //ordering test
  //for(let i = 0; i < 10; i++){
  //  tablarray.push([player.birthday + randomindex(1000),"event " + i]);
  //}

  //Name-stealing prep
  if(player.fullname[0] == "<abbr title=\"Fey\"></abbr>"){
    namestolen = 0;
  }
  if(player.parent1.fullname[0] == "<abbr title=\"Fey\"></abbr>"){
    namestolenp1 = 0;
  }
  if(player.parent2.fullname[0] == "<abbr title=\"Fey\"></abbr>"){
    namestolenp2 = 0;
  }

  //adoption
  if(player.adopted){
    if(!player.adoptedLate){
      adoptiondate = player.birthday + normaldist(365*3);
    }
    else{
      adoptiondate = player.birthday + normalyear(10);
    }
  }
  if(player.adopted){
    if(!player.adoptedLate){
      tablarray.push([adoptiondate,player.fullname[0] + " is adopted by " + formname(player.parent1.fullname) + " and " + formname(player.parent2.fullname) + "."]);
    }
    else{
      tablarray.push([adoptiondate,player.fullname[0] + " is adopted by " + formname(player.parent1.fullname) + " and " + formname(player.parent2.fullname) + "."]);
    }
  }

  //kill single parent
  if(player.parent1.dead != player.parent2.dead){
    if(player.parent1.dead == " (dead)"){
      if(player.locale == "urban"){
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(366*12.5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent1.fullname[0] + ", hitting " + obj(player.parent1.gender) + " in the neck and killing " + obj(player.parent1.gender) + " while " + sub(player.parent1.gender) + " " + was(player.parent1.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent1.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent1.fullname[0] + ", hitting " + obj(player.parent1.gender) + " in the neck and killing " + obj(player.parent1.gender) + " while " + sub(player.parent1.gender) + " " + was(player.parent1.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent1.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent1.fullname[0] + ", hitting " + obj(player.parent1.gender) + " in the neck and killing " + obj(player.parent1.gender) + " while " + sub(player.parent1.gender) + " " + was(player.parent1.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent1.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
      }
      else{  //rural
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(365*12.5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent1.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent1.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent1.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
      }
    }
    else{  //parent 2 is dead
      if(player.locale == "urban"){
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(366*12.5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent2.fullname[0] + ", hitting " + obj(player.parent2.gender) + " in the neck and killing " + obj(player.parent2.gender) + " while " + sub(player.parent2.gender) + " " + was(player.parent2.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent2.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent2.fullname[0] + ", hitting " + obj(player.parent2.gender) + " in the neck and killing " + obj(player.parent2.gender) + " while " + sub(player.parent2.gender) + " " + was(player.parent2.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent2.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),"An assassination is attempted on " + formname(choosename(chooseRace()[0],chooseGender(),["Lawful","Evil"])) + ", a noble from " + player.hometown[0] + ". It failed and the stray arrow struck " + player.parent2.fullname[0] + ", hitting " + obj(player.parent2.gender) + " in the neck and killing " + obj(player.parent2.gender) + " while " + sub(player.parent2.gender) + " " + was(player.parent2.gender) + " in the market with " + player.fullname[0] + ". Bending down desperately to help " + pos(player.gender) + " " + parent(player.parent2.gender) + ", " + player.fullname[0] + " notices the arrow's shaft bears the image of a " + recurringsymbol + "."]);
        }
      }
      else{  //rural
        if(!player.adopted){
          tablarray.push([player.birthday + normaldist(365*12.5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent2.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else if(player.adoptedLate){
          tablarray.push([adoptiondate + normaldist(365*5),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent2.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
        else{
          tablarray.push([adoptiondate + normaldist(365*12),player.fullname[0] + " hears a <i>clunk</i> in the middle of the night, and goes to investigate. " + cap(sub(player.gender)) + " looks outside to see a handful of figures running into the darkness. Just outside " + pos(player.gender) + " parents' bedroom, " + sub(player.gender) + " found " + pos(player.gender) + " " + parent(player.parent2.gender) + " lying on the floor, bleeding to death. Nearby on the floor, was a broken brooch bearing the image of a " + recurringsymbol + "."]);
        }
      }
    }
  }


  //parent profession stuff

  //highest stat stuff
  if(player.statorder[0] == 0){    //strength
    currentdate = player.birthday + yearToDay(12) + normalyear(4);
    if(player.alignment[1] == "Stupid" && Math.random() < 0.5){
      tablarray.push([currentdate,"A rock, about the size of a bowling ball, catches " + player.fullname[0] + "'s eye. It vaguely resembled a smiley-face, so " + sub(player.gender) + " carried it home."]);
      currentdate += normalyear(0.7);
      tablarray.push([currentdate,"Carrying the rock with " + obj(player.gender) + " at all times, caused " + player.fullname[0] + " to build muscle and get stronger than " + pos(player.gender) + " peers."]);
    }
    else if(player.alignment[0]){
    }
  }
  else if(player.statorder[0] = 1){  //dexterity
  }
  else if(player.statorder[0] = 2){  //constitution
  }
  else if(player.statorder[0] = 3){  //intelligence
  }
  else if(player.statorder[0] = 4){  //wisdom
  }
  else{          //charisma
  }

  //class stuff
  if(player.clas == "Artificer"){
    possibclas.push(["Artificer_default",1]);
    if(player.alignment[1] == "Stupid" || player.stats[4] < 10){
      possibclas.push["Artificer_binney",10];
      // 
    }
  }
  else if(player.clas == "Barbarian"){
    possibclas.push(["Barbarian_default",1]);
    if(player.alignment[1] == "Good" || player.alignment[1] == "Stupid"){
      possibclas.push(["Barbarian_mythra",10]);
      // grows up in a remote village, chopping trees
      // parents talk to the player and tell them it is time to find themselves by going on a quest
      // the player decides to prove themself by defeating a very powerful creature (subjective)
    }
  }
  else if(player.clas == "Bard"){
    possibclas.push(["Bard_default",1]);
    // 
    if(player.alignment[1] != "Good" && player.alignment[1] != "Stupid" && player.socialclass == "poor"){
      if(player.alignment[1] == "Evil"){
        possibclas.push(["Bard_scammer",10]);
        // player is starving and is forced to steal bread. they lie to the baker, telling them a very wealthy person will arrive soon. the baker starts baking more breads and the player steals what they can while the bakers back is turned.
        // the player tells a similar lie to get better food
        // the player does it again to get fine clothes (random color/style)
        // lies to get fine jewelery (similarly random)
        // lies to get an audience with the mayor or whatever and convinces them that the bakers bakery is rightfully theirs and so aquires the deed
        // the player kicks the baker out of thier home/workplace with the power of the city guard behind them
      }
      else{
        possibclas.push(["Bard_charlatan"],10);
        // is a nonmagical illusionist
        // a wizard notices the players skill and mistakes it for arcane talent
        // the player attends wizard school, faking their way through
        // the player realizes that their pure charisma is able to conjure magic even though their technique sucks
      }
    }
    if(player.sad == 1){
      possibclas.push(["Bard_distraction",10]);
    }
    if(player.stats[0] < 10 || player.stats[2] < 10){
      possibclas.push(["Bard_old_adventurer",10]);
    }
  }
  else if(player.clas == "Cleric"){
    possibclas.push(["Cleric_default",1]);
    if(player.alignment[0] == "Lawful" && player.alignment[1] == "Good" && player.parent1.profession != "Cleric" && player.parent1.profession != "Cleric"){
      possibclas.push(["Cleric_found_god",10]);
    }
  }
  else if(player.clas == "Druid"){
    possibclas.push(["Druid_default",1]);
  }
  else if(player.clas == "Fighter"){
    possibclas.push(["Fighter_default",1]);
  }
  else if(player.clas == "Monk"){
    possibclas.push(["Monk_default",1]);
    if(player.socialclass == "wealthy"){
      if(player.sad == 1){
        possibclas.push(["Monk_sad_batman",10]);
      }
      else{
        possibclas.push(["Monk_batman",10]);
      }
    }
  }
  else if(player.clas == "Paladin"){
    possibclas.push(["Paladin_default",1]);
    if(player.parent1.dead == " (dead)" || player.parent2.dead == " (dead)"){
      possibclas.push(["Paladin_revenge",10]);
    }
  }
  else if(player.clas == "Ranger"){
    possibclas.push(["Ranger_default",1]);
    if(player.sad == 1){
      if(player.parent1.dead == 1 || player.parent2.dead == 1){
        possibclas.push(["Ranger_sad_parent",10]);
      }
      else{
        possibclas.push(["Ranger_sad_pet",10]);
      }
    }
  }
  else if(player.clas == "Rogue"){
    possibclas.push(["Rogue_default",1]);
    if(player.socialclass == "wealthy"){
      if(player.sad == 1){
        possibclas.push(["Rogue_sad_batman",10]);
      }
      else{
        possibclas.push(["Rogue_batman",10]);
      }
    }
  }
  else if(player.clas == "Sorcerer"){
    if(daysToDate(player.birthday)[1] == 2 && daysToDate(player.birthday)[0] == 29){
      //Leap day sorcerer
      possibclas.push(["Sorcerer_leap",100]);
    }
    else if(daysToDate(player.birthday)[1] <= 2 || daysToDate(player.birthday)[1] == 12){
      //Winter sorcerer
      possibclas.push(["Sorcerer_winter",1]);
    }
    else if(daysToDate(player.birthday)[1] <= 5){
      //Spring sorcerer
      possibclas.push(["Sorcerer_Spring",1]);
    }
    else if(daysToDate(player.birthday)[1] <= 8){
      //Summer sorcerer
      possibclas.push(["Sorcerer_Summer",1]);
    }
    else if(daysToDate(player.birthday)[1] <= 11){
      //Autumn sorcerer
      possibclas.push(["Sorcerer_autumn",1]);
    }
    else{
      possibclas.push(["Sorcerer_default",1]);
    }
  }
  else if(player.clas == "Warlock"){
    possibclas.push(["Warlock_default",1]);
  }
  else if(player.clas == "Wizard"){
    //Defalut wizard
    possibclas.push(["Wizard_default",1]);
    //Charlatan wizard
    if(statRank(5,player.statorder) < 2 && player.alignment[1] == "Evil"){
      possibclas.push(["Wizard_charlatan",10]);
    }
    if(player.alignment[0] == "Smart" || player.stats[3] == 18){
      //Insane wizard
      if(player.alignment[1] == "Stupid" || statRank(4,player.statorder) >= 4){
        possibclas.push(["Wizard_insane",10]);
        // goes to wizard school
        // gets into trouble experimenting
        // accidentally traps roommate in (now) sentient magic item
        // gets kicked out of wizard school
      }
      //Genius wizard
      possibclas.push(["Wizard_genius",10]);
      // is spotted by an older wizard who sees potential in the player
      // goes to wizard school and knocks it out of the park
      // invents womething extraordinary, now people are after the player for the details
    }
    if(player.race[0] != "Yuan-ti" && player.stats[4] < 8 && player.alignment[1] != "Evil"){
      possibclas.push(["Wizard_truman",7]);
    }
    //Dumb-Luck wizard
    if(player.alignment[1] == "Stupid" && player.stats[3] < 10){
      possibclas.push(["Wizard_dumb-luck",10]);
    }
    //Altruist wizard
    if(player.alignment[1] == "Good"){
      possibclas.push(["Wizard_altruist",10]);
    }
  }
  else{
    possibclas.push(["What_class_default",1]);
  }

  //decide backstory paths
  //class
  for(let i = 0; i < possibclas.length; i++){
    weightot += possibclas[i][1];    //sum the weights
  }
  pathselector = randomindex(weightot);
  console.log(possibclas);
  console.log("Total of Weights = " + weightot);
  console.log("Path Selector =  " + pathselector);
  for(let i = 0; i < possibclas.length; i++){
    pathselector -= possibclas[i][1];
    console.log("Path Selector =  " + pathselector);
    if(pathselector <= 0){
      bslist.push(possibclas[i]);
      break;
    }
  }

  console.log(bslist);

  //expand class backstory paths to events
          tablarray.push([player.birthday+1,bslist[0][0] + " backstory"]);
          if(player.clas == "Artificer"){
    if(bslist[0][0] == "Artificer_default"){
      currentdate = Math.round(player.birthday+(((6*365)+normalyear(8))*normaturage));
      tablarray.push([currentdate,mentor[0][0]+" "+mentor[0][1]+", a local smith and tinker, teaches "+player.fullname[0]+" how to make tiny <a href=\"https://www.dndbeyond.com/species/18-gnome#RockGnome\">clockwork devices</a> and finds "+sub(player.gender)+" "+has(player.gender)+" a knack for it."]);
      currentdate += normaldist(400);
      tablarray.push([currentdate,mentor[0][0]+" continues to teach "+player.fullname[0]+" about smithing and artificing and shows "+obj(player.gender)+" how to use basic magic to send short messages telepathically."]);
      currentdate += normaldist(400);
      if(player.locale == "rural"){
        tablarray.push([currentdate,mentor[0][0]+" asks "+player.fullname[0]+" to help "+obj(mentor[1])+" design and build a bridge just outside "+player.hometown[0]+". "+player.fullname[0]+" feel"+ess(player.gender)+" excited and a bit nervous at the thought of undertaking such a large project."]);
        currentdate += normaldist(45);
        tablarray.push([currentdate,player.fullname[0]+" helps "+mentor[0][0]+" build a bridge just outside "+player.hometown[0]+". "+cap(sub(player.gender))+" feel"+ess(player.gender)+" emboldened upon completing such a large project."]);
      }
      else{
        tablarray.push([currentdate,mentor[0][0]+" asks "+player.fullname[0]+" to help "+obj(mentor[1])+" design and build a crane for stacking crates in a warehouse on the outskirts of "+player.hometown[0]+". "+player.fullname[0]+" is excited and a bit nervous at the thought of undertaking such a large project."]);
        currentdate += normaldist(60);
        tablarray.push([currentdate,player.fullname[0]+" and "+mentor[0][0]+" complete construction on the crane. "+player.fullname[0]+" feel"+ess(player.gender)+" satisfied with having completed such a large and complex project."]);
      }
      currentdate += normalyear(3.5);
      tablarray.push([currentdate,player.fullname[0]+" begins feeling comfortable combining "+pos(player.gender)+" mundane creations with magic on "+pos(player.gender)+" own."]);
    }
  }
  else if(player.clas == "Barbarian"){
    if(bslist[0][0] == "Barbarian_default"){
      currentdate = Math.round(player.birthday+((4*365)+normalyear(4)));
      if(player.locale == "urban"){
        tablarray.push([currentdate,player.fullname[0]+" begins to explore parts of "+player.hometown[0]+" "+pos(player.gender)+" parents told "+obj(player.gender)+" not to go."]);
        currentdate += normaldist(14);
        tablarray.push([currentdate,"A fight breaks out in the "+tavern+", a local tavern, while "+player.fullname[0]+" is there. "+cap(sub(player.gender))+" is hit by a thrown tankard, staggers back and is deeply cut by a stray sword blade across "+pos(player.gender)+" "+bodypartsext[randomindex(bodypartsext.length)]+"."]);
        if(player.parent1.dead != " (dead)" && player.parent2 != " (dead)"){
          tablarray.push([currentdate,player.parent1.fullname[0]+" notices "+player.fullname[0]+"\'s wound and dresses it."]);
        }
        else if(player.parent1.dead == " (dead)"){
          tablarray.push([currentdate,player.parent2.fullname[0]+" notices "+player.fullname[0]+"\'s wound and dresses it."]);
        }
        else if(player.parent2.dead == " (dead)"){
          tablarray.push([currentdate,player.parent1.fullname[0]+" notices "+player.fullname[0]+"\'s wound and dresses it."]);
        }
        else{
          tablarray.push([currentdate,player.fullname[0]+"\'s isn't noticed by anyone because "+sub(player.gender)+" is an orphan."]);
        }
        currentdate += 1;
        tablarray.push([currentdate,player.fullname[0]+" is walking through the city when "+sub(player.gender)+" is stopped by an imposing-looking "+adultword(mentor[1])+". "+mentor[2][1]]);
      }
      else{
        tablarray.push([currentdate,player.fullname[0]+" wanders into the wilderness surrounding "+player.hometown[0]+", in search of adventures like in the stories "+sub(player.gender)+" was told by "+pos(player.gender)+" parents."]);
        currentdate += normaldist(28);
        tablarray.push([currentdate,"Having explored outside of town for several days, "+player.fullname[0]+" is suddenly tackled to the ground by a large "+smallbeasts[randomindex(smallbeasts.length)]+". Mere seconds later, the beast itself is tackled by a "+adultword(mentor[1])+" with an imposing figure. "+player.fullname[0]+" could do nothing but watch with amazement while the unfamiliar "+adultword(mentor[1])+" wrestled "+pos(mentor[1])+" opponent into submission. After the ordeal was over, the "+adultword(mentor[1])+" approached "+player.fullname[0]+".<br>Strange "+adultword(mentor[1])+": That was a close one. I'm "+mentor[0][0]+" "+mentor[0][1]+". Who might you be?<br>"+player.fullname[0]+": uh uhh "+player.fullname[0]+", "+player.fullname[0]+" "+player.fullname[1]+".<br>"+mentor[0][0]+": And where are you from, little "+player.fullname[0]+"?<br>"+player.fullname[0]+": Uh, I'm f-from "+player.hometown[0]+".<br>"+mentor[0][0]+": You're a bit far from home, aren't you? Let's get you back where you belong."]);
        currentdate += 2;
        if(player.parent1.dead != " (dead)" && player.parent2 != " (dead)"){
          tablarray.push([currentdate,"Upon "+player.fullname[0]+" being returned to "+pos(player.gender)+" home in "+player.hometown[0]+", "+player.parent2.fullname[0]+" and "+player.parent1.fullname[0]+" are incredibly relieved to see that their "+kidword(player.gender)+" is safe."]);
        }
        else if(player.parent1.dead != " (dead)"){
          tablarray.push([currentdate,"Upon "+player.fullname[0]+" being returned to "+pos(player.gender)+" home in "+player.hometown[0]+", "+player.parent1.fullname[0]+" is incredibly relieved to see that "+pos(player.parent1.gender)+" "+kidword(player.gender)+" is safe."]);
        }
        else if(player.parent2.dead != " (dead)"){
          tablarray.push([currentdate,"Upon "+player.fullname[0]+" being returned to "+pos(player.gender)+" home in "+player.hometown[0]+", "+player.parent2.fullname[0]+" is incredibly relieved to see that "+pos(player.parent2.gender)+" "+kidword(player.gender)+" is safe."]);
        }
        else{
            tablarray.push([currentdate,"After being led aimlessly through town, "+mentor[0][0]+" realizes that "+player.fullname[0]+" doesn't have parents to be returned to and decides to take"+obj(player.gender)+" under "+pos(mentor[1])+" wing."]);
        }
      }
    }
  }

  //sort array by date
  for(let i = 0; i < tablarray.length; i++){
    shortestindex[1] = tablarray[i][0] + 1000000;
    for(let j = i; j < tablarray.length; j++){
      if(shortestindex[1] > tablarray[j][0]){
        shortestindex = [j,tablarray[j][0]];
      }
    }
    holdingvar = tablarray[i];
    tablarray[i] = tablarray[shortestindex[0]];
    tablarray[shortestindex[0]] = holdingvar;
  }
  //convert array to table
  b_story += "<table>";

  for(let i = 0; i < tablarray.length; i++){
    b_story += "<tr>";
    b_story += "<th>";
    b_story += dateToDATE(daysToDate(tablarray[i][0]));
    b_story += "</th>";
    b_story += "<th>";
    b_story += tablarray[i][1];
    b_story += "</th>";
    b_story += "</tr>";
  }

  b_story += "</table>";

  player.backstory = tablarray;
  return b_story;
}
function trueNeutral(inputalignment){
  //True Neutral
  if(inputalignment[0] == "Neutral" && inputalignment[1] == "Neutral"){
    inputalignment[0] = "True";
  }
  return inputalignment;
}
function chooseSillyAlignment(){
  var randomnum = Math.random();
  localsillyalignment = ["", ""];
  //Lawfulness
  if(randomnum < 1/6){
    localsillyalignment[0] = "Lawful";
  }
  else if(randomnum < 2/6){
    localsillyalignment[0] = "Chad";
  }  
  else if(randomnum < 3/6){
    localsillyalignment[0] = "Neutral";
  }  
  else if(randomnum < 4/6){
    localsillyalignment[0] = "Smart";
  }  
  else if(randomnum < 5/6){
    localsillyalignment[0] = "Chaotic";
  }  
  else{
    localsillyalignment[0] = "Sad";
  }
  //Goodness
  randomnum = Math.random();
  if(randomnum < 1/5){
    localsillyalignment[1] = "Stupid";
  }
  else if(randomnum < 2/5){
    localsillyalignment[1] = "Good";
  }
  else if(randomnum < 3/5){
    localsillyalignment[1] = "Neutral";
  }
  else if(randomnum < 4/5){
    localsillyalignment[1] = "Horny";
  }
  else{
    localsillyalignment[1] = "Evil";
  }
  return localsillyalignment
}
function chooseAlignment(){
  var randomnum = Math.random();
  localalignment = ["", ""];
  //Lawfulness
  if(randomnum < 1/3){
    localalignment[0] = "Lawful";
  }
  else if(randomnum < 2/3){
    localalignment[0] = "Neutral";
  }  
  else{
    localalignment[0] = "Chaotic";
  }
  //Goodness
  randomnum = Math.random();
  if(randomnum < 0.48){
    localalignment[1] = "Good";
  }
  else if(randomnum < 0.96){
    localalignment[1] = "Neutral";
  }
  else{
    localalignment[1] = "Evil";
  }
  return localalignment
}
function chooseGender(){
  var randomnum = Math.random();
  if(randomnum < 0.49){
    return "F";
  }
  else if(randomnum < 0.98){
    return "M";
  }
  else{
    return "NB";
  }
}
function choosename(race, gender, alignment){
  var randomnum = Math.random();
  var alignmenttag = "";

  if(race == "Drider"){
    race = "Elf";
  }
  if(race.slice(0,8) == "Half-Elf"){
    if(Math.random() < 0.5){
      race = humanlist[randomindex(humanlist.length)][0];
    }
    else{
      race = "Elf";
    }
  }
  else if(race == "Half-Orc"){
    if(Math.random() < 0.5){
      race = humanlist[randomindex(humanlist.length)][0];
    }
    else{
      race = "Orc";
    }
  }
  if(race == "Human (Tethyrian)"){
    race = "Human (Chondathan)";
  }
  else if(race.slice(0,3) == "Elf"){
    race = "Elf";
  }
  else if(race.slice(0,5) == "Dwarf"){
    race = "Dwarf";
  }
  else if(race.slice(0,8) == "Halfling"){
    race = "Halfling";
  }
  else if(race.slice(0,5) == "Gnome"){
    race = "Gnome";
  }
  else if(race.slice(0,10) == "Dragonborn"){
    race = "Dragonborn";
  }
  else if(race.slice(0,7) == "Aasimar"){
    race = "Aasimar";
  }
  else if(race == "Satyr" || race == "Fairy"){
    race = "Fey";
  }
  else if(race.slice(0,8) == "Tiefling"){
    if(Math.random() < 0.5){
      race = "Tiefling";
    }
    else{
      if(Math.random() < 0.5){
        race = "Tiefling";
        alignmenttag = " (" + alignment[0] + ")";
      }
      else{
        race = "Tiefling";
        alignmenttag = " (" + alignment[1] + ")";
      }
    }
  }

  var output = ["<abbr title=\"" + race + alignmenttag + "\">","<abbr title=\"" + race + "\">","<abbr title=\"" + race + "\">"];
  race += alignmenttag;

  if(gender == "NB"){
    if(Math.random() < 0.5){
      gender = "M";
    }
    else{
      gender = "F";
    }
  }

  if(race.slice(0,5) == "Human"){
    if(race.slice(7,16) == "Calishite"){
      if(gender == "M"){
        output[0] += humanCalishiteMaleNames[randomindex(humanCalishiteMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanCalishiteFemaleNames[randomindex(humanCalishiteFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanCalishiteLastNames[randomindex(humanCalishiteLastNames.length)];
    }
    else if(race.slice(7,17) == "Chondathan"){
      if(gender == "M"){
        output[0] += humanChondathanMaleNames[randomindex(humanChondathanMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanChondathanFemaleNames[randomindex(humanChondathanFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanChondathanLastNames[randomindex(humanChondathanLastNames.length)];
    }
    else if(race.slice(7,14) == "Damaran"){
      if(gender == "M"){
        output[0] += humanDamaranMaleNames[randomindex(humanDamaranMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanDamaranFemaleNames[randomindex(humanDamaranFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanDamaranLastNames[randomindex(humanDamaranLastNames.length)];
    }
    else if(race.slice(7,15) == "Illuskan"){
      if(gender == "M"){
        output[0] += humanIlluskanMaleNames[randomindex(humanIlluskanMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanIlluskanFemaleNames[randomindex(humanIlluskanFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanIlluskanLastNames[randomindex(humanIlluskanLastNames.length)];
    }
    else if(race.slice(7,12) == "Mulan"){
      if(gender == "M"){
        output[0] += humanMulanMaleNames[randomindex(humanMulanMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanMulanFemaleNames[randomindex(humanMulanFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanMulanLastNames[randomindex(humanMulanLastNames.length)];
    }
    else if(race.slice(7,14) == "Rashemi"){
      if(gender == "M"){
        output[0] += humanRashemiMaleNames[randomindex(humanRashemiMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanRashemiFemaleNames[randomindex(humanRashemiFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanRashemiLastNames[randomindex(humanRashemiLastNames.length)];
    }
    else if(race.slice(7,11) == "Shou"){
      if(gender == "M"){
        output[0] += humanShouMaleNames[randomindex(humanShouMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanShouFemaleNames[randomindex(humanShouFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanShouLastNames[randomindex(humanShouLastNames.length)];
    }
    else if(race.slice(7,13) == "Turami"){
      if(gender == "M"){
        output[0] += humanTuramiMaleNames[randomindex(humanTuramiMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += humanTuramiFemaleNames[randomindex(humanTuramiFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += humanTuramiLastNames[randomindex(humanTuramiLastNames.length)];
    }
  }
  else if(race.slice(0,5) == "Dwarf"){
    if(gender == "M"){
      output[0] += dwarfMaleNames[randomindex(dwarfMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += dwarfFemaleNames[randomindex(dwarfFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += dwarfLastNames[randomindex(dwarfLastNames.length)];
  }
  else if(race.slice(0,3) == "Elf"){
    if(gender == "M"){
      output[0] += elfMaleNames[randomindex(elfMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += elfFemaleNames[randomindex(elfFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += elfLastNames[randomindex(elfLastNames.length)];
  }
  else if(race.slice(0,8) == "Halfling"){
    if(gender == "M"){
      output[0] += halflingMaleNames[randomindex(halflingMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += halflingFemaleNames[randomindex(halflingFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += halflingLastNames[randomindex(halflingLastNames.length)];
  }
  else if(race.slice(0,10) == "Dragonborn"){
    if(gender == "M"){
      output[0] += dragonbornMaleNames[randomindex(dragonbornMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += dragonbornFemaleNames[randomindex(dragonbornFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += dragonbornLastNames[randomindex(dragonbornLastNames.length)];
  }
  else if(race.slice(0,5) == "Gnome"){
    if(gender == "M"){
      output[0] += gnomeMaleNames[randomindex(gnomeMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += gnomeFemaleNames[randomindex(gnomeFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
      output[1] += "LASTNAMER SCREWED UP";
    }

    output[1] += gnomeLastNames[randomindex(gnomeLastNames.length)];

    var nicknamenum = randomindex(6);
    for(let i = 0; i < nicknamenum; i++){
      output[2] += gnomeNicknames[randomindex(gnomeNicknames.length)] + " ";
    }
  }
  else if(race.slice(0,6) == "Kobold"){
    if(gender == "M"){
      output[0] += koboldMaleNames[randomindex(koboldMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += koboldFemaleNames[randomindex(koboldFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += "";
  }
  else if(race.slice(0,3) == "Orc"){
    if(gender == "M"){
      output[0] += orcMaleNames[randomindex(orcMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += orcFemaleNames[randomindex(orcFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
  }
  else if(race.slice(0,8) == "Tiefling"){
    if(is_containedin_("Lawful",race)){
      output[0] += tieflingLawfulNames[randomindex(tieflingLawfulNames.length)];
    }
    else if(is_containedin_("Chad",race)){
      output[0] += tieflingChadNames[randomindex(tieflingChadNames.length)];
    }
    else if(is_containedin_("Smart",race)){
      output[0] += tieflingSmartNames[randomindex(tieflingSmartNames.length)];
    }
    else if(is_containedin_("Chaotic",race)){
      output[0] += tieflingChaoticNames[randomindex(tieflingChaoticNames.length)];
    }
    else if(is_containedin_("Sad",race)){
      output[0] += tieflingSadNames[randomindex(tieflingSadNames.length)];
    }
    else if(is_containedin_("Stupid",race)){
      output[0] += tieflingStupidNames[randomindex(tieflingStupidNames.length)];
    }
    else if(is_containedin_("Good",race)){
      output[0] += tieflingGoodNames[randomindex(tieflingGoodNames.length)];
    }
    else if(is_containedin_("Horny",race)){
      output[0] += tieflingHornyNames[randomindex(tieflingHornyNames.length)];
    }
    else if(is_containedin_("Evil",race)){
      output[0] += tieflingEvilNames[randomindex(tieflingEvilNames.length)];
    }
    else if(is_containedin_("Neutral",race)){
      output[0] += tieflingNeutralNames[randomindex(tieflingNeutralNames.length)];
    }
    else{
      if(gender == "M"){
        output[0] += tieflingMaleNames[randomindex(orcMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += tieflingFemaleNames[randomindex(orcFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
    }
    output[1] += tieflingLastNames[randomindex(tieflingLastNames.length)];
  }
  else if(race == "Fire Genasi"){
    if(gender == "M"){
      output[0] += fireGenasiMaleNames[randomindex(fireGenasiMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += fireGenasiFemaleNames[randomindex(fireGenasiFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += fireGenasiLastNames[randomindex(fireGenasiLastNames.length)];
  }
  else if(race.slice(0,7) == "Firbolg"){
    if(gender == "M"){
      output[0] += firbolgMaleNames[randomindex(firbolgMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += firbolgFemaleNames[randomindex(firbolgFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += firbolgLastNames[randomindex(firbolgLastNames.length)];
  }
  else if(race == "Air Genasi"){
    if(gender == "M"){
      output[0] += airGenasiMaleNames[randomindex(airGenasiMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += airGenasiFemaleNames[randomindex(airGenasiFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += airGenasiLastNames[randomindex(airGenasiLastNames.length)];
  }
  else if(race == "Water Genasi"){
    if(gender == "M"){
      output[0] += waterGenasiMaleNames[randomindex(waterGenasiMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += waterGenasiFemaleNames[randomindex(waterGenasiFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += waterGenasiLastNames[randomindex(waterGenasiLastNames.length)];
  }
  else if(race == "Earth Genasi"){
    if(gender == "M"){
      output[0] += earthGenasiMaleNames[randomindex(earthGenasiMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += earthGenasiFemaleNames[randomindex(earthGenasiFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += earthGenasiLastNames[randomindex(earthGenasiLastNames.length)];
  }
  else if(race.slice(0,6) == "Tabaxi"){
    if(ischild){
      output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " Kit";
    }
    else{
      ischild = Math.random();
      if(ischild < 0.5){
        output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " Paw";
      }
      else if(ischild < 0.99){
        output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " " + tabaxiNames[randomindex(tabaxiNames.length)];
      }
      else{
        output[0] += tabaxiNames[randomindex(tabaxiNames.length)] + " Star";
      }
    }
  }
  else if(race.slice(0,6) == "Tortle"){
    if(gender == "M"){
      output[0] += tortleMaleNames[randomindex(tortleMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += tortleFemaleNames[randomindex(tortleFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += tortleLastNames[randomindex(tortleLastNames.length)];
  }
  else if(race == "Fey"){
    output[0] += feyNames[randomindex(feyNames.length)];
  }
  else if(race.slice(0,5) == "Owlin"){
    if(gender == "M"){
      output[0] += owlinMaleNames[randomindex(owlinMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += owlinFemaleNames[randomindex(owlinFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += owlinLastNames[randomindex(owlinLastNames.length)];
  }
  else if(race.slice(0,7) == "Bugbear"){
    if(gender == "M"){
      output[0] += bugbearMaleNames[randomindex(bugbearMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += bugbearFemaleNames[randomindex(bugbearFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
  }
  else if(race == "Centaur"){
    if(gender == "M"){
      output[0] += centaurMaleNames[randomindex(centaurMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += centaurFemaleNames[randomindex(centaurFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += centaurLastNames[randomindex(centaurLastNames.length)];
  }
  else if(race.slice(0,4) == "Gith"){
    if(race.slice(4,9) == "yanki"){
      if(gender == "M"){
        output[0] += githyankiMaleNames[randomindex(githyankiMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += githyankiFemaleNames[randomindex(githyankiFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += githyankiLastNames[randomindex(githyankiLastNames.length)];
    }
    else if(race.slice(4,9) == "zerai"){
      if(gender == "M"){
        output[0] += githzeraiMaleNames[randomindex(githzeraiMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += githzeraiFemaleNames[randomindex(githzeraiFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += githzeraiLastNames[randomindex(githzeraiLastNames.length)];
    }
    else{
      output[0] +="UNKNOWN_GITH";
      output[1] +="UNKNOWN_GITH";
    }
  }
  else if(is_containedin_("oblin",race)){
    if(gender == "M"){
      output[0] += goblinMaleNames[randomindex(orcMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += goblinFemaleNames[randomindex(orcFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
  }
  else if(race == "Goliath"){
    if(gender == "M"){
      output[0] += goliathMaleNames[randomindex(goliathMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += goliathFemaleNames[randomindex(goliathFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += goliathLastNames[randomindex(goliathLastNames.length)];
  }
  else if(race == "Lizardfolk"){
    if(gender == "M"){
      output[0] += lizardfolkMaleNames[randomindex(lizardfolkMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += lizardfolkFemaleNames[randomindex(lizardfolkFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
  }
  else if(race == "Triton"){
    output[0] += tritonFirstNames[randomindex(tritonFirstNames.length)];
    output[1] += tritonLastNames[randomindex(tritonLastNames.length)];
  }
  else if(race == "Warforged"){
    if(Math.random() < 0.5){
      output[0] += warforgedNames[randomindex(warforgedNames.length)];
    }
    else{
      var acroindex = randomindex(warforgedAcron.length);
      output[0] += warforgedAcron[acroindex];
      output[1] += warforgedExpan[acroindex];
      if(is_containedin_("Elimin", output[1])){
        if(Math.random() < 0.5){
          output[1] += lmalefirstnames[randomindex(lmalefirstnames.length)] + " " + flastnames[randomindex(flastnames.length)];
        }
        else{
          output[1] += lfemalefirstnames[randomindex(lfemalefirstnames.length)] + " " + flastnames[randomindex(flastnames.length)];
        }
        output[1] += ")";
      }
    }
  }
  else if(race == "Dohwar"){
    if(gender == "M"){
      output[0] += dohwarMaleNames[randomindex(dohwarMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += dohwarFemaleNames[randomindex(dohwarFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += dohwarLastNames[randomindex(dohwarLastNames.length)];
  }
  else if(race == "Vedalken"){
    if(gender == "M"){
      output[0] += vedalkenMaleNames[randomindex(vedalkenMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += vedalkenFemaleNames[randomindex(vedalkenFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += vedalkenLastNames[randomindex(vedalkenLastNames.length)];
  }
  else if(race == "Leonin"){
    if(gender == "M"){
      output[0] += leoninMaleNames[randomindex(leoninMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += leoninFemaleNames[randomindex(leoninFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += leoninLastNames[randomindex(leoninLastNames.length)];
  }
  else if(race == "Aarakocra"){
    if(gender == "M"){
      output[0] += aarakocraMaleNames[randomindex(aarakocraMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += aarakocraFemaleNames[randomindex(aarakocraFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += aarakocraLastNames[randomindex(aarakocraLastNames.length)];
  }
  else if(race == "Harengon"){
    if(gender == "M"){
      output[0] += harengonMaleNames[randomindex(harengonMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += harengonFemaleNames[randomindex(harengonFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += harengonLastNames[randomindex(harengonLastNames.length)];
  }
  else if(is_containedin_("Neufolk",race)){
    if(is_containedin_("Verdi",race) || is_containedin_("Zurri",race)){
      if(gender == "M"){
        output[0] += neufolkZurriMaleNames[randomindex(neufolkZurriMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += neufolkZurriFemaleNames[randomindex(neufolkZurriFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += neufolkZurriLastNames[randomindex(neufolkZurriLastNames.length)];
    }
    else if(is_containedin_("Grigii",race)){
      if(gender == "M"){
        output[0] += neufolkGrigiiMaleNames[randomindex(neufolkGrigiiMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += neufolkGrigiiFemaleNames[randomindex(neufolkGrigiiFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += neufolkGrigiiLastNames[randomindex(neufolkGrigiiLastNames.length)];
    }
    else if(is_containedin_("Rossi",race)){
      if(gender == "M"){
        output[0] += neufolkRossiMaleNames[randomindex(neufolkRossiMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += neufolkRossiFemaleNames[randomindex(neufolkRossiFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += neufolkRossiLastNames[randomindex(neufolkRossiLastNames.length)];
    }
    else if(is_containedin_("Violi",race)){
      if(gender == "M"){
        output[0] += neufolkVioliMaleNames[randomindex(neufolkVioliMaleNames.length)];
      }
      else if(gender == "F"){
        output[0] += neufolkVioliFemaleNames[randomindex(neufolkVioliFemaleNames.length)];
      }
      else{
        output[0] += "GENDER SCREWED UP";
      }
      output[1] += neufolkVioliLastNames[randomindex(neufolkVioliLastNames.length)];
    }
    else{
      output[0] += "UNKOWN NEUFOLK";
      output[1] += "UNKOWN NEUFOLK";
    }
  }
  else if(race == "Milifian"){
    if(gender == "M"){
      output[0] += milifianMaleNames[randomindex(milifianMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += milifianFemaleNames[randomindex(milifianFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += milifianLastNames[randomindex(milifianLastNames.length)];
  }
  else if(race == "Hadozee"){
    if(gender == "M"){
      output[0] += hadozeeMaleNames[randomindex(hadozeeMaleNames.length)];
      output[2] += hadozeeMaleNames[randomindex(hadozeeMaleNames.length)] + " ";
    }
    else if(gender == "F"){
      output[0] += hadozeeFemaleNames[randomindex(hadozeeFemaleNames.length)];
      output[2] += hadozeeFemaleNames[randomindex(hadozeeFemaleNames.length)] + " ";
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += hadozeeLastNames[randomindex(hadozeeLastNames.length)];
  }
  else if(race == "Thri-kreen"){
    output[0] += thrikreenUpperFirstNames[randomindex(thrikreenUpperFirstNames.length)];
    for(let i = 0; i< randomindex(3)+2; i++){
      output[0] += thrikreenLowerFirstNames[randomindex(thrikreenLowerFirstNames.length)];
    }
    output[1] += thrikreenLastNames[randomindex(thrikreenLastNames.length)];
  }
  else if(race == "Kenku"){
    output[0] += kenkuNames[randomindex(kenkuNames.length)];
  }
  else if(race == "Loxodon"){
    if(gender == "M"){
      output[0] += loxodonMaleNames[randomindex(loxodonMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += loxodonFemaleNames[randomindex(loxodonFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += loxodonLastNames[randomindex(loxodonLastNames.length)];
  }
  else if(race == "Verdan"){
    output[0] += verdanNames[randomindex(verdanNames.length)];
  }
  else if(race == "Plasmoid"){
    output[0] += plasmoidNames[randomindex(plasmoidNames.length)];
  }
  else if(race == "Grung"){
    if(gender == "M"){
      output[0] += grungMaleNames[randomindex(grungMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += grungFemaleNames[randomindex(grungFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += grungLastNames[randomindex(grungLastNames.length)];
  }
  else if(race == "Locathah"){
    if(gender == "M"){
      output[0] += locathahMaleNames[randomindex(locathahMaleNames.length)];
    }
    else if(gender == "F"){
      output[0] += locathahFemaleNames[randomindex(locathahFemaleNames.length)];
    }
    else{
      output[0] += "GENDER SCREWED UP";
    }
    output[1] += locathahLastNames[randomindex(locathahLastNames.length)];
  }
  else if(race == "Autognome"){
    output[0] += autognomeNames[randomindex(autognomeNames.length)];
  }
  //choosenamebottom
  else{
    output[0] += "<font color='red'>FIRST_NAME</font>";
    output[1] += "<font color='red'>LAST_NAME</font>";  
  }

  output[0] += "</abbr>";
  output[1] += "</abbr>";
  output[2] += "</abbr>";
  return output;
}
function chooseClass(topstat, secstat){
  var randomnum = Math.random();
  //Highest stat STR
  if(topstat == 0){
    //STR --> DEX
    if(secstat == 1){
      return "Fighter";
    }
    //STR --> CON
    else if(secstat == 2){
      if(randomnum < 0.5){
        return "Fighter";
      }
      else{
        return "Barbarian";
      }
    }
    //STR --> INT
    else if(secstat == 3){
      if(randomnum < 0.98){
        return "Fighter";
      }
      else{
        return "Wizard";
      }
    }
    //STR --> WIS
    else if(secstat == 4){
      if(randomnum < 0.75){
        return "Ranger";
      }
      else{
        return "Fighter";
      }
    }
    //STR --> CHA
    else if(secstat == 5){
      if(randomnum < 0.8){
        return "Paladin";
      }
      else{
        return "Fighter";
      }
    }
    else{
      alert("ERROR: Something went wrong with secstat. topstat = 0");
    }
  }
  //Highest stat DEX
  else if(topstat == 1){
    //DEX --> STR
    if(secstat == 0){
      if(randomnum < 0.75){
        return "Fighter";
      }
      else{
        return "Rogue";
      }
    }
    //DEX --> CON
    else if(secstat == 2){
      return "Rogue";
    }
    //DEX --> INT
    else if(secstat == 3){
      return "Rogue";
    }
    //DEX --> WIS
    else if(secstat == 4){
      if(randomnum < 0.3){
        return "Monk";
      }
      else if(randomnum < 0.6){
        return "Ranger";
      }
      else if(randomnum < 0.9){
        return "Druid";
      }
      else{
        return "Rogue";
      }
    }
    //DEX --> CHA
    else if(secstat == 5){
      if(randomnum < 0.3){
        return "Rogue";
      }
      else if(randomnum < 0.6){
        return "Sorcerer";
      }
      else if(randomnum < 0.9){
        return "Warlock";
      }
      else{
        return "Bard";
      }
    }
    else{
      alert("ERROR: Something went wrong with secstat. topstat = 1");
    }
  }
  //Highest stat CON
  else if(topstat == 2){
    //CON --> STR
    if(secstat == 0){
      return "Barbarian";
    }
    //CON --> DEX
    else if(secstat == 1){
      return "Rogue";
    }
    //CON --> INT
    else if(secstat == 3){
      return "Wizard";
    }
    //CON --> WIS
    else if(secstat == 4){
      return "Cleric";
    }
    //CON --> CHA
    else if(secstat == 5){
      return "Sorcerer";
    }
    else{
      alert("ERROR: Something went wrong with secstat. topstat = 2");
    }
  }
  //Highest stat INT
  else if(topstat == 3){
    //INT --> STR
    if(secstat == 0){
      return "Artificer";
    }
    //INT --> DEX
    else if(secstat == 1){
      if(randomnum < 0.5){
        return "Wizard";
      }
      else{
        return "Artificer";
      }
    }
    //INT --> CON
    else if(secstat == 2){
      if(randomnum < 0.66){
        return "Wizard";
      }
      else{
        return "Artificer";
      }
    }
    //INT --> WIS
    else if(secstat == 4){
      return "Wizard";
    }
    //INT --> CHA
    else if(secstat == 5){
      return "Wizard";
    }
    else{
      alert("ERROR: Something went wrong with secstat. topstat = 3");
    }
  }
  //Highest stat WIS
  else if(topstat == 4){
    //WIS --> STR
    if(secstat == 0){
      if(randomnum < 0.75){
        return "Ranger";
      }
      else{
        return "Cleric";
      }
    }
    //WIS --> DEX
    else if(secstat == 1){
      if(randomnum < 0.75){
        return "Monk";
      }
      else{
        return "Ranger";
      }
    }
    //WIS --> CON
    else if(secstat == 2){
      if(randomnum < 0.45){
        return "Cleric";
      }
      else if(randomnum < 0.9){
        return "Druid";
      }
      else{
        return "Ranger";
      }
    }
    //WIS --> INT
    else if(secstat == 3){
      if(randomnum < 0.8){
        return "Cleric";
      }
      else{
        return "Druid";
      }
    }
    //WIS --> CHA
    else if(secstat == 5){
      return "Cleric";
    }
    else{
      alert("ERROR: Something went wrong with secstat, topstat = 4");
    }
  }
  //Highest stat CHA
  else if(topstat == 5){
    //CHA --> STR
    if(secstat == 0){
      if(randomnum < 0.4){
        return "Paladin";
      }
      else if(randomnum < 0.8){
        return "Bard";
      }
      else{
        return "Warlock";
      }
    }
    //CHA --> DEX
    else if(secstat == 1){
      if(randomnum < 0.5){
        return "Bard";
      }
      else{
        return "Sorcerer";
      }
    }
    //CHA --> CON
    else if(secstat == 2){
      if(randomnum < 0.33){
        return "Warlock";
      }
      else if(randomnum < 0.66){
        return "Bard";
      }
      else{
        return "Sorcerer";
      }
    }
    //CHA --> INT
    else if(secstat == 3){
      if(randomnum < 0.45){
        return "Warlock";
      }
      else if(randomnum < 0.9){
        return "Sorcerer";
      }
      else{
        return "Bard";
      }
    }
    //CHA --> WIS
    else if(secstat == 4){
      return "Warlock";
    }
    else{
      alert("ERROR: Something went wrong with secstat. topstat = 5");
    }
  }
  else{
    return "ERROR: Something went wrong with topstat";
  }
}
function rollCharacter(total){
  var statvar = [0,0,0,0,0,0];
  statvar[0] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[1] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[2] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[3] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[4] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  statvar[5] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  var statstorage = [0,0,0,0,0,0];
  while(statvar[0]+statvar[1]+statvar[2]+statvar[3]+statvar[4]+statvar[5] != total){
    statvar[0] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[1] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[2] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[3] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[4] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
    statvar[5] = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 3;
  }  
  return statvar;
}
function rankStats(stat0, stat1, stat2, stat3, stat4, stat5){
  var statstorage = [stat0, stat1, stat2, stat3, stat4, stat5];
  var outputarray = [0,0,0,0,0,0];
  var maxstat = 0;
  //rank stats
  for(let i = 0; i < 6; i++){
    maxstat = Math.max(statstorage[0], statstorage[1], statstorage[2], statstorage[3], statstorage[4], statstorage[5]);
    for(let j = 0; j < 6; j++){
      if(statstorage[j] == maxstat){
        outputarray[i] = j;
        statstorage[j] = 0;
        break;
      }
    }
  }
  return outputarray;
}
function statRank(statindex, storder){
  var index = 0;
  for(let i = 0; i < 6; i++){
    if(statindex == storder[i]){
      index = i;
      break;
    }
  }
  return index;
}
function writeToScreen(){
  //Output to screen
  outputstring = "<div class=\"floatbox\">"
  outputstring = outputstring + "<table>" +
  "<tr>" + "<th>" + "Strength" + "</th>" + "<th>" + player.stats[0] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Dexterity" + "</th>" + "<th>" + player.stats[1] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Constitution" + "</th>" + "<th>" + player.stats[2] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Intelligence" + "</th>" + "<th>" + player.stats[3] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Wisdom" + "</th>" + "<th>" + player.stats[4] + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Charisma" + "</th>" + "<th>" + player.stats[5] + "</th>" + "</tr>" + 
  "</table>";
  outputstring = outputstring + "</div>";
  outputstring = outputstring + "<hr>";
  outputstring = outputstring + "<div class=\"floatbox\">"
  outputstring = outputstring + "<table>" + 
  "<tr>" + "<th>" + "Info." + "</th>" + "<th>" + "Player" + "</th>" + "<th>" + "Parent #1" + "</th>" + "<th>" + "Parent #2" + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Name" + "</th>" + "<th>" + player.fullname[0] + " " + player.fullname[2] + player.fullname[1] + "</th>" + "<th>" + player.parent1.fullname[0] + " " + player.parent1.fullname[2] + player.parent1.fullname[1] + player.parent1.dead + "</th>" + "<th>" + player.parent2.fullname[0] + " " + player.parent2.fullname[2] + player.parent2.fullname[1] + player.parent2.dead + "</th>" + "</tr>" + 
  "<tr>" + "<th>" + "Race" + "</th>" + "<th>" + player.race[0] + player.race2[0] + "</th>" + "<th>" + player.parent1.race[0] + "</th>" + "<th>" + player.parent2.race[0] + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Gender" + "</th>" + "<th>" + player.gender + "</th>" + "<th>" + player.parent1.gender + "</th>" + "<th>" + player.parent2.gender + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Class/Profession" + "</th>" + "<th>" + player.clas + "</th>" + "<th>" + player.parent1.profession + "</th>" + "<th>" + player.parent2.profession + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Alignment" + "</th>" + "<th>" + player.alignment[0] + " " + player.alignment[1] + "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Hometown" + "</th>" + "<th>" + player.hometown[1]+ "</th>" + "</tr>" + 
    "<tr>" + "<th>" + "Birthdate" + "</th>" + "<th>" + dateToDATE(daysToDate(player.birthday)) + "</th>" + "<th>" + dateToDATE(daysToDate(player.parent1.birthday)) + "</th>" + "<th>" + dateToDATE(daysToDate(player.parent2.birthday)) + "</th>" + "</tr>" + 
    "</table>";
    //outputstring = "STR = " + player.stats[0] + "<br>DEX = " + player.stats[1] + "<br>CON = " + player.stats[2] + "<br>INT = " + player.stats[3] + "<br>WIS = " + player.stats[4] + "<br>CHA = " + player.stats[5] + "<br><br>Name: " + player.fullname[0] + " " + player.fullname[1] + "<br><br>Gender: " + player.gender + "<br>Race: " + player.race[0] + "<br>Class: " + player.clas + "<br>Alignment: " + player.alignment[0] + " " + player.alignment[1];
    outputstring = outputstring + "</div>";
    outputstring = outputstring + "<div class=\"bottombox\">";
    outputstring = outputstring + "<hr>";
    outputstring = outputstring + backstory();
    outputstring = outputstring + "</div>";
    document.getElementById("characteroutput").innerHTML = outputstring;
}

Date: 2025-03-05 Wed 11:58

Author: Mack

Created: 2025-06-23 Mon 19:10