diff --git a/devTools/types/FC/arcology.d.ts b/devTools/types/FC/arcology.d.ts
index 0aa28cf91c15cb07474cc165f58d3f4b8a180308..1ce42f9e1bcb2f12221724e0d757f8c403097b99 100644
--- a/devTools/types/FC/arcology.d.ts
+++ b/devTools/types/FC/arcology.d.ts
@@ -171,11 +171,11 @@ declare namespace FC {
 	type FSName<T extends string> = T extends `FS${infer Name}` ? Name : never;
 
 	// direction with respect to the player's arcology
-	type ArcologyDirection = "east" | "north" | "northeast" | "northwest" | "south" | "southeast" | "southwest" | "west";
+	type ArcologyDirection = 0 /* player */ | "east" | "north" | "northeast" | "northwest" | "south" | "southeast" | "southwest" | "west";
 
 	type ArcologyStateBase = {
 		name: string;
-		direction: Zeroable<ArcologyDirection>;
+		direction: ArcologyDirection;
 		government: string;
 		leaderID: number;
 		honeymoon: number;
@@ -185,19 +185,15 @@ declare namespace FC {
 		PCminority: number;
 		demandFactor: number;
 		embargo: number;
-		embargoTarget: Zeroable<ArcologyDirection>;
-		influenceTarget: Zeroable<ArcologyDirection>;
+		embargoTarget: -1|ArcologyDirection;
+		influenceTarget: -1|ArcologyDirection;
 		influenceBonus: number;
 		CyberEconomic: number;
-		CyberEconomicTarget: Zeroable<ArcologyDirection>;
+		CyberEconomicTarget: -1|ArcologyDirection;
 		CyberReputation: number;
-		CyberReputationTarget: Zeroable<ArcologyDirection>;
+		CyberReputationTarget: -1|ArcologyDirection;
 		rival: number;
 		childhoodFertilityInducedNCSResearch: Bool;
-		hackingEconomic: number;
-		hackingEconomicTarget: number;
-		hackingReputationTarget: number;
-		hackingReputation: number;
 		weeks: number;
 	}
 
diff --git a/js/003-data/slaveGeneData.js b/js/003-data/slaveGeneData.js
index e642acf3c0b6119d8806521846e769c9d21bbc92..5107f065446b0ee68cd33d441c9f1bec2dbad085 100644
--- a/js/003-data/slaveGeneData.js
+++ b/js/003-data/slaveGeneData.js
@@ -7,7 +7,7 @@
  * @property {boolean} [requirements]
  * @property {boolean} [pubertyActivated]
  */
-/** @type {Map.<FC.GeneticQuirks|string, geneData>} */
+/** @type {Map.<keyof FC.GeneticQuirks, geneData>} */
 App.Data.geneticQuirks = new Map([
 	["albinism",
 		{
diff --git a/js/medicine/surgery/genitials/insemination.js b/js/medicine/surgery/genitials/insemination.js
index 9505c907a3504d3690c6e730864afc640a004d8e..eb6c02c0ed08ca39bea5f9e388857a7166fb5b22 100644
--- a/js/medicine/surgery/genitials/insemination.js
+++ b/js/medicine/surgery/genitials/insemination.js
@@ -1,6 +1,6 @@
 App.Medicine.Surgery.Reactions.Insemination = class extends App.Medicine.Surgery.SimpleReaction {
 	/**
-	 * @param {App.Entity.SlaveState} seedSource
+	 * @param {FC.HumanState} seedSource
 	 */
 	constructor(seedSource) {
 		super();
@@ -73,7 +73,7 @@ App.Medicine.Surgery.Procedures.Insemination = class extends App.Medicine.Surger
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 * @param {string} name
-	 * @param {App.Entity.SlaveState} seedSource
+	 * @param {FC.HumanState} seedSource
 	 */
 	constructor(slave, name, seedSource) {
 		super(slave);
diff --git a/js/utils.js b/js/utils.js
index 4ee72ebf6bced819a356a55e31f26f4e3e07c9f9..d3c93175282d38bc4a5fc511c76b2baee1e69728 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -309,16 +309,17 @@ App.Utils.topologicalSort = function(keys, edges) {
 		nodes[from].afters.push(to);
 	});
 
-	// 2. topological sort
-	Object.keys(nodes).forEach(function visit(idstr, ancestors) {
+	/** 2. topological sort with visitor
+	 * @param {string} idstr
+	 * @param {number[]} [ancestors]
+	 */
+	function visit(idstr, ancestors = []) {
 		let node = nodes[idstr];
 		let id = node.id;
 
 		// if already exists, do nothing
 		if (visited[idstr]) { return; }
 
-		if (!Array.isArray(ancestors)) { ancestors = []; }
-
 		ancestors.push(id);
 
 		visited[idstr] = true;
@@ -332,7 +333,8 @@ App.Utils.topologicalSort = function(keys, edges) {
 		});
 
 		sorted.unshift(id);
-	});
+	}
+	Object.keys(nodes).forEach(node => visit(node));
 
 	return sorted;
 };
diff --git a/src/Mods/SecExp/js/securityReport.js b/src/Mods/SecExp/js/securityReport.js
index 65c0319580c68fcd0057e173e03d65b35e674a72..4e4965936c5151e18916bebc87bc04d6129e1514 100644
--- a/src/Mods/SecExp/js/securityReport.js
+++ b/src/Mods/SecExp/js/securityReport.js
@@ -1,13 +1,16 @@
-/** @returns {DocumentFragment} */
-App.Mods.SecExp.securityReport = function() {
+/**
+ * @param {number} oldACitizens
+ * @returns {DocumentFragment}
+ */
+App.Mods.SecExp.securityReport = function(oldACitizens) {
 	let immigration = 0;
 	let emigration = 0;
 	let secGrowth = 0;
 	let crimeGrowth = 0;
-	if (V.ACitizens > V.oldACitizens) {
-		immigration = V.ACitizens - V.oldACitizens;
+	if (V.ACitizens > oldACitizens) {
+		immigration = V.ACitizens - oldACitizens;
 	} else {
-		emigration = V.oldACitizens - V.ACitizens; // takes into account citizens leaving and those getting enslaved
+		emigration = oldACitizens - V.ACitizens; // takes into account citizens leaving and those getting enslaved
 	}
 	const activeUnits = App.Mods.SecExp.battle.activeUnits();
 	/** @type {(string|HTMLElement|DocumentFragment)[]} */
diff --git a/src/cheats/cheatEditArcology.js b/src/cheats/cheatEditArcology.js
index 315d736c73f755969d0a61156cfec82733941ac6..e902ea26605b6fade7eb9b7acfc0ba8b06204442 100644
--- a/src/cheats/cheatEditArcology.js
+++ b/src/cheats/cheatEditArcology.js
@@ -100,20 +100,6 @@ App.UI.Cheat.arcology = function(num) {
 				.addValue("Yes", 1).on()
 				.addValue("No", 0).off();
 		}
-		if (arc.hasOwnProperty("hackingEconomic")) { // Sadly, hacking seems to be sometimes undefined, and .addOption will break atm if it is.
-			options.addOption("Hacking economic", "hackingEconomic", arc).showTextBox();
-		}
-		if (arc.hasOwnProperty("hackingEconomicTarget")) {
-			option = options.addOption("Hacking economic target", "hackingEconomicTarget", arc)
-				.addValue("none", -1).off()
-				.addValueList(compass).pulldown();
-			if (num !== 0) {
-				option.addValue("player", 0);
-			}
-		}
-		if (arc.hasOwnProperty("hackingReputation")) {
-			options.addOption("Hacking reputation", "hackingReputation", arc).showTextBox();
-		}
 		if (arc.hasOwnProperty("childhoodFertilityInducedNCSResearch")) {
 			options.addOption("Childhood fertility induced NCS research", "childhoodFertilityInducedNCSResearch", arc).showTextBox();
 		}
diff --git a/src/cheats/neighborArcologyCheatDatatypeCleanup.js b/src/cheats/neighborArcologyCheatDatatypeCleanup.js
index d03b0a7b7a2fcc9c3cb983f2136e72cf10571520..1c21116668e0ccb7dfc350cdfe4b44cb014ba93d 100644
--- a/src/cheats/neighborArcologyCheatDatatypeCleanup.js
+++ b/src/cheats/neighborArcologyCheatDatatypeCleanup.js
@@ -1,10 +1,7 @@
 App.UI.Cheat.neighborArcologyCheatDatatypeCleanup = function() {
 	const node = new DocumentFragment();
 
-	const clean = App.Update.arcologiesDatatypeCleanup();
-	if (clean) {
-		App.UI.DOM.appendNewElement("p", node, clean);
-	}
+	App.Update.arcologiesDatatypeCleanup();
 
 	App.UI.DOM.appendNewElement("p", node, "You have CHEATED your way to influencing the neighboring arcologies. They have been unscrupulously directed according to your CHEAT whims.");
 
diff --git a/src/data/backwardsCompatibility/datatypeCleanup.js b/src/data/backwardsCompatibility/datatypeCleanup.js
index 952a1c3984b440b7f8c1cd54ddadd419c13378f7..07adf18d76526666d269373cd7c5999ce8f40768 100644
--- a/src/data/backwardsCompatibility/datatypeCleanup.js
+++ b/src/data/backwardsCompatibility/datatypeCleanup.js
@@ -1200,6 +1200,7 @@ globalThis.PCDatatypeCleanup = (function PCDatatypeCleanup() {
 		if (PC.actualAge > PC.pubertyAgeXY) {
 			PC.pubertyXY = 1;
 		}
+		PC.NCSyouthening = Math.max(+PC.NCSyouthening, 0) || 0;
 	}
 
 	/**
@@ -1363,7 +1364,6 @@ globalThis.PCDatatypeCleanup = (function PCDatatypeCleanup() {
 		PC.fertPeak = Math.clamp(+PC.fertPeak, 0, 4) || 0;
 		PC.pregSource = +PC.pregSource || 0;
 		PC.pregMood = Math.clamp(+PC.pregMood, 0, 2) || 0;
-		PC.fertDrugs = Math.clamp(+PC.fertDrugs, 0, 1) || 0;
 		PC.forcedFertDrugs = Math.max(+PC.forcedFertDrugs, 0) || 0;
 		WombNormalizePreg(PC);
 	}
@@ -1491,7 +1491,6 @@ globalThis.PCDatatypeCleanup = (function PCDatatypeCleanup() {
 			PC.drugs = "no drugs";
 		}
 		PC.aphrodisiacs = Math.clamp(+PC.aphrodisiacs, -1, 2) || 0;
-		PC.staminaPills = Math.clamp(+PC.staminaPills, 0, 1) || 0;
 	}
 
 	/**
diff --git a/src/endWeek/economics/arcmgmt.js b/src/endWeek/economics/arcmgmt.js
index 2c97e12c5860fe9e821496ab20c8f5c4c73d0d93..614cfe607c7cbec917e0238a641e90ce7a3b9a48 100644
--- a/src/endWeek/economics/arcmgmt.js
+++ b/src/endWeek/economics/arcmgmt.js
@@ -38,7 +38,6 @@ App.EndWeek.arcManagement = function() {
 	Populations depend on the 'demand' for them. People flock to the Free City when there are jobs. Jobs for lower class people depend on prosperity and the need for labor from other classes. They compete with slaves for work.
 	More elite citizens require their own slaves and will cause the population of slaves to increase as they move in. FS and policies will impact how many slaves they desire and how productive they are. The PC's menials also compete for labor within the arcology. Slaves can now 'expire', speed depends on FS and policies. Default lifespan for menials is an average of ~4 years. */
 
-	V.oldACitizens = V.ACitizens;
 	let FSScore = 0; /* FS progress for tourism */
 	let	slaveDemandU = 1; /* Changes to upperClass slave demand */
 	let	slaveDemandT = 1; /* Changes to topClass slave demand */
diff --git a/src/endWeek/economics/economics.js b/src/endWeek/economics/economics.js
index 4ca4911742d07b70f4badc17c4dcf892d238fa85..081ea69ecc1e1509c7fff289323b557b9fc69bce 100644
--- a/src/endWeek/economics/economics.js
+++ b/src/endWeek/economics/economics.js
@@ -11,6 +11,7 @@ App.EndWeek.economics = function() {
 		V.mods.food.warned = false;
 	}
 
+	const oldACitizens = V.ACitizens;
 	SectorCounts();
 	App.Arcology.updateOwnership();
 
@@ -53,7 +54,7 @@ App.EndWeek.economics = function() {
 		["securityReport", {
 			name: "Security",
 			get requirements() { return V.secExpEnabled > 0; },
-			get report() { return App.Mods.SecExp.securityReport(); }
+			get report() { return App.Mods.SecExp.securityReport(oldACitizens); }
 		}],
 		["reputation", {
 			name: "Reputation",
diff --git a/src/endWeek/player/prLongTermPhysicalEffects.js b/src/endWeek/player/prLongTermPhysicalEffects.js
index 0fcf7bd32b2b7258b96e35e2904e1102c3abd952..4938c9b4b99ce2e648d0a9822201222c6870c1e8 100644
--- a/src/endWeek/player/prLongTermPhysicalEffects.js
+++ b/src/endWeek/player/prLongTermPhysicalEffects.js
@@ -541,6 +541,7 @@ App.EndWeek.Player.longTermPhysicalEffects = function(PC = V.PC) {
 		**	the slave's accumulated youthening is 6 or higher,
 		**	or by a 50% chance.
 		*/
+		/** @type {FC.NippleShape} */
 		let nipplesString;
 		if ((boobSize >= 5000) && (random(1, 100) < 90) && gigantomastiaMod !== 3) {
 			r.push(`Your <span class="ncs">NCS</span> <span class="change negative">reduces the size of your heaving breasts.</span>`);
diff --git a/src/endWeek/reports/personalAttention.js b/src/endWeek/reports/personalAttention.js
index 2a2d5da1782dcd7fe92f2e9b16b56a0b998b49ee..c425aa74f229d1679561d63df3cb09b312fcc084 100644
--- a/src/endWeek/reports/personalAttention.js
+++ b/src/endWeek/reports/personalAttention.js
@@ -317,7 +317,7 @@ App.PersonalAttention.slaveReport = function(slave) {
 				} else {
 					slave.training = 0;
 					r.push(`By the end of the week,`);
-					r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, "green"));
+					r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, ["green"]));
 					r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"]));
 					SoftenBehavioralFlaw(slave);
 					slave.devotion += 4;
@@ -325,20 +325,20 @@ App.PersonalAttention.slaveReport = function(slave) {
 				if (slave.fetishKnown !== 1) {
 					if (slave.fetish === Fetish.SUBMISSIVE) {
 						r.push(`${He} really takes to your close attention;`);
-						r.push(App.UI.DOM.makeElement("span", `${he}'s a natural submissive!`, "pink"));
-						(slave.fetishKnown = 1);
+						r.push(App.UI.DOM.makeElement("span", `${he}'s a natural submissive!`, ["pink"]));
+						slave.fetishKnown = 1;
 					} else if (slave.fetish === "cumslut") {
 						r.push(`While you're giving ${him} personal attention, you discover by chance that`);
-						r.push(App.UI.DOM.makeElement("span", `${he} has an oral fixation!`, "pink"));
-						(slave.fetishKnown = 1);
+						r.push(App.UI.DOM.makeElement("span", `${he} has an oral fixation!`, ["pink"]));
+						slave.fetishKnown = 1;
 					} else if (slave.fetish === "masochist") {
 						r.push(`While you're giving ${him} personal correction, you discover by chance that`);
-						r.push(App.UI.DOM.makeElement("span", `${he} likes pain!`, "pink"));
-						(slave.fetishKnown = 1);
+						r.push(App.UI.DOM.makeElement("span", `${he} likes pain!`, ["pink"]));
+						slave.fetishKnown = 1;
 					} else if (slave.fetish === "humiliation") {
 						r.push(`While you're giving ${him} personal attention in public, you discover by chance that`);
-						r.push(App.UI.DOM.makeElement("span", `${he} likes humiliation!`, "pink"));
-						(slave.fetishKnown = 1);
+						r.push(App.UI.DOM.makeElement("span", `${he} likes humiliation!`, ["pink"]));
+						slave.fetishKnown = 1;
 					}
 				}
 				if (slave.behavioralFlaw === "none") {
@@ -474,7 +474,7 @@ App.PersonalAttention.slaveReport = function(slave) {
 				} else {
 					slave.training = 0;
 					r.push(`By the end of the week,`);
-					r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, "green"));
+					r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, ["green"]));
 					r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"]));
 					SoftenSexualFlaw(slave);
 					slave.devotion += 4;
@@ -482,19 +482,19 @@ App.PersonalAttention.slaveReport = function(slave) {
 				if (slave.fetishKnown !== 1) {
 					if (slave.fetish === Fetish.SUBMISSIVE) {
 						r.push(`${He} really takes to your close attention;`);
-						r.push(App.UI.DOM.makeElement("span", `${he}'s a natural submissive!`, "pink"));
+						r.push(App.UI.DOM.makeElement("span", `${he}'s a natural submissive!`, ["pink"]));
 						slave.fetishKnown = 1;
 					} else if (slave.fetish === "cumslut") {
 						r.push(`While you're giving ${him} personal attention, you discover by chance that`);
-						r.push(App.UI.DOM.makeElement("span", `${he} has an oral fixation!`, "pink"));
+						r.push(App.UI.DOM.makeElement("span", `${he} has an oral fixation!`, ["pink"]));
 						slave.fetishKnown = 1;
 					} else if (slave.fetish === "masochist") {
 						r.push(`While you're giving ${him} personal correction, you discover by chance that`);
-						r.push(App.UI.DOM.makeElement("span", `${he} likes pain!`, "pink"));
+						r.push(App.UI.DOM.makeElement("span", `${he} likes pain!`, ["pink"]));
 						slave.fetishKnown = 1;
 					} else if (slave.fetish === "humiliation") {
 						r.push(`While you're giving ${him} personal attention in public, you discover by chance that`);
-						r.push(App.UI.DOM.makeElement("span", `${he} likes humiliation!`, "pink"));
+						r.push(App.UI.DOM.makeElement("span", `${he} likes humiliation!`, ["pink"]));
 						slave.fetishKnown = 1;
 					}
 				}
diff --git a/src/endWeek/saGuardYou.js b/src/endWeek/saGuardYou.js
index 7d73f89e5147fbcf3b7dd80aa47c970eae9c222e..e4cef6ec030782abb119a1f980ee81fb27726356 100644
--- a/src/endWeek/saGuardYou.js
+++ b/src/endWeek/saGuardYou.js
@@ -248,6 +248,7 @@ App.SlaveAssignment.guardYou = function saGuardYou(slave) {
 	 *
 	 */
 	function trainReplacements(slave) {
+		/** @type {[boolean, string][]} */
 		const requirements = [
 			[slave.devotion > 95, "not devoted enough"],
 			[slave.trust > 50, "too fearful"],
@@ -257,7 +258,7 @@ App.SlaveAssignment.guardYou = function saGuardYou(slave) {
 
 		if (requirements.filter(s => !s[0]).length > 0) {
 			if (V.debugMode > 0) {
-				r.push(`<span class="yellow">${He}'s is ${toSentence(requirements.filter(s => !s[0]).map(s => s[1]))} to train any successors.</span>`);
+				r.push(`<span class="yellow">${He} is ${toSentence(requirements.filter(s => !s[0]).map(s => s[1]))} to train any successors.</span>`);
 			}
 		} else {
 			const successorCandidates = V.slaves.filter(function(s) { return (assignmentVisible(s) || s.assignment === Job.CONCUBINE || s.assignment === Job.WARDEN || s.assignment === Job.HEADGIRL || s.assignment === Job.QUARTER || s.assignment === Job.MASTERSUITE) && bodyguardSuccessorEligible(s); });
diff --git a/src/events/RE/reCitizenHookup.js b/src/events/RE/reCitizenHookup.js
index 39e8a0b1379ad0c95dfe6d82801a67239bd7718f..67b248293a79fd43bb8e88c3e9ee707d51332480 100644
--- a/src/events/RE/reCitizenHookup.js
+++ b/src/events/RE/reCitizenHookup.js
@@ -9,9 +9,8 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 		let r = [];
 		let repopHookupPregnant;
 
-		const fsArray = App.Data.FutureSociety.fsNames.filter(f => V.arcologies[0][f] !== "unset");
-		const FS = fsArray.random();
-		const fsAdj = (fsArray.length > 0) ? App.Data.FutureSociety.records[FS].adj : "none";
+		const FSArray = FutureSocieties.activeFSes(V.arcologies[0]);
+		const FS = (FSArray.length > 0) ? FSArray.random() : "none";
 
 		r.push(`At night, the best living areas in the arcology offer a constant mélange of selective entertainments. There's a perpetual social scrum of who is to be invited to what going on, and you occupy a preeminent place atop it, mostly aloof from the struggles of your citizens for recognition and influence. You're invited to almost everything, since everyone who lives here knows the value of being in favor with the owner of the arcology. Invitations to your parties, of course, are some of the most valuable social currency in the arcology and one of ${V.assistant.name}'s most important duties is to help you manage them without wasting your valuable time. It's not actually necessary for you to attend your own parties, since almost everyone will be glad to be seen in the entertainment area of the penthouse whether or not the`);
 		r.push(`${V.PC.title === 1 ? 'proprietor' : 'proprietress'} is actually present.`);
@@ -26,18 +25,18 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 			r.push(`alcohol`);
 		}
 		r.push(`and eating your food, though of course they helped pay for it through their rent. They're performing a complex dance of social dominance, and it all radiates around you, with complex unspoken rules of collective approval governing which citizens cycle past you for a word, and for how long. During a low point in the ebb and flow,`);
-		switch (fsAdj) {
-			case "Subjugationist":
-			case "Supremacist":
+		switch (FS) {
+			case "FSSubjugationist":
+			case "FSSupremacist":
 				r.push(`a pretty, racially pure young woman`);
 				break;
-			case "Gender Radicalist":
+			case "FSGenderRadicalist":
 				r.push(`a beautiful young futa`);
 				break;
-			case "Gender Fundamentalist":
+			case "FSGenderFundamentalist":
 				r.push(`a good-looking young lady`);
 				break;
-			case "Repopulationist":
+			case "FSRepopulationFocus":
 				if (V.arcologies[0].FSRepopulationFocusLaw === 1 && (random(1, 10) > 3)) {
 					repopHookupPregnant = 1;
 					r.push(`a heavily pregnant young lady`);
@@ -46,22 +45,22 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 					r.push(`a pretty, fertile young woman with wide, child-bearing hips`);
 				}
 				break;
-			case "Eugenics":
+			case "FSRestart":
 				r.push(`a stunningly gorgeous woman`);
 				break;
-			case "Paternalist":
+			case "FSPaternalist":
 				r.push(`a pretty, cheerful young woman`);
 				break;
-			case "Degradationist":
+			case "FSDegradationist":
 				r.push(`a confident girl`);
 				break;
-			case "Body Purist":
+			case "FSBodyPurist":
 				r.push(`a clean-looking young woman`);
 				break;
-			case "Transformation Fetishist":
+			case "FSTransformationFetishist":
 				r.push(`a nicely augmented girl`);
 				break;
-			case "Youth Preferentialist":
+			case "FSYouthPreferentialist":
 				if (V.minimumSlaveAge < 13) {
 					r.push(`an adorable little loli`);
 				} else if (V.minimumSlaveAge < 18) {
@@ -70,83 +69,83 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 					r.push(`a nice looking girl`);
 				}
 				break;
-			case "Maturity Preferentialist":
+			case "FSMaturityPreferentialist":
 				r.push(`an attractive, mature woman`);
 				break;
-			case "Slimness Enthusiast":
+			case "FSSlimnessEnthusiast":
 				r.push(`a slim young thing`);
 				break;
-			case "Asset Expansionist":
+			case "FSAssetExpansionist":
 				r.push(`a curvaceous young woman`);
 				break;
-			case "Pastoralist":
+			case "FSPastoralist":
 				r.push(`a hot little lady`);
 				break;
-			case "Physical Idealist":
+			case "FSPhysicalIdealist":
 				r.push(`a hot little amazon`);
 				break;
-			case "Hedonistic":
+			case "FSHedonisticDecadence":
 				r.push(`a plump little cutey`);
 				break;
-			case "Chattel Religionist":
+			case "FSChattelReligionist":
 				r.push(`a pretty, devout-looking young woman`);
 				break;
-			case "Roman Revivalist":
+			case "FSRomanRevivalist":
 				r.push(`a proper young Roman lady`);
 				break;
-			case "Neo-Imperialism":
+			case "FSNeoImperialist":
 				r.push(`a gorgeous young Imperial Knight with flowing blonde hair and a scarred face`);
 				break;
-			case "Aztec Revivalist":
+			case "FSAztecRevivalist":
 				r.push(`a natural Aztec beauty`);
 				break;
-			case "Egyptian Revivalist":
+			case "FSEgyptianRevivalist":
 				r.push(`a pretty, sun-kissed lady`);
 				break;
-			case "Edo Revivalist":
+			case "FSEdoRevivalist":
 				r.push(`a proper Edo lady`);
 				break;
-			case "Arabian Revivalist":
+			case "FSArabianRevivalist":
 				r.push(`a pretty Arabian princess`);
 				break;
-			case "Chinese Revivalist":
+			case "FSChineseRevivalist":
 				r.push(`a pretty Chinese lady`);
 				break;
-			case "Intellectual Dependency":
+			case "FSIntellectualDependency":
 				r.push(`a cute party girl`);
 				break;
-			case "Slave Professionalism":
+			case "FSSlaveProfessionalism":
 				r.push(`an elegant woman`);
 				break;
-			case "Petite Admiration":
+			case "FSPetiteAdmiration":
 				r.push(`a delightfully short young lady`);
 				break;
-			case "Statuesque Glorification":
+			case "FSStatuesqueGlorification":
 				r.push(`a towering figure`);
 				break;
 			default:
 				r.push(`a pretty young woman`);
 		}
 		r.push(`sidles up to you. She begins to introduce herself, but one of the advantages of your connection to the arcology is that you always know who everyone is, and you greet her by name, which people have never learned not to be impressed by. She gushes about some of your recent`);
-		if (fsAdj !== "none") {
-			r.push(fsAdj);
+		if (FS !== "none") {
+			r.push(FutureSocieties.displayAdj(FS));
 		}
 		r.push(`actions, displaying an unusual grasp of what you've been planning. Despite her sincere interest, she's obviously got something else on her mind.`);
 		App.Events.addParagraph(node, r);
 		r = [];
 		r.push(`She's yours for the taking, if you want her, and if her praise and proximity weren't enough to make that clear, she manages to`);
-		switch (fsAdj) {
-			case "Subjugationist":
-			case "Supremacist":
+		switch (FS) {
+			case "FSSubjugationist":
+			case "FSSupremacist":
 				r.push(`give you an excellent view straight down her ethnically superior cleavage, straining against the top of her fashionable dress.`);
 				break;
-			case "Gender Radicalist":
+			case "FSGenderRadicalist":
 				r.push(`simultaneously give you an excellent view straight down her cleavage, and bring the material of her sheer dress tight across her legs in a way that outlines her dick.`);
 				break;
-			case "Gender Fundamentalist":
+			case "FSGenderFundamentalist":
 				r.push(`press her flirting as far she can decorously take it, batting her eyes at you coquettishly.`);
 				break;
-			case "Repopulationist":
+			case "FSRepopulationFocus":
 				if (repopHookupPregnant === 1) {
 					r.push(`lean back just far enough that her full term, triplets rounded middle splits the front of her overly tight dress.`);
 				} else {
@@ -158,76 +157,76 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 					}
 				}
 				break;
-			case "Eugenics":
+			case "FSRestart":
 				r.push(`give you an excellent view straight down her perfect cleavage, straining against the top of her name-brand dress.`);
 				break;
-			case "Paternalist":
+			case "FSPaternalist":
 				r.push(`brush her breasts against your arm, presuming on the egalitarian nature of your Paternalist society to flirt a little aggressively.`);
 				break;
-			case "Degradationist":
+			case "FSDegradationist":
 				r.push(`raise one shoulder far enough that her breast on that side pulls its nipple just clear of her tight leather dress, revealing a spiked piercing.`);
 				break;
-			case "Body Purist":
+			case "FSBodyPurist":
 				r.push(`arch her back with such warm propinquity that her natural breasts almost spill out of her tight little dress, and actually reveal the upper edges of their areolae.`);
 				break;
-			case "Transformation Fetishist":
+			case "FSTransformationFetishist":
 				r.push(`pop her huge fake boobs entirely out of her tight little evening dress without even using her hands.`);
 				break;
-			case "Youth Preferentialist":
+			case "FSYouthPreferentialist":
 				r.push(`perfectly balance her youthful, innocent appeal with the proper decorum between you and a citizen.`);
 				break;
-			case "Maturity Preferentialist":
+			case "FSMaturityPreferentialist":
 				r.push(`perfectly balance her matronly, sensual appeal with the proper decorum between you and a citizen.`);
 				break;
-			case "Slimness Enthusiast":
+			case "FSSlimnessEnthusiast":
 				r.push(`turn from side to side as she flirts with you in a way that shows off the coquettish forum under her tight dress to great effect.`);
 				break;
-			case "Asset Expansionist":
+			case "FSAssetExpansionist":
 				r.push(`arch her back with such warm propinquity that her huge breasts spill out of her tight little dress, springing clear to offer themselves glorious and nude.`);
 				break;
-			case "Pastoralist":
+			case "FSPastoralist":
 				r.push(`let you know that she's almost entirely milk-fed, while giving you quite an eyeful of her straining cleavage.`);
 				break;
-			case "Physical Idealist":
+			case "FSPhysicalIdealist":
 				r.push(`get a pretty good flex going without being obvious about it, outlining her abs against the sheer midsection of her tight dress.`);
 				break;
-			case "Hedonistic":
+			case "FSHedonisticDecadence":
 				r.push(`lean her chubby body back far enough to pop the buttons off her top and allow her ample breasts and armful of a belly to hang free.`);
 				break;
-			case "Chattel Religionist":
+			case "FSChattelReligionist":
 				r.push(`assume just a hint of a Chattel Religionist devotional pose used to request penetration. It's heavy flirting, of a modern religious sort.`);
 				break;
-			case "Roman Revivalist":
+			case "FSRomanRevivalist":
 				r.push(`hint that her pudicitia, that is her purity, would be if anything enhanced by sexual commerce with someone as powerful as you.`);
 				break;
-			case "Neo-Imperialism":
+			case "FSNeoImperialist":
 				r.push(`hint that as a Knight under your banner, to serve you in *any* way would be among the greatest of honors.`);
 				break;
-			case "Aztec Revivalist":
+			case "FSAztecRevivalist":
 				r.push(`hint that her devotion, which is the most important thing, cannot be besmirched by tasting your divine power.`);
 				break;
-			case "Egyptian Revivalist":
+			case "FSEgyptianRevivalist":
 				r.push(`hint that she would like nothing better than to bask in the pharaonic light in the arcology, very close to its source, while loosening her linen dress a little.`);
 				break;
-			case "Edo Revivalist":
+			case "FSEdoRevivalist":
 				r.push(`allude to the refined pleasures, while assuming a slightly less dignified posture in her gorgeous kimono.`);
 				break;
-			case "Arabian Revivalist":
+			case "FSArabianRevivalist":
 				r.push(`reference young Scheherazade and mighty Shahryar in a way that suggests she's quite willing to play the former.`);
 				break;
-			case "Chinese Revivalist":
+			case "FSChineseRevivalist":
 				r.push(`allude to the divinity that resides with the powerful, implying that she'd very much like to come closer to it.`);
 				break;
-			case "Intellectual Dependency":
+			case "FSIntellectualDependency":
 				r.push(`hint that she forgot to put on panties and that she needs that dripping sound checked out.`);
 				break;
-			case "Slave Professionalism":
+			case "FSSlaveProfessionalism":
 				r.push(`bring you fully erect with a single, masterful stroke of her fingers.`);
 				break;
-			case "Petite Admiration":
+			case "FSPetiteAdmiration":
 				r.push(`give the bulge in your pants a quick kiss.`);
 				break;
-			case "Statuesque Glorification":
+			case "FSStatuesqueGlorification":
 				r.push(`affectionately rest her breasts on your head.`);
 				break;
 			default:
@@ -240,7 +239,7 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 			new App.Events.Result(`Keep aloof without offending her`, aloof),
 			new App.Events.Result(`To them that hath, it shall be given`, give)
 		];
-		if (fsAdj !== "none") {
+		if (FS !== "none") {
 			choices.push(new App.Events.Result(`Emphasize her societal style with exhibitionism`, exhibitionism));
 		}
 		App.Events.addResponses(node, choices);
@@ -289,18 +288,18 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 				}
 			}
 			r.push(`Your guest restrains her eager praise now that you're in private, but her wide-eyed appreciation of your domain is compliment enough. Once in your suite, she strips, revealing`);
-			switch (fsAdj) {
-				case "Subjugationist":
-				case "Supremacist":
+			switch (FS) {
+				case "FSSubjugationist":
+				case "FSSupremacist":
 					r.push(`her fresh, pure body.`);
 					break;
-				case "Gender Radicalist":
+				case "FSGenderRadicalist":
 					r.push(`perky young breasts, a pretty pussy, and a stiff dick above it.`);
 					break;
-				case "Gender Fundamentalist":
+				case "FSGenderFundamentalist":
 					r.push(`perky young breasts and an elegantly coiffed strip of hair that perfectly highlights her demure pussy.`);
 					break;
-				case "Repopulationist":
+				case "FSRepopulationFocus":
 					if (repopHookupPregnant === 1) {
 						if (random(1, 10) > 7) {
 							r.push(`an experienced body, comfortable with the burdens of pregnancy.`);
@@ -316,76 +315,76 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 						}
 					}
 					break;
-				case "Eugenics":
+				case "FSRestart":
 					r.push(`a near flawless body; the only distinguishable mark on it: a small tattoo of a prestigious school.`);
 					break;
-				case "Paternalist":
+				case "FSPaternalist":
 					r.push(`a nice young body, with all the little attractions and flaws of a free girl's.`);
 					break;
-				case "Degradationist":
+				case "FSDegradationist":
 					r.push(`a taut body covered in dominant tattoos and spiky piercings.`);
 					break;
-				case "Body Purist":
+				case "FSBodyPurist":
 					r.push(`a delectably curvaceous young body unmarred by any trace of surgical intervention.`);
 					break;
-				case "Transformation Fetishist":
+				case "FSTransformationFetishist":
 					r.push(`a massive fake bubble butt to go with her fake boobs.`);
 					break;
-				case "Youth Preferentialist":
+				case "FSYouthPreferentialist":
 					r.push(`that her whole body looks fresh, untouched, and quite young.`);
 					break;
-				case "Maturity Preferentialist":
+				case "FSMaturityPreferentialist":
 					r.push(`a big pair of motherly tits, generous hips, a broad ass, and total self confidence.`);
 					break;
-				case "Slimness Enthusiast":
+				case "FSSlimnessEnthusiast":
 					r.push(`perky little breasts, a smooth waist, trim hips, and a cute little ass.`);
 					break;
-				case "Asset Expansionist":
+				case "FSAssetExpansionist":
 					r.push(`an inhumanly enormous ass to match her similarly improbable boobs.`);
 					break;
-				case "Pastoralist":
+				case "FSPastoralist":
 					r.push(`amply milk-fed assets.`);
 					break;
-				case "Physical Idealist":
+				case "FSPhysicalIdealist":
 					r.push(`the dimples that form on the sides of her cute buttocks when she flexes.`);
 					break;
-				case "Hedonistic":
+				case "FSHedonisticDecadence":
 					r.push(`well-fed and delightfully jiggly assets.`);
 					break;
-				case "Chattel Religionist":
+				case "FSChattelReligionist":
 					r.push(`a fresh and ready body, adorned here and there with sensual devotional jewelry.`);
 					break;
-				case "Roman Revivalist":
+				case "FSRomanRevivalist":
 					r.push(`a graceful, milk-pale vision of classical beauty.`);
 					break;
-				case "Neo-Imperialism":
+				case "FSNeoImperialist":
 					r.push(`a statuesque body, corded with fit musculature made for practical service.`);
 					break;
-				case "Aztec Revivalist":
+				case "FSAztecRevivalist":
 					r.push(`a strong, tight, bronze body.`);
 					break;
-				case "Egyptian Revivalist":
+				case "FSEgyptianRevivalist":
 					r.push(`a perfect expanse of smooth, warm, tanned skin.`);
 					break;
-				case "Edo Revivalist":
+				case "FSEdoRevivalist":
 					r.push(`a graceful form so perfectly pale that her face requires almost no whitening at all.`);
 					break;
-				case "Arabian Revivalist":
+				case "FSArabianRevivalist":
 					r.push(`a nubile young body perfectly formed for a Sultan's bed.`);
 					break;
-				case "Chinese Revivalist":
+				case "FSChineseRevivalist":
 					r.push(`a pretty young body that would not look out of place in an Imperial bed.`);
 					break;
-				case "Intellectual Dependency":
+				case "FSIntellectualDependency":
 					r.push(`a young body practically begging you for dick.`);
 					break;
-				case "Slave Professionalism":
+				case "FSSlaveProfessionalism":
 					r.push(`an elegant, mature body that knows its way around the bedroom.`);
 					break;
-				case "Petite Admiration":
+				case "FSPetiteAdmiration":
 					r.push(`an adorably petite figure.`);
 					break;
-				case "Statuesque Glorification":
+				case "FSStatuesqueGlorification":
 					r.push(`that you have to crane your neck back to take in her full stature.`);
 					break;
 				default:
@@ -407,10 +406,10 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 			}
 			r.push(`When your guest is finally spent, she showers, dresses, and leaves discreetly, offering you a proper thank you. This is the kind of thing that <span class="green">builds a lasting reputation</span> in the Free Cities.`);
 			repX(5000, "event");
-			if (fsAdj === "Repopulationist" && V.PC.dick !== 0 && repopHookupPregnant === 0 && (random(1, 100) > 40)) {
-				addTrinket(`a tasteful morning-after message, with attached positive pregnancy test, from a pretty ${fsAdj} citizen you bred`);
-			} else if (fsAdj !== "none") {
-				addTrinket(`a tasteful morning-after message from a pretty ${fsAdj} citizen`);
+			if (FS === "FSRepopulationFocus" && V.PC.dick !== 0 && repopHookupPregnant === 0 && (random(1, 100) > 40)) {
+				addTrinket(`a tasteful morning-after message, with attached positive pregnancy test, from a pretty citizen you bred`);
+			} else if (FS !== "none") {
+				addTrinket(`a tasteful morning-after message from a pretty ${FutureSocieties.displayAdj(FS)} citizen`);
 			} else {
 				addTrinket("a tasteful morning-after message from a pretty citizen");
 			}
@@ -422,99 +421,99 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 			const frag = new DocumentFragment();
 			let r = [];
 			r.push(`You turn to face her straight on, and something about the look in your eye fills her with mixed apprehension and anticipation. You agree with her banter and praise her for being so forward-thinking, before transitioning to more direct praise of her style and then her body. You're speaking in a tone that cuts through the room, and by the time you kiss your willing conquest, there's not a person in the room who isn't paying attention. They all understand the message: this gathering is turning into something else, now. Those few who aren't willing to fuck in public withdraw, and everyone who didn't come with a sexual partner sends urgent messages to have appropriate slaves brought from their apartments. You make out with her for a while, letting everyone make arrangements, and then pull her clothes off, making sure her`);
-			if (!["none", "Multiculturalist"].includes(fsAdj)) {
+			if (!["none", "FSNull"].includes(FS)) {
 				V.arcologies[0][FS] += 5;
 			}
-			switch (fsAdj) {
-				case "Subjugationist":
-				case "Supremacist":
+			switch (FS) {
+				case "FSSubjugationist":
+				case "FSSupremacist":
 					r.push(`superior body`);
 					break;
-				case "Gender Radicalist":
+				case "FSGenderRadicalist":
 					r.push(`tits and stiff dick`);
 					break;
-				case "Gender Fundamentalist":
+				case "FSGenderFundamentalist":
 					r.push(`femininity`);
 					break;
-				case "Repopulationist":
+				case "FSRepopulationFocus":
 					if (repopHookupPregnant === 1) {
 						r.push(`fecund body`);
 					} else {
 						r.push(`ready-to-be-bred body`);
 					}
 					break;
-				case "Eugenics":
+				case "FSRestart":
 					r.push(`perfect body`);
 					break;
-				case "Paternalist":
+				case "FSPaternalist":
 					r.push(`appealing body`);
 					break;
-				case "Degradationist":
+				case "FSDegradationist":
 					r.push(`dominant form`);
 					break;
-				case "Body Purist":
+				case "FSBodyPurist":
 					r.push(`natural body`);
 					break;
-				case "Transformation Fetishist":
+				case "FSTransformationFetishist":
 					r.push(`fake butt`);
 					break;
-				case "Youth Preferentialist":
+				case "FSYouthPreferentialist":
 					r.push(`young body`);
 					break;
-				case "Maturity Preferentialist":
+				case "FSMaturityPreferentialist":
 					r.push(`mature body`);
 					break;
-				case "Slimness Enthusiast":
+				case "FSSlimnessEnthusiast":
 					r.push(`slender body`);
 					break;
-				case "Asset Expansionist":
+				case "FSAssetExpansionist":
 					r.push(`curvaceous form`);
 					break;
-				case "Pastoralist":
+				case "FSPastoralist":
 					r.push(`milk-fed plushness`);
 					break;
-				case "Physical Idealist":
+				case "FSPhysicalIdealist":
 					r.push(`muscular body`);
 					break;
-				case "Hedonistic":
+				case "FSHedonisticDecadence":
 					r.push(`plump body`);
 					break;
-				case "Chattel Religionist":
+				case "FSChattelReligionist":
 					r.push(`divine sexuality`);
 					break;
-				case "Roman Revivalist":
+				case "FSRomanRevivalist":
 					r.push(`elegant form`);
 					break;
-				case "Neo-Imperialism":
+				case "FSNeoImperialist":
 					r.push(`chiseled body`);
 					break;
-				case "Aztec Revivalist":
+				case "FSAztecRevivalist":
 					r.push(`well-built form`);
 					break;
-				case "Egyptian Revivalist":
+				case "FSEgyptianRevivalist":
 					r.push(`beautiful tanned body`);
 					break;
-				case "Arabian Revivalist":
-				case "Chinese Revivalist":
-				case "Edo Revivalist":
+				case "FSArabianRevivalist":
+				case "FSChineseRevivalist":
+				case "FSEdoRevivalist":
 					r.push(`graceful form`);
 					break;
-				case "Intellectual Dependency":
+				case "FSIntellectualDependency":
 					r.push(`extreme horniness`);
 					break;
-				case "Slave Professionalism":
+				case "FSSlaveProfessionalism":
 					r.push(`experienced body`);
 					break;
-				case "Petite Admiration":
+				case "FSPetiteAdmiration":
 					r.push(`tiny form`);
 					break;
-				case "Statuesque Glorification":
+				case "FSStatuesqueGlorification":
 					r.push(`towering form`);
 					break;
 				default:
 					r.push(`hot young body`);
 			}
-			r.push(`is obvious to everyone. The message is clear, and your guest of honor is the center of attention as you take her there in view of the arcology's leading citizens. Naturally, the story percolates, making it clear that there's nothing you won't do to <span class="green">further acceptance of ${fsArray.length > 0 ? FutureSocieties.displayAdj(FS) : "societal"} principles.</span>`);
+			r.push(`is obvious to everyone. The message is clear, and your guest of honor is the center of attention as you take her there in view of the arcology's leading citizens. Naturally, the story percolates, making it clear that there's nothing you won't do to <span class="green">further acceptance of ${FS !== "none" ? FutureSocieties.displayAdj(FS) : "societal"} principles.</span>`);
 
 			App.Events.addParagraph(frag, r);
 			return frag;
diff --git a/src/events/REFS/refsKnightlyDuel.js b/src/events/REFS/refsKnightlyDuel.js
index a1e8d64f1b574817da8d52174a27e04a40c49e5b..43601b026771b27c0190cf6353c1a22ef6e04ce4 100644
--- a/src/events/REFS/refsKnightlyDuel.js
+++ b/src/events/REFS/refsKnightlyDuel.js
@@ -47,7 +47,7 @@ App.Events.refsKnightlyDuel = class refsKnightlyDuel extends App.Events.BaseEven
 		}
 
 		function televise() {
-			cashX(3000, "televised a duel");
+			cashX(3000, "event");
 			repX(-2500, "event");
 			return `The Knights straighten up as you inform them that you'll allow the duel, and they're hardly listening when you explain that it'll be televised under your supervision. If anything, they seem more excited to have an audience for their fight. A few days later, you host the event between your two champions, giving each a longsword and a tabard bearing their coat of arms as their only protection against the other. With the cameras rolling, you announce for the duel to commence, and the two massive men lunge at once another with the immediate clatter of steel on steel. As the crowd cheers fanatically, the two Knights wrestle and fight, slashing violently at the slightest sign of exposure from their enemy. After a few intense minutes of close, bloody fighting, one of the Knights slips for a moment on a pocket of loose sand, and the other rams his longsword through their neck immediately, nearly decapitating him in single motion. The crowd cheers wildly as the victorious Knight drives the rest of his longsword to the side, totally severing his enemy's head from their shoulders. As you congratulate the victor on his success, ${V.assistant.name} sends you a series of statistics indicating that the short, televised brutality has earned you <span class="cash inc">several thousand credits,</span> but that many of the public are absolutely <span class="reputation dec">horrified</span> to have seen idolized Knights murder one another in such a senseless display of brutality.`;
 		}
diff --git a/src/events/REFS/refsWarhound.js b/src/events/REFS/refsWarhound.js
index b841a48fe9db2327866413f8ba00c9a3a471357e..27e7b6f1aa2ca8f819e956e05dd682a7699be756 100644
--- a/src/events/REFS/refsWarhound.js
+++ b/src/events/REFS/refsWarhound.js
@@ -93,7 +93,7 @@ App.Events.refsWarhound = class refsWarhound extends App.Events.BaseEvent {
 		App.Events.addResponses(node, choices);
 
 		function buy() {
-			cashX(-enormousCash, "Bought a Warbeast");
+			cashX(forceNeg(enormousCash), "slaveTransfer", slave);
 			return [
 				`You nod once to the merchant and electronically transfer the money to him without a second thought. The pudgy man clasps his hands together gleefully and then hands you the leash, smiling like a snake. "Oh, and we have not yet assigned ${him} a name, my liege - please feel free to call ${him} whatever you wish. Enjoy your new beast!"`,
 				App.UI.newSlaveIntro(slave)
diff --git a/src/events/RESS/breedingBull.js b/src/events/RESS/breedingBull.js
index d24523da271bbd99c2a6ac0bcfde256af4cb1671..4d5fbbdb1e64b59ffee272ee99bcaceabc12e26e 100644
--- a/src/events/RESS/breedingBull.js
+++ b/src/events/RESS/breedingBull.js
@@ -24,7 +24,7 @@ App.Events.RESSBreedingBull = class RESSBreedingBull extends App.Events.BaseEven
 
 	get weight() {
 		let weight = 1;
-		if (V.PC.fertDrugs > 0) {
+		if (V.PC.drugs === "fertility supplements" || V.PC.diet === "fertility") {
 			weight += 2;
 		}
 		if (V.PC.forcedFertDrugs > 0) {
diff --git a/src/events/RESS/review/gorging.js b/src/events/RESS/review/gorging.js
index 3d98b349b1d2187e79e6027031c628f174159e28..cbdb16e091da1c64ee97490808a6d816afa9b867 100644
--- a/src/events/RESS/review/gorging.js
+++ b/src/events/RESS/review/gorging.js
@@ -55,7 +55,6 @@ App.Events.RESSGorging = class RESSGorging extends App.Events.BaseEvent {
 		App.Events.addParagraph(node, r);
 		r = [];
 
-		r.push(``);
 		if (V.cockFeeder === 1) {
 			r.push(`${eventSlave.slaveName} is kneeling on the floor, passionately working the phallic dispenser. ${His} ${eventSlave.lips > 50 ? "plush" : ""} lips are wrapped around the rod, producing loud slurping sounds as ${he} aggressively sucks it while rubbing ${his} growing belly.`);
 		} else {
@@ -75,7 +74,7 @@ App.Events.RESSGorging = class RESSGorging extends App.Events.BaseEvent {
 		} else if (eventSlave.trust < -50) {
 			r.push(`${He} attempts to get up quickly, terror clouding ${his} face. However, ${his} cumbersome belly hinders ${his} movements and in ${his} haste, ${he} slips in the puddle of slave food. ${He} quickly prostrates ${himself} in front of you, begging for your forgiveness.`);
 		} else if (eventSlave.devotion > 50){
-			r.push(Spoken(eventSlave, `${Master}! I was just so ${slave.energy > 80 ? "horny" : "hungry"}, I don't know what came over me. I just needed to feel my belly growing..."`), ` ${he} ${eventSlave.trust > 50 ? "" : "nervously"} explains while continuing to tease ${his} bloated form. ${He} must have been in the cafeteria for a while already, as ${his} swollen belly sloshes slightly as ${he} speaks.`);
+			r.push(Spoken(eventSlave, `${Master}! I was just so ${eventSlave.energy > 80 ? "horny" : "hungry"}, I don't know what came over me. I just needed to feel my belly growing..."`), ` ${he} ${eventSlave.trust > 50 ? "" : "nervously"} explains while continuing to tease ${his} bloated form. ${He} must have been in the cafeteria for a while already, as ${his} swollen belly sloshes slightly as ${he} speaks.`);
 		} else if (eventSlave.devotion > 20){
 			r.push(Spoken(eventSlave, `${Master}! I don't know what came over me!`), ` ${he} ${eventSlave.trust > 50 ? "" : "nervously"} exclaims while continuing to massage ${his} bloated form, waiting to see how you will react. ${He} must have been in the cafeteria for a while already, as ${his} swollen belly sloshes slightly as ${he} speaks.`);
 		} else {
@@ -209,9 +208,9 @@ App.Events.RESSGorging = class RESSGorging extends App.Events.BaseEvent {
 
 			eventSlave.devotion += 5;
 			if (canDoVaginal(eventSlave)) {
-				t.push(VCheck.Vaginal(eventSlave, 1));
+				r.push(VCheck.Vaginal(eventSlave, 1));
 			} else {
-				t.push(VCheck.Anal(eventSlave, 1));
+				r.push(VCheck.Anal(eventSlave, 1));
 			}
 			eventSlave.inflation = 3;
 			SetBellySize(eventSlave);
diff --git a/src/events/intro/pcAppearance.js b/src/events/intro/pcAppearance.js
index b8b04b9e38e7d25d93a32790fb13e46f05d391da..a318ba069f96e9b46d8c13eb92699f8c6d021864 100644
--- a/src/events/intro/pcAppearance.js
+++ b/src/events/intro/pcAppearance.js
@@ -1214,13 +1214,7 @@ App.UI.Player.design = function() {
 		options.addOption(`Sexual Energy`, "sexualEnergy", V.PC).showTextBox();
 		options.addOption(`Cum Tap`, "cumTap", V.PC.skill).showTextBox();
 		options.addOption(`Stored Cum`, "storedCum", V.PC.counter).showTextBox();
-		options.addOption(`Fertility Drugs`, "fertDrugs", V.PC)
-			.addValue("Yes", 1).on()
-			.addValue("No", 0).off();
 		options.addOption(`Forced Fertility Drugs`, "forcedFertDrugs", V.PC).showTextBox();
-		options.addOption(`Stamina Pills`, "staminaPills", V.PC)
-			.addValue("Yes", 1).on()
-			.addValue("No", 0).off();
 		el.append(options.render());
 	}
 
diff --git a/src/events/intro/pcExperienceIntro.js b/src/events/intro/pcExperienceIntro.js
index f8bf09ef3ffbe8803f5e1d0ee43a29a8c51a3196..9795c870073b77fcc4f404f14561946e99f4dcc4 100644
--- a/src/events/intro/pcExperienceIntro.js
+++ b/src/events/intro/pcExperienceIntro.js
@@ -1,5 +1,4 @@
 App.Intro.PCExperienceIntro = function() {
-	//	:: PC Experience Intro [nobr]
 	const node = new DocumentFragment();
 
 	V.showSecExp = V.showSecExp || 0;
diff --git a/src/events/intro/pcRumorIntro.js b/src/events/intro/pcRumorIntro.js
index a9d29db217e28ca9006a6cb1af05377bb958747b..ce59b6e765fcb036b1ecd78dc218dba1e922bcd4 100644
--- a/src/events/intro/pcRumorIntro.js
+++ b/src/events/intro/pcRumorIntro.js
@@ -1,5 +1,4 @@
 App.Intro.PCRumorIntro = function() {
-	//	:: PC Experience Intro [nobr]
 	const node = new DocumentFragment();
 
 	delete V.showSecExp;
diff --git a/src/events/intro/terrainIntro.js b/src/events/intro/terrainIntro.js
index bccd6131a31fcc8c73942d6243621861e070c10d..24aa9d9336e3a8af10c5ba80c04949376f2ccbc9 100644
--- a/src/events/intro/terrainIntro.js
+++ b/src/events/intro/terrainIntro.js
@@ -11,7 +11,6 @@
  */
 
 App.Intro.terrainIntro = function() {
-	//	:: Terrain Intro [nobr]
 	const node = new DocumentFragment();
 
 	App.Events.addParagraph(node, [`The Free Cities are located wherever the rule of law is weak enough or permissive enough to allow a small area to secede, and where founders can afford to buy an area on which to build.`]);
diff --git a/src/events/nonRandom/daughters/pUndergroundRailroad.js b/src/events/nonRandom/daughters/pUndergroundRailroad.js
index 557a22fb03b6146ac118cbbaf123ed19c72f125a..dbf86c9f61538d669ee6c1186a544fb6b7592891 100644
--- a/src/events/nonRandom/daughters/pUndergroundRailroad.js
+++ b/src/events/nonRandom/daughters/pUndergroundRailroad.js
@@ -320,9 +320,9 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events.
 			V.traitor.sisters = 0;
 			V.traitor.daughters = 0;
 			if (V.traitor.bodySwap > 0) {
-				const myBody = V.slaves.findIndex(function(s) { return s.origBodyOwnerID === V.traitor.ID; });
-				if (myBody !== -1) {
-					V.traitorStats.traitorBody = V.slaves[myBody].ID;
+				const myBody = V.slaves.find(s => s.origBodyOwnerID === traitor.ID);
+				if (myBody) {
+					V.traitorStats.traitorBody = myBody.ID;
 				}
 			}
 			removeSlave(traitor);
diff --git a/src/events/nonRandom/pAidResult.js b/src/events/nonRandom/pAidResult.js
index 54733f9cf20f9690a9115ec2d70ed30e3d06e37f..1753645d214ec5af3a6e2489833c00cf9fa59e09 100644
--- a/src/events/nonRandom/pAidResult.js
+++ b/src/events/nonRandom/pAidResult.js
@@ -314,7 +314,6 @@ App.Events.pAidResult = class pAidResult extends App.Events.BaseEvent {
 			newSlaves.push(missLeader);
 
 			/* preggo */
-			pram = {disableDisability: 1, ageOverridesPedoMode: 1, race: "white"};
 			if (V.pedo_mode === 1) {
 				pram.minAge = 16;
 				pram.maxAge = 18;
@@ -358,7 +357,6 @@ App.Events.pAidResult = class pAidResult extends App.Events.BaseEvent {
 			newSlaves.push(slave);
 
 			/* post preggo */
-			pram = {disableDisability: 1, ageOverridesPedoMode: 1, race: "white"};
 			if (V.pedo_mode === 1) {
 				pram.minAge = 16;
 				pram.maxAge = 18;
@@ -399,7 +397,6 @@ App.Events.pAidResult = class pAidResult extends App.Events.BaseEvent {
 			newSlaves.push(slave);
 
 			/* young preggo*/
-			pram = {disableDisability: 1, ageOverridesPedoMode: 1, race: "white"};
 			if (V.minimumSlaveAge < V.fertilityAge) {
 				if (V.minimumSlaveAge < 8) {
 					pram.minAge = 8;
diff --git a/src/events/scheduled/assholeKnight.js b/src/events/scheduled/assholeKnight.js
index c93aa374234e9602b98faaeb4859978b2f181c73..49cb6ba80bf343925332bc28a112784745d4bc11 100644
--- a/src/events/scheduled/assholeKnight.js
+++ b/src/events/scheduled/assholeKnight.js
@@ -62,7 +62,7 @@ App.Events.SEAssholeKnight = class SEAssholeKnight extends App.Events.BaseEvent
 		}
 
 		function blindInjustice() {
-			cashX(500, "bribe");
+			cashX(500, "event");
 			repX(-2000, "event");
 			return `You opt to ignore the abuses of the cruel knight completely. Every few weeks, you receive another <span class="red">pleading</span> message in your inbox about the Knight, until they simply stop coming as the lower class accepts the random abuse of their betters. A few days later, as you socialize with your upper-class, the Knight in question passes you a <span class="green">full envelope</span> and winks with no further explanation.`;
 		}
diff --git a/src/events/scheduled/newBaron.js b/src/events/scheduled/newBaron.js
index be34ca48bff96acf1becf9b7a4aafac909cdfb97..a777b423ce3a1a7b66b0b3d49507e1c48d8309d8 100644
--- a/src/events/scheduled/newBaron.js
+++ b/src/events/scheduled/newBaron.js
@@ -26,7 +26,7 @@ App.Events.SENewBaron = class SENewBaron extends App.Events.BaseEvent {
 		App.Events.addResponses(node, choices);
 
 		function executive() {
-			cashX(5000, "Baron gift");
+			cashX(5000, "event");
 			V.arcologies[0].prosperity -= 1;
 			return `You select one of your loyal executives, an ultra-wealthy trader within the arcology who made a fortune in the sale of human bodies, for the new Barony. The man, a portly and unintimidating man that hides a razor-sharp mind behind his fat and an expensive suit, smiles full of teeth as you announce your decision to a waiting crowd of elites. After you go through the formalities and hand him the golden band that'll represent his symbol of office, he shakes your hand vigorously, still smiling devilishly. The next day, the newly-appointed Baron sends you a platter of expensive gifts and foreign candies, complimented with a <span class="green">massive direct deposit to your bank account.</span> You can't help but feel that such a crafty fox might use his new power to <span class="red">corner the market</span> in his barony, though.`;
 		}
diff --git a/src/facilities/penthouse/HGSelect.js b/src/facilities/penthouse/HGSelect.js
index 12af30da4b268ac8983125cbe339527f74ce514b..1001e4333b008e1567aa15f81cd952956cd8bf98 100644
--- a/src/facilities/penthouse/HGSelect.js
+++ b/src/facilities/penthouse/HGSelect.js
@@ -150,9 +150,8 @@ App.Facilities.HGSelect = function() {
 		if (V.seePreg !== 0) {
 			if (V.universalRulesImpregnation === "HG") {
 				App.UI.DOM.appendNewElement("div", f, `${HGName} is responsible for impregnating fertile slaves.`);
-				V.HGCum = resetHGCum(S.HeadGirl);
 				if (canPenetrate(S.HeadGirl) && S.HeadGirl.pubertyXY === 1) {
-					App.UI.DOM.appendNewElement("div", f, `To maximize the chances of impregnation, ${he} will fuck fertile pussies frequently during the week. ${S.HeadGirl.slaveName} can service ${V.HGCum} slaves this way.`);
+					App.UI.DOM.appendNewElement("div", f, `To maximize the chances of impregnation, ${he} will fuck fertile pussies frequently during the week. ${S.HeadGirl.slaveName} can service ${resetHGCum(S.HeadGirl)} slaves this way.`);
 					if (S.HeadGirl.devotion > 95) {
 						App.UI.DOM.appendNewElement("div", f, `${He} loves you so much ${he}'ll fuck them until ${he}'s sore.`);
 					} else {
diff --git a/src/facilities/surgery/analyzePregnancy.js b/src/facilities/surgery/analyzePregnancy.js
index 285359e7840179d9c2228224945c5db7d00a82e5..dae95df153d4c2d28c63ec751e23c331b963084a 100644
--- a/src/facilities/surgery/analyzePregnancy.js
+++ b/src/facilities/surgery/analyzePregnancy.js
@@ -1,5 +1,5 @@
 /**
- * @param {App.Entity.SlaveState} mother
+ * @param {FC.HumanState} mother
  * @param {boolean} cheat
  * @returns {DocumentFragment}
  */
diff --git a/src/gui/Encyclopedia/encyclopediaSlaveLeaders.js b/src/gui/Encyclopedia/encyclopediaSlaveLeaders.js
index ae2c15095b3d991cbb81331b34e4594177e02318..e5f502e1475b14dc10651b5bb1bf49f517c09933 100644
--- a/src/gui/Encyclopedia/encyclopediaSlaveLeaders.js
+++ b/src/gui/Encyclopedia/encyclopediaSlaveLeaders.js
@@ -9,7 +9,8 @@ App.Encyclopedia.addArticle("Leadership Positions", function() {
 App.Encyclopedia.addArticle("Career Experiences", function() {
   const link = (text, article, className) => App.Encyclopedia.Dialog.linkDOM(text, article, className);
   const devotion = (text="devotion") => link(text, "From Rebellious to Devoted", "hotpink");
-  const trust = (text="trust") => link(text, "Trust", "mediumaquamarine");  
+  const trust = (text="trust") => link(text, "Trust", "mediumaquamarine");
+  /** @type {[string, HTMLElement, string, string?][]} */
   const careerData = [
 	["Grateful", trust(), "grateful"],
 	["Menial", devotion() , "menial"],
@@ -35,7 +36,7 @@ App.Encyclopedia.addArticle("Career Experiences", function() {
 
   t.append("Slaves may retain useful experience from their lives before enslavement. Freedom and slavery are so different that the bonuses slaves get are minor. Careers fall into categories, each with its own bonus; these are:");
   for (const [boldItem, bonus, career, note] of careerData) {
-	App.Events.addParagraph(t, [CareerBonus(boldItem, bonus, career, note)]);
+	  App.Events.addParagraph(t, [CareerBonus(boldItem, bonus, career, note)]);
   }
   r.push("Slaves who have been in slavery long enough that it is effectively their career get a bonus to", devotion("devotion."));
   r.push("Slaves can forget their career experience in an industrialized Dairy, but if they do so and remain sane, they will get a special bonus to both", devotion(), "and", trust("trust."));
diff --git a/src/interaction/budgets/recordTemplates.js b/src/interaction/budgets/recordTemplates.js
index 497cc87a07df8fb63b7087ee35edfba02ffbad64..efea68093dc4c388d88b2ed1c423b5d041fa4a39 100644
--- a/src/interaction/budgets/recordTemplates.js
+++ b/src/interaction/budgets/recordTemplates.js
@@ -211,6 +211,7 @@ App.Data.Records.LastWeeksRep = function() {
 	this.overflow = 0; // loss above 20k cap
 	this.curve = 0; // loss due to income curving
 	this.cheating = 0;
+	this.weather = 0;
 
 	this.total = 0;
 };
diff --git a/src/interaction/main/walkPast.js b/src/interaction/main/walkPast.js
index 46a7791342afb99da1ff1768328c5a63d7350693..a2070f279445d3066d91ef774071fe1f3c4b1ebc 100644
--- a/src/interaction/main/walkPast.js
+++ b/src/interaction/main/walkPast.js
@@ -2004,9 +2004,6 @@ globalThis.walkPast = (function() {
 								t += `under ${S.Schoolteacher.slaveName}, perhaps literally; `;
 							}
 							break;
-						case Job.ATTENDANT:
-							t += `look after the slaves in ${V.spaName}; `;
-							break;
 						case Job.CLASSES:
 							t += `attend classes with ${V.assistant.name}; `;
 							break;
diff --git a/src/interaction/prostheticConfig.js b/src/interaction/prostheticConfig.js
index 9a64ec644b246b8b9dc56fb3a13121a187343c6b..1d6c2bbd6ac4df648e7852cb52bf13e11d6d171e 100644
--- a/src/interaction/prostheticConfig.js
+++ b/src/interaction/prostheticConfig.js
@@ -482,7 +482,7 @@ App.UI.prostheticsConfig = function(slave) {
 	}
 
 	/**
-	 * @param {string} prosthetic
+	 * @param {FC.prostheticID} prosthetic
 	 * @param {HTMLDivElement} container
 	 */
 	function addBuyRow(prosthetic, container) {
diff --git a/src/interaction/siModify.js b/src/interaction/siModify.js
index e95089968f71eaeb21ed77f932be72f84e8c4b96..0a31e1530fdf583871bd3c110e4b16ea5ee9d488 100644
--- a/src/interaction/siModify.js
+++ b/src/interaction/siModify.js
@@ -27,11 +27,7 @@ App.UI.SlaveInteract.modify = function(slave) {
 
 		makeRoomLink(p, "Auto salon", "Salon", ' Modify hair (color, length, style), nails, and even skin color.');
 
-		makeRoomLink(p, "Body mod studio", "Body Modification", ' Mark your slave with piercings, tattoos, brands or even scars.',
-			() => {
-				V.tattooChoice = undefined;
-			},
-		);
+		makeRoomLink(p, "Body mod studio", "Body Modification", ' Mark your slave with piercings, tattoos, brands or even scars.');
 
 		makeRoomLink(p, "Remote surgery", "Remote Surgery", ` Surgically modify your slave with state of the art plastic surgery and more. Alter ${his} senses, skeletal structure, organs, and even more.`);
 
diff --git a/src/interaction/siUtilities.js b/src/interaction/siUtilities.js
index 3a8bfae984fa716d7c9408a7796d7eef8156da70..9e6ceb33a1f068cb65071a0280b7126a44069dce 100644
--- a/src/interaction/siUtilities.js
+++ b/src/interaction/siUtilities.js
@@ -39,7 +39,7 @@ App.UI.SlaveInteract.placeInLine = function(slave) {
  * @param {App.Entity.SlaveState} slave
  * @param {string} [category] - should be in the form of slave.category, the thing we want to update.
  * @param {boolean} [accessCheck=false]
- * @param {Function} refresh
+ * @param {Function} [refresh]
  * @returns {HTMLSpanElement}
  */
 App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck = false, refresh) {
@@ -74,8 +74,7 @@ App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck
 				);
 
 				if (item.FS) {
-					link.append(App.UI.DOM.spanWithTooltip(`FS`,
-						FutureSocieties.displayAdj(item.FS), "note"));
+					link.append(App.UI.DOM.spanWithTooltip(`FS`, FutureSocieties.displayAdj(item.FS), ["note"]));
 				}
 			}
 			linkArray.push(link);
diff --git a/src/js/CustomSlave.js b/src/js/CustomSlave.js
index b519a0589ef15aa964731fa0b8ca245c9a83d490..e2932758acabb46ae423bd843d6a0eb4cef33fa4 100644
--- a/src/js/CustomSlave.js
+++ b/src/js/CustomSlave.js
@@ -103,19 +103,19 @@ App.Entity.CustomSlaveOrder = class CustomSlaveOrder {
 
 		/** desired clit size, female and futa only
 		 * Values as in SlaveState.
-		 * @type {number}
+		 * @type {FC.ClitType}
 		 */
 		this.clit = 0;
 
 		/** desired labia size, female and futa only
 		 * Values as in SlaveState.
-		 * @type {number}
+		 * @type {FC.LabiaType}
 		 */
 		this.labia = 0;
 
 		/** desired vaginal lubrication, female and futa only
 		 * Values as in SlaveState.
-		 * @type {number}
+		 * @type {FC.VaginaLubeType}
 		 */
 		this.vaginaLube = 1;
 
diff --git a/src/js/birth/birth.js b/src/js/birth/birth.js
index 4f4e3b9301a6bcfce57c9cb3cc32095a5f24c53d..e8bdefc35e2ef1a3f2c03fc0850fbcb49b8155f9 100644
--- a/src/js/birth/birth.js
+++ b/src/js/birth/birth.js
@@ -2223,6 +2223,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 		cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
 		surgeryDamage(slave, 10);
 		App.Medicine.Modification.removeScar(slave, "belly", "c-section");
+		return ``;
 	}
 
 	function broodmotherBirth() {
@@ -5010,7 +5011,6 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 				}
 			}
 		} else {
-			/** @type {App.Entity.Animal[]} */
 			const animals = [];
 
 			if (V.animals.canine.length > 0) {
@@ -5023,7 +5023,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 				animals.push(V.animals.feline.random());
 			}
 
-			const animal = animals.random();
+			const animal = getAnimal(animals.random());
 
 			switch (slave.assignment) {
 				case Job.REST:
diff --git a/src/js/eventHandlers.js b/src/js/eventHandlers.js
index 521bb80790a99932e8c9cc5a1df85733d39dc7fd..35e7d270aa14b34be2632c53c2a6ebc92fdd751a 100644
--- a/src/js/eventHandlers.js
+++ b/src/js/eventHandlers.js
@@ -3,7 +3,7 @@ App.EventHandlers = function() {
 	 * @param {TwineSugarCube.SaveObject} save
 	 */
 	function onLoad(save) {
-		const v = save.state.history[0].variables;
+		const v = /** @type {FC.GameVariables} */(save.state.history[0].variables);
 		if (v.releaseID === 2000) {
 			v.releaseID = 1100;
 		}
diff --git a/src/js/itemAvailability.js b/src/js/itemAvailability.js
index 26b33ee29848229f1b0a375cdff77cacf15e2a33..a4517a60719b46108adb801f48847dbf2d659550 100644
--- a/src/js/itemAvailability.js
+++ b/src/js/itemAvailability.js
@@ -270,7 +270,7 @@ globalThis.findProsthetic = function(slave, prosthetic) {
 
 /**
  * @param {string} prosthetic
- * @returns {number}
+ * @returns {FC.LimbType}
  */
 globalThis.prostheticToLimb = function(prosthetic) {
 	switch (prosthetic) {
diff --git a/src/js/pregJS.js b/src/js/pregJS.js
index 7ef7354d4d453c3c8e4f430cbd1e655f71e30e12..b8c224087ab87f600a1563a632570cd7cc2430d7 100644
--- a/src/js/pregJS.js
+++ b/src/js/pregJS.js
@@ -17,7 +17,7 @@ globalThis.getPregBellySize = function(s) {
 };
 
 /**
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  * @returns {string}
  */
 globalThis.bellyAdjective = function(slave) {
diff --git a/src/js/storyJS.js b/src/js/storyJS.js
index c36fc5b4fd9a8a201425632fd05c64324dee2950..4659baf1e06a43e3d17649d846289658c3bd1fd4 100644
--- a/src/js/storyJS.js
+++ b/src/js/storyJS.js
@@ -389,7 +389,7 @@ globalThis.toJson = function(obj) {
 };
 
 /**
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  * @returns {string}
  */
 globalThis.nippleColor = function(slave) {
diff --git a/src/markets/theMarket/tradeMenials.js b/src/markets/theMarket/tradeMenials.js
index 276e2ea29aee3ae8eb18bc475a4b5890c6881d08..f29ed0017c2359338a57e34000f5591b4a1d0ef2 100644
--- a/src/markets/theMarket/tradeMenials.js
+++ b/src/markets/theMarket/tradeMenials.js
@@ -467,7 +467,7 @@ App.UI.tradeMenials = function(menialWorkersOnly) {
 						const value = forceNeg(menialSlaveCost(number - 100) * number);
 						V.menialBioreactors += number;
 						V.menialSupplyFactor -= number;
-						cashX(value, "bioreactorsTransfer");
+						cashX(value, "menialBioreactorsTransfer");
 						jQuery("#menial-transaction-result").empty().append(App.UI.DOM.cashFormat(value));
 					};
 
@@ -512,7 +512,7 @@ App.UI.tradeMenials = function(menialWorkersOnly) {
 					V.menialBioreactors -= number;
 					V.menialDemandFactor -= number;
 					jQuery("#menial-transaction-result").empty().append(App.UI.DOM.cashFormat(value));
-					cashX(value, "bioreactorsTransfer");
+					cashX(value, "menialBioreactorsTransfer");
 				};
 				linkArray.push(
 					App.UI.DOM.link(
diff --git a/src/npc/descriptions/belly/belly.js b/src/npc/descriptions/belly/belly.js
index 1eb9161eb2f91200429c4ee21bc32fdd1e5ddca5..7c92fa5bdfe002cdc17d44fe8acc30934c27c216 100644
--- a/src/npc/descriptions/belly/belly.js
+++ b/src/npc/descriptions/belly/belly.js
@@ -11447,7 +11447,7 @@ App.Desc.belly = function(slave, descType = DescType.NORMAL) {
 						} else {
 							r.push(`${slave.slaveName}'s huge pregnant stomach hangs out the front of ${his} suit jacket and blouse, as there is no way ${he} could close them.`);
 						}
-					} else if (slave.belly >= 10000 || (slave.bellyAccessory === "a huge empathy belly") || (slave.bellyAccessory === "a large empathy belly")) {
+					} else if (slave.belly >= 10000 || (slave.bellyAccessory === "a large empathy belly")) {
 						if (slave.bellyAccessory === "a large empathy belly") {
 							r.push(`${slave.slaveName}'s big pregnant stomach hangs out the front of ${his} suit jacket and blouse, as there is no way ${he} could close them.`);
 						} else if (isBellyFluidLargest) {
@@ -11552,7 +11552,7 @@ App.Desc.belly = function(slave, descType = DescType.NORMAL) {
 						} else {
 							r.push(`${slave.slaveName}'s huge pregnant stomach hangs out the front of ${his} specially tailored blouse and jacket as there is no way for ${him} to close them. ${His} maternity skirt fits ${him} quite well, though.`);
 						}
-					} else if (slave.belly >= 10000 || (slave.bellyAccessory === "a huge empathy belly") || (slave.bellyAccessory === "a large empathy belly")) {
+					} else if (slave.belly >= 10000 || (slave.bellyAccessory === "a large empathy belly")) {
 						if (slave.bellyAccessory === "a large empathy belly") {
 							r.push(`${slave.slaveName}'s big pregnant belly strains ${his} specially tailored blouse and jacket.`);
 						} else if (isBellyFluidLargest) {
diff --git a/src/npc/descriptions/heightImplant.js b/src/npc/descriptions/heightImplant.js
index dc3923afb8e1c0573114c1cec9c37623178e52bd..e23f74769a3f2fd7b1ff752e0799dce0b9c50cf7 100644
--- a/src/npc/descriptions/heightImplant.js
+++ b/src/npc/descriptions/heightImplant.js
@@ -57,22 +57,10 @@ App.Desc.heightImplant = function(slave) {
 	}
 
 	function isare() {
-		const d = [];
-		if (getLimbCount(slave) === 1) {
-			d.push(`is`);
-		} else {
-			d.push(`are`);
-		}
-		return d;
+		return getLimbCount(slave) === 1 ? `is` : `are`;
 	}
 
 	function ithastheyhave() {
-		const d = [];
-		if (getLimbCount(slave) === 1) {
-			d.push(`it has`);
-		} else {
-			d.push(`they have`);
-		}
-		return d;
+		return getLimbCount(slave) === 1 ? `it has` : `they have`;
 	}
 };
diff --git a/src/npc/generate/slaveGenerationJS.js b/src/npc/generate/slaveGenerationJS.js
index aea42dcc3584ad1718f4eb8d694c52b8b8abf461..524a2ddf936489e19d14f726d7f5dc97179172ac 100644
--- a/src/npc/generate/slaveGenerationJS.js
+++ b/src/npc/generate/slaveGenerationJS.js
@@ -1423,7 +1423,7 @@ globalThis.generatePuberty = function(slave) {
 
 /**
  * Apply the effects of an age lift (make them appear younger than they do currently)
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  */
 globalThis.applyAgeImplant = function(slave) {
 	if (slave.visualAge >= 25) {
@@ -1435,7 +1435,7 @@ globalThis.applyAgeImplant = function(slave) {
 
 /**
  * Makes someone appear older than they do currently
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  */
 globalThis.applyAgeImplantOlder = function(slave) {
 	if (slave.visualAge < 80) {
diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js
index 9584f33b8b09b12e6812079d89d435dd1a21c7a1..672918f827ed37c7c7a21a25e9fb2c38087b378b 100644
--- a/src/npc/startingGirls/startingGirls.js
+++ b/src/npc/startingGirls/startingGirls.js
@@ -2121,7 +2121,7 @@ App.StartingGirls.finalize = function(slave) {
 App.StartingGirls.stats = function(slave) {
 	const el = new DocumentFragment();
 	const options = new App.UI.OptionsGroup();
-	const counters = Object.keys(new App.Entity.SlaveActionsCountersState()).sort((a, b) => a.toLowerCase() > b.toLowerCase());
+	const counters = Object.keys(new App.Entity.SlaveActionsCountersState()).map(x => x.toLowerCase()).sort();
 	const titles = new Map([
 		["birthsTotal", "Total births"],
 		["laborCount", "Labor count"],
diff --git a/src/player/desc/pLongBelly.js b/src/player/desc/pLongBelly.js
index aa9dba1901e6f595565cc96d60fb45c17e993611..9d2b9d67494956b48909ed7d1b9cd1180aee73c4 100644
--- a/src/player/desc/pLongBelly.js
+++ b/src/player/desc/pLongBelly.js
@@ -1581,13 +1581,13 @@ App.Desc.Player.belly = function(PC = V.PC) {
 			} else if (PC.bellyPreg >= 750000) {
 				r.push(`While the massive pressure is arousing enough, the real pleasure are the endless vibrations caused by the minute motions of your brood. It's practically impossible to get anything done when chaining orgasm after orgasm until you risk passing out.`);
 			} else if (PC.bellyPreg >= 600000) {
-				r.push(`Between the constant movement and the pressure against your sensetive womb, it's impossible to not be constantly aroused. The quivering never ends, trapping you in a game of orgasm roulette.`);
+				r.push(`Between the constant movement and the pressure against your sensitive womb, it's impossible to not be constantly aroused. The quivering never ends, trapping you in a game of orgasm roulette.`);
 			} else if (PC.bellyPreg >= 450000) {
-				r.push(`Between the movement and the pressure against your sensetive womb, it's impossible to not be constantly aroused. Any kick can send you over the edge, and there are just so many of them…`);
+				r.push(`Between the movement and the pressure against your sensitive womb, it's impossible to not be constantly aroused. Any kick can send you over the edge, and there are just so many of them…`);
 			} else if (PC.wombImplant === "restraint" && PC.belly >= 400000) {
-				r.push(`Your womb is so full that the restraining mesh designed to support it has begun to strangle it, but thanks to your overly sensetive uterus, this feels way better than it should.`);
+				r.push(`Your womb is so full that the restraining mesh designed to support it has begun to strangle it, but thanks to your overly sensitive uterus, this feels way better than it should.`);
 			} else if (PC.bellyPreg >= 10000) {
-				r.push(`Between the movement and the pressure in your sensetive womb, you find it difficult to not be in a state of constant arousal.`);
+				r.push(`Between the movement and the pressure in your sensitive womb, you find it difficult to not be in a state of constant arousal.`);
 			}
 		} else if ((PC.dick > 0 || PC.genes === "XY") && PC.prostate > 0 && PC.preg > 0 && PC.preg > PC.pregData.normalBirth * .75) { // Do this here for dicks and males, otherwise do it in the special vagina description
 			r.push(`Not only is your bladder under constant pressure from your advanced pregnancy, but your prostate is too. Between that and your baby's movements, you find it difficult to not be in a state of constant arousal.`);
diff --git a/src/player/electiveSurgery.js b/src/player/electiveSurgery.js
index d39b69fff4a40555271c7956695687210adb7442..b0ead916ad6d2ddd4921085630c5e961d82b4dfe 100644
--- a/src/player/electiveSurgery.js
+++ b/src/player/electiveSurgery.js
@@ -76,7 +76,7 @@ App.UI.electiveSurgery = function() {
 	nurse.hColor = "black";
 	nurse.eye.left.iris = "brown";
 	nurse.eye.right.iris = "brown";
-	if (arcology.FSFSIntellectualDependency !== "unset") {
+	if (arcology.FSIntellectualDependency !== "unset") {
 		nurse.clothes = "a slutty nurse outfit";
 	} else {
 		nurse.clothes = "a nice nurse outfit";
diff --git a/src/player/js/PlayerState.js b/src/player/js/PlayerState.js
index 7cc3d7a9012fdf25e9b13d9aa7e2ffa7765ee933..7136ca0a315b1e27423a3597ed7aec7df5d6a57f 100644
--- a/src/player/js/PlayerState.js
+++ b/src/player/js/PlayerState.js
@@ -556,6 +556,7 @@ App.Entity.PlayerState = class PlayerState {
 		 * * 1: basic interface
 		 * * 2: advanced interface
 		 * * 3: quadruped interface
+		 * @type {0 | 1 | 2 | 3}
 		 */
 		this.PLimb = 0;
 		/**
@@ -1377,6 +1378,7 @@ App.Entity.PlayerState = class PlayerState {
 		 * may accept strings, use at own risk
 		 * * "none"
 		 * * "flats"
+		 * @type {FC.WithNone<FC.Shoes>}
 		 */
 		this.shoes = "none";
 		/**
@@ -1998,7 +2000,9 @@ App.Entity.PlayerState = class PlayerState {
 			 flavoring: 0
 		 };
 		/** flavor of their milk*/
-		 this.milkFlavor = "none";
+		this.milkFlavor = "none";
+		/* eslint-disable camelcase*/
+		this.NCSyouthening = 0;
 		/** erratic weight gain
 		 *
 		 * 0: stable; 1: gaining; -1: losing */
diff --git a/src/player/js/enslavePlayer.js b/src/player/js/enslavePlayer.js
index 173e62009054e598c10f2dd568a2b9c68b885840..2c7aa5b287b40e181684118cca1b537d80874c40 100644
--- a/src/player/js/enslavePlayer.js
+++ b/src/player/js/enslavePlayer.js
@@ -128,9 +128,7 @@ globalThis.convertPlayerToSlave = function(player, badEnd = "boring") {
 	delete slave.refreshmentType;
 	delete slave.rumor;
 	delete slave.physicalImpairment;
-	delete slave.fertDrugs;
 	delete slave.forcedFertDrugs;
-	delete slave.staminaPills;
 
 	/* badEnd will be used here to apply unique effects depending on the ending */
 
diff --git a/src/player/managePersonalAffairs.js b/src/player/managePersonalAffairs.js
index 3e628bbd5c7effeb14e07fe44d0571ed07865a00..3056d1f91c54b82b86c634c9b8a02512a935e473 100644
--- a/src/player/managePersonalAffairs.js
+++ b/src/player/managePersonalAffairs.js
@@ -404,8 +404,6 @@ App.UI.managePersonalAffairs = function() {
 				links.push(
 					App.UI.DOM.link(`Start taking birth control`, () => {
 						V.PC.preg = -1;
-						V.PC.fertDrugs = 0;
-
 						App.UI.DOM.replace(pregnancyDiv, pregnancy);
 					}),
 					App.UI.DOM.disabledLink(`Stop taking birth control`, [