diff --git a/css/gui/tooltips/tippy.css b/css/gui/tooltips/tippy.css
index 0025e60e0503ff55ccc7f55dbe171352cc5ddb24..666b85948865439d0447b0270d0322879000a552 100644
--- a/css/gui/tooltips/tippy.css
+++ b/css/gui/tooltips/tippy.css
@@ -3,6 +3,14 @@
 	white-space: nowrap;
 }
 
+/* Fix links */
+a.has-tooltip {
+	text-decoration: none;
+}
+a.has-tooltip:hover {
+	text-decoration: underline;
+}
+
 .tippy-content {
 	text-indent: initial;
 	font-weight: initial;
diff --git a/devTools/types/FC/gameState.d.ts b/devTools/types/FC/gameState.d.ts
index 53338f89c27c7ec8801427a3840c66c5e78fc29c..1f8e04625aa09294b95d587bcd800f33db544ced 100644
--- a/devTools/types/FC/gameState.d.ts
+++ b/devTools/types/FC/gameState.d.ts
@@ -151,6 +151,7 @@ declare namespace FC {
 
 		heroSlaves: SlaveTemplate[];
 		endweekFlag?: boolean;
+		limitedCheatStart?: Bool
 	}
 
 	export interface GameVariables extends DefaultGameStateVariables, ResetOnNGPVariables,
diff --git a/js/003-data/clothes/001-slaveWearData.js b/js/003-data/clothes/001-slaveWearData.js
index 8de9e186cfd26738c7abe82b4a606dece7a6f740..deccd8429c36529ebaeda36dd4acb85f5daae9c8 100644
--- a/js/003-data/clothes/001-slaveWearData.js
+++ b/js/003-data/clothes/001-slaveWearData.js
@@ -27,9 +27,9 @@
 /**
  * @typedef {object} clothes
  * @property {string} name
+ * @property {0|1|2|3|4} exposure 0: Modest, 1: Acceptable, 2: Slutty, 3: Humiliating (exposes genitals), 4: Might as well be nude
  * @property {itemFS} [fs]
  * @property {boolean} [requirements]
- * @property {0|1|2|3|4} [exposure] 0: Modest, 1: Acceptable, 2: Slutty, 3: Humiliating (exposes genitals), 4: Might as well be nude
  * @property {boolean} [harsh]
  * @property {boolean} [topless]
  * @property {boolean} [fuckdoll]
@@ -1147,13 +1147,22 @@ App.Data.slaveWear = {
 
 	dickAccessory: new Map([
 		["none", {name: "None"}],
-		["bullet vibrator", {name: "Bullet vibrator"}],
+		["bullet vibrator",
+			{
+				name: "Bullet vibrator",
+				get requirements() {
+					return V.boughtItem.toys.dildos === 1;
+				},
+				vibrates: 1,
+			}
+		],
 		["smart bullet vibrator",
 			{
 				name: "Smart bullet vibrator",
 				get requirements() {
 					return V.boughtItem.toys.smartVibes === 1;
-				}
+				},
+				vibrates: 2,
 			}
 		]
 	]),
diff --git a/js/rulesAssistant/conditionEditorTree.js b/js/rulesAssistant/conditionEditorTree.js
index 84862bc625ff722dcc2e007f94226540f7ac4558..73013e1d588e348639f5b73eace43668653159b9 100644
--- a/js/rulesAssistant/conditionEditorTree.js
+++ b/js/rulesAssistant/conditionEditorTree.js
@@ -73,7 +73,6 @@ App.RA.Activation.TreeEditor = (function() {
 		} else {
 			ruleDiv.append("Condition saved.");
 		}
-		ruleDiv.append(" ", App.Encyclopedia.link("Help", "RA Condition Editor"));
 		ruleDiv.append(currentRule.render());
 		outerDiv.append(ruleDiv);
 
diff --git a/js/rulesAssistant/z1-conditionEditorController.js b/js/rulesAssistant/z1-conditionEditorController.js
index a45aa13f4624221969686df21c0af27483cf14bb..275da0fce67044ea6ef1ba40ddfa7c9a0f276cf9 100644
--- a/js/rulesAssistant/z1-conditionEditorController.js
+++ b/js/rulesAssistant/z1-conditionEditorController.js
@@ -26,8 +26,10 @@ App.RA.Activation.Editor = (function() {
 	function fillOuterNode(args) {
 		advanced = args.advancedMode;
 		let editorNode = document.createElement("div");
+		let switchNode = document.createElement("div");
+		outerNode.append(switchNode);
 		if (advanced) {
-			outerNode.append(App.UI.DOM.link("Reset to simple mode", () => {
+			switchNode.append(App.UI.DOM.link("Reset to simple mode", () => {
 				if (SugarCube.Dialog.isOpen()) {
 					SugarCube.Dialog.close();
 				}
@@ -48,13 +50,14 @@ App.RA.Activation.Editor = (function() {
 			}));
 			App.RA.Activation.TreeEditor.build(args.activation, editorNode);
 		} else {
-			outerNode.append(App.UI.DOM.link("Switch to advanced mode", () => {
+			switchNode.append(App.UI.DOM.link("Switch to advanced mode", () => {
 				args.advancedMode = true;
 				$(outerNode).empty();
 				fillOuterNode(args);
 			}));
 			App.RA.Activation.SimpleEditor.build(args.activation, editorNode);
 		}
+		switchNode.append(" / ", App.Encyclopedia.link("Help", "RA Condition Editor"));
 		outerNode.append(editorNode);
 	}
 
diff --git a/src/data/backwardsCompatibility/datatypeCleanup.js b/src/data/backwardsCompatibility/datatypeCleanup.js
index eb155928a0f0d97565feabf185eb828255034371..6c457b108f7164fc74e520e0aad5818af3171049 100644
--- a/src/data/backwardsCompatibility/datatypeCleanup.js
+++ b/src/data/backwardsCompatibility/datatypeCleanup.js
@@ -249,6 +249,10 @@ App.Entity.Utils.SlaveDataSchemeCleanup = (function() {
 				hairVector: "customHairVector"
 			});
 		}
+
+		if (!slave.custom.hasOwnProperty("name")) {
+			slave.custom.name = "";
+		}
 	}
 
 	/**
diff --git a/src/events/intro/acquisition.js b/src/events/intro/acquisition.js
index 3c17f8154e88cc5cfbfb43806055319129234f7a..d101e80d46372baba212e1b767b994beddc4bd9b 100644
--- a/src/events/intro/acquisition.js
+++ b/src/events/intro/acquisition.js
@@ -25,6 +25,8 @@ App.Intro.acquisition = function() {
 	V.targetAgeNursery = V.minimumSlaveAge;
 	resetFamilyCounters();
 
+	delete V.limitedCheatStart;
+
 	App.UI.DOM.appendNewElement("p", el, "You've done it.");
 	App.UI.DOM.appendNewElement("p", el, `You arrive at your new arcology, ${V.arcologies[0].name}, and head straight to the penthouse to enter the access codes that will tell the ${V.arcologies[0].name} systems to recognize you as their owner. The penthouse office is ready to receive the codes, and they authenticate. A voice activates in your earpiece.`);
 	App.UI.DOM.appendNewElement("p", el, `Congratulations. I am a personal assistant program, and it is my pleasure to assist you, ${PlayerName()} the new owner of ${V.arcologies[0].name}. I will offer useful information whenever possible in italics. Your new arcology has some unusual equipment. The previous owner kept a small stable of sex slaves. The penthouse therefore has a body modification studio for tattooing, bleaching and piercing, and an auto salon for more prosaic things like hair care. It also has a remote surgery, a small surgical theater that can be operated remotely by a qualified surgeon if you can pay the fee. Finally, it has a slave nutrition system connected to the arcology's hydroponics bays. This system produces a tasty protein-rich drink that provides the physically active female body all its necessary nutrients while leaving the lower digestive tract extremely clean. It even causes a mild increase in sex drive.`, ["note"]);
diff --git a/src/events/intro/introSummary.js b/src/events/intro/introSummary.js
index 6b2623414ee599a963a25aeed0f087a7c342626a..b4e33818e101639220a3e459711d8ad3cf9e8f9d 100644
--- a/src/events/intro/introSummary.js
+++ b/src/events/intro/introSummary.js
@@ -57,468 +57,7 @@ App.Intro.summary = function() {
 			App.UI.DOM.link(
 				"Continue",
 				() => {
-					if (V.freshPC === 1 || V.saveImported === 0) {
-						switch (V.PC.career) {
-							case "arcology owner":
-								V.PC.skill.trading = 100;
-								V.PC.skill.warfare = 100;
-								V.PC.skill.hacking = 100;
-								V.PC.skill.slaving = 100;
-								V.PC.skill.engineering = 100;
-								V.PC.skill.medicine = 100;
-								V.PC.skill.combat = 100;
-								break;
-							case "wealth":
-								if (V.PC.vagina === 1) {
-									V.PC.vagina = 2;
-								}
-								V.PC.weight = 60;
-								V.PC.muscles = 0;
-								break;
-							case "trust fund":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.warfare = -50;
-								V.PC.skill.slaving = -50;
-								V.PC.skill.engineering = -50;
-								V.PC.skill.medicine = -50;
-								V.PC.weight = 60;
-								V.PC.muscles = 0;
-								break;
-							case "rich kid":
-								V.PC.intelligenceImplant = 5;
-								V.PC.skill.trading = -25;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -25;
-								V.PC.weight = 60;
-								V.PC.muscles = 0;
-								break;
-							case "capitalist":
-								V.PC.skill.trading = 100;
-								V.PC.muscles = 0;
-								break;
-							case "entrepreneur":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = 50;
-								V.PC.skill.warfare = -25;
-								V.PC.skill.slaving = -25;
-								V.PC.skill.engineering = -25;
-								V.PC.skill.medicine = -25;
-								V.PC.muscles = 0;
-								break;
-							case "business kid":
-								V.PC.intelligenceImplant = 5;
-								V.PC.skill.warfare = -80;
-								V.PC.skill.slaving = -80;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -20;
-								V.PC.muscles = 0;
-								break;
-							case "mercenary":
-								V.PC.skill.warfare = 100;
-								V.PC.skill.combat = 70;
-								V.PC.muscles = 50;
-								break;
-							case "recruit":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = -25;
-								V.PC.skill.warfare = 50;
-								V.PC.skill.slaving = -25;
-								V.PC.skill.engineering = -25;
-								V.PC.skill.medicine = -25;
-								V.PC.skill.combat = 50;
-								V.PC.muscles = 40;
-								break;
-							case "child soldier":
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.trading = -100;
-								V.PC.skill.slaving = -80;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -80;
-								V.PC.skill.combat = 30;
-								break;
-							case "slaver":
-								V.PC.skill.slaving = 100;
-								V.PC.skill.combat = 50;
-								V.PC.muscles = 50;
-								break;
-							case "slave overseer":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = -20;
-								V.PC.skill.warfare = -20;
-								V.PC.skill.slaving = 50;
-								V.PC.skill.engineering = -25;
-								V.PC.skill.medicine = -20;
-								V.PC.skill.combat = 30;
-								V.PC.muscles = 50;
-								break;
-							case "slave tender":
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.trading = -100;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -60;
-								V.PC.skill.hacking = -100;
-								V.PC.muscles = 10;
-								break;
-							case "engineer":
-								V.PC.skill.engineering = 100;
-								break;
-							case "construction":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = -25;
-								V.PC.skill.warfare = -50;
-								V.PC.skill.slaving = -25;
-								V.PC.skill.engineering = 50;
-								V.PC.skill.medicine = -25;
-								V.PC.skill.hacking = -20;
-								V.PC.muscles = 50;
-								break;
-							case "worksite helper":
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.trading = -80;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = 0;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -100;
-								break;
-							case "medicine":
-								V.PC.skill.medicine = 100;
-								V.PC.muscles = 0;
-								V.consumerDrugs = 1;
-								break;
-							case "medical assistant":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = -25;
-								V.PC.skill.warfare = -50;
-								V.PC.skill.slaving = -25;
-								V.PC.skill.engineering = -25;
-								V.PC.skill.medicine = 50;
-								V.PC.skill.hacking = -20;
-								V.PC.muscles = 0;
-								break;
-							case "nurse":
-								V.PC.intelligenceImplant = 5;
-								V.PC.skill.trading = -100;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.hacking = -20;
-								V.PC.muscles = 0;
-								break;
-							case "celebrity":
-								if (V.PC.vagina === 1) {
-									V.PC.vagina = 2;
-								}
-								V.PC.muscles = -20;
-								break;
-							case "rising star":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = -50;
-								V.PC.skill.warfare = -50;
-								V.PC.skill.slaving = -50;
-								V.PC.skill.engineering = -50;
-								V.PC.skill.medicine = -50;
-								V.PC.muscles = -20;
-								break;
-							case "child star":
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.trading = -100;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -20;
-								V.PC.muscles = 0;
-								break;
-							case "BlackHat":
-								V.PC.skill.hacking = 100;
-								V.PC.muscles = -20;
-								break;
-							case "hacker":
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = -50;
-								V.PC.skill.warfare = -50;
-								V.PC.skill.slaving = -50;
-								V.PC.skill.engineering = -50;
-								V.PC.skill.medicine = -50;
-								V.PC.skill.hacking = 50;
-								V.PC.muscles = -20;
-								break;
-							case "script kiddy":
-								V.PC.intelligenceImplant = 5;
-								V.PC.skill.trading = -80;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -80;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = 20;
-								V.PC.muscles = -20;
-								break;
-							case "escort":
-								if (V.PC.vagina >= 0) {
-									V.PC.vagina = 4;
-								}
-								V.PC.anus = 1;
-								V.PC.clothes = "a slutty outfit";
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = 50;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = 10;
-								V.PC.skill.hacking = 10;
-								V.PC.muscles = 0;
-								break;
-							case "prostitute":
-								if (V.PC.vagina >= 0) {
-									V.PC.vagina = 3;
-								}
-								V.PC.anus = 1;
-								V.PC.clothes = "a slutty outfit";
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -50;
-								V.PC.skill.hacking = -20;
-								V.PC.muscles = 0;
-								break;
-							case "child prostitute":
-								if (V.PC.vagina >= 0) {
-									V.PC.vagina = 2;
-								}
-								V.PC.anus = 1;
-								V.PC.clothes = "a slutty outfit";
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.trading = -50;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -80;
-								V.PC.muscles = -20;
-								break;
-							case "servant":
-								V.PC.clothes = "a nice maid outfit";
-								V.PC.intelligenceImplant = 0;
-								if (V.PC.vagina >= 1) {
-									V.PC.vagina = 3;
-								}
-								if (V.PC.vagina >= 0) {
-									V.PC.geneticQuirks.fertility = 2;
-								} else {
-									V.PC.geneticQuirks.fertility = 1;
-								}
-								V.PC.skill.trading = -100;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -100;
-								V.PC.muscles = 0;
-								V.PC.digestiveSystem = "atrophied";
-								break;
-							case "handmaiden":
-								V.PC.clothes = "a nice maid outfit";
-								V.PC.intelligenceImplant = 0;
-								if (V.PC.vagina >= 1) {
-									V.PC.vagina = 3;
-								}
-								if (V.PC.vagina >= 0) {
-									V.PC.geneticQuirks.fertility = 2;
-								} else {
-									V.PC.geneticQuirks.fertility = 1;
-								}
-								V.PC.skill.trading = -100;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -100;
-								V.PC.muscles = 0;
-								V.PC.geneticQuirks.fertility = 1;
-								V.PC.digestiveSystem = "atrophied";
-								break;
-							case "child servant":
-								V.PC.clothes = "a nice maid outfit";
-								V.PC.intelligenceImplant = 0;
-								if (V.PC.vagina >= 1) {
-									V.PC.vagina = 2;
-								}
-								if (V.PC.vagina >= 0) {
-									V.PC.geneticQuirks.fertility = 2;
-								} else {
-									V.PC.geneticQuirks.fertility = 1;
-								}
-								V.PC.skill.trading = -100;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -100;
-								V.PC.muscles = 0;
-								V.PC.geneticQuirks.fertility = 1;
-								V.PC.digestiveSystem = "atrophied";
-								break;
-							case "gang":
-								if (V.PC.vagina === 1) {
-									V.PC.vagina = 2;
-								}
-								V.PC.intelligenceImplant = 15;
-								V.PC.skill.trading = 50;
-								V.PC.skill.warfare = 50;
-								V.PC.skill.slaving = 50;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.hacking = 50;
-								V.PC.skill.combat = 50;
-								V.PC.muscles = 60;
-								break;
-							case "hoodlum":
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.warfare = -20;
-								V.PC.skill.slaving = -20;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -50;
-								V.PC.skill.hacking = 0;
-								V.PC.skill.combat = 30;
-								break;
-							case "street urchin":
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.trading = -20;
-								V.PC.skill.warfare = -40;
-								V.PC.skill.slaving = -80;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -100;
-								V.PC.skill.combat = 10;
-								break;
-							case "test subject":
-								V.PC.intelligenceImplant = 0;
-								V.PC.skill.trading = -100;
-								V.PC.skill.warfare = -100;
-								V.PC.skill.slaving = -100;
-								V.PC.skill.engineering = -100;
-								V.PC.skill.medicine = -100;
-								V.PC.skill.hacking = -100;
-								V.PC.muscles = -100;
-								V.PC.boobs = 50000;
-								V.PC.lactation = 1;
-								V.PC.lactationAdaptation = 100;
-								if (V.PC.pubertyXX === 1) {
-									V.PC.pregType = 100;
-									V.PC.preg = 27;
-								} else {
-									V.PC.bellyImplant = 800000;
-								}
-								V.PC.pregAdaptation = 200;
-								V.PC.hips = 3;
-								V.PC.butt = 20;
-								V.PC.dick = 50;
-								V.PC.balls = 100;
-								V.PC.weight = 200;
-								V.PC.digestiveSystem = "atrophied";
-								break;
-						}
-						if (V.PC.rumor === "diligence") {
-							V.PC.weight = 0;
-							if (V.PC.muscles < 30) {
-								V.PC.muscles += 20;
-							}
-						} else if (V.PC.rumor === "force") {
-							V.PC.muscles += 20;
-						}
-						// I hope this works
-						PCDatatypeCleanup(V.PC);
-
-						if (V.PC.dick >= 3) {
-							V.PC.geneticQuirks.wellHung = 2;
-						}
-						if (V.PC.title === 0) {
-							V.PC.hLength = 15;
-							V.PC.waist = -20;
-							V.PC.voice = 2;
-						}
-						if (V.PC.eye.right.vision === 1 || V.PC.eye.left.vision === 1) {
-							V.PC.eyewear = "corrective glasses";
-						}
-						if (V.PC.physicalAge >= 14) {
-							if (V.PC.balls > 0) {
-								V.PC.pubertyXY = 1;
-							}
-							if (V.PC.ovaries > 0) {
-								V.PC.pubertyXX = 1;
-							}
-						}
-						if (V.PC.pubertyXX === 0 && V.PC.pubertyXY === 0) {
-							if (V.PC.physicalAge < 11) {
-								V.PC.energy = 20;
-							} else if (V.PC.physicalAge < 12) {
-								V.PC.energy = 30;
-							} else if (V.PC.physicalAge < 13) {
-								V.PC.energy = 40;
-							}
-						}
-						if (V.PC.genes === "XX") {
-							if (V.PC.ovaries === 1 && V.PC.pubertyXX > 0) {
-								if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
-									V.PC.hormoneBalance = 10;
-								} else {
-									V.PC.hormoneBalance = 50;
-								}
-							} else if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
-								V.PC.hormoneBalance = -30;
-							} else {
-								V.PC.hormoneBalance = 10;
-							}
-						} else if (V.PC.genes === "XY") {
-							if (V.PC.ovaries === 1 && V.PC.pubertyXX > 0) {
-								if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
-									V.PC.hormoneBalance = -10;
-								} else {
-									V.PC.hormoneBalance = 30;
-								}
-							} else {
-								if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
-									V.PC.hormoneBalance = -50;
-								} else {
-									V.PC.hormoneBalance = -10;
-								}
-							}
-						}
-						if (V.PC.preg > 0 && V.PC.preg > V.PC.pregData.normalBirth / 2) {
-							V.PC.lactation = 1;
-						}
-						if (V.PC.pubertyXX === 1 && V.PC.physicalAge < V.PC.pubertyAgeXX) {
-							V.PC.pubertyAgeXX = 8;
-						}
-						if (V.PC.pubertyXY === 1 && V.PC.physicalAge < V.PC.pubertyAgeXY) {
-							V.PC.pubertyAgeXY = 8;
-						}
-						V.genePool.push(clone(V.PC));
-					}
-
-					V.PC.birthName = V.PC.slaveName;
-					V.PC.birthSurname = V.PC.slaveSurname;
-
-					if (V.saveImported === 1 && V.freshPC === 0 && V.PC.rules.living !== "luxurious") {
-						if (V.PC.rules.living === "spare") {
-							V.PC.rules.living = "normal";
-						} else {
-							V.PC.rules.living = "luxurious";
-						}
-					} else if (["celebrity", "child star", "rich kid", "rising star", "trust fund", "wealth"].includes(V.PC.career)) {
-						V.PC.rules.living = "normal";
-					} else {
-						V.PC.rules.living = "spare";
-					}
-					App.Intro.initNationalities();
-					SectorCounts(); // Update AProsperityCap
+					continueNormal();
 				},
 				[],
 				"Starting Girls"
@@ -647,6 +186,18 @@ App.Intro.summary = function() {
 				"Intended for debugging: may have unexpected effects"
 			)
 		);
+		linkArray.push(
+			App.UI.DOM.link(
+				"Limited Cheat Start",
+				() => {
+					continueNormal();
+					V.limitedCheatStart = 1;
+				},
+				[],
+				"Starting Girls",
+				"Allow cheating when selecting starting slaves"
+			)
+		);
 		App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray));
 
 		return el;
@@ -791,6 +342,473 @@ App.Intro.summary = function() {
 
 		return el;
 	}
+
+
+	function continueNormal() {
+
+		if (V.freshPC === 1 || V.saveImported === 0) {
+			switch (V.PC.career) {
+				case "arcology owner":
+					V.PC.skill.trading = 100;
+					V.PC.skill.warfare = 100;
+					V.PC.skill.hacking = 100;
+					V.PC.skill.slaving = 100;
+					V.PC.skill.engineering = 100;
+					V.PC.skill.medicine = 100;
+					V.PC.skill.combat = 100;
+					break;
+				case "wealth":
+					if (V.PC.vagina === 1) {
+						V.PC.vagina = 2;
+					}
+					V.PC.weight = 60;
+					V.PC.muscles = 0;
+					break;
+				case "trust fund":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.warfare = -50;
+					V.PC.skill.slaving = -50;
+					V.PC.skill.engineering = -50;
+					V.PC.skill.medicine = -50;
+					V.PC.weight = 60;
+					V.PC.muscles = 0;
+					break;
+				case "rich kid":
+					V.PC.intelligenceImplant = 5;
+					V.PC.skill.trading = -25;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -25;
+					V.PC.weight = 60;
+					V.PC.muscles = 0;
+					break;
+				case "capitalist":
+					V.PC.skill.trading = 100;
+					V.PC.muscles = 0;
+					break;
+				case "entrepreneur":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = 50;
+					V.PC.skill.warfare = -25;
+					V.PC.skill.slaving = -25;
+					V.PC.skill.engineering = -25;
+					V.PC.skill.medicine = -25;
+					V.PC.muscles = 0;
+					break;
+				case "business kid":
+					V.PC.intelligenceImplant = 5;
+					V.PC.skill.warfare = -80;
+					V.PC.skill.slaving = -80;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -20;
+					V.PC.muscles = 0;
+					break;
+				case "mercenary":
+					V.PC.skill.warfare = 100;
+					V.PC.skill.combat = 70;
+					V.PC.muscles = 50;
+					break;
+				case "recruit":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = -25;
+					V.PC.skill.warfare = 50;
+					V.PC.skill.slaving = -25;
+					V.PC.skill.engineering = -25;
+					V.PC.skill.medicine = -25;
+					V.PC.skill.combat = 50;
+					V.PC.muscles = 40;
+					break;
+				case "child soldier":
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.trading = -100;
+					V.PC.skill.slaving = -80;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -80;
+					V.PC.skill.combat = 30;
+					break;
+				case "slaver":
+					V.PC.skill.slaving = 100;
+					V.PC.skill.combat = 50;
+					V.PC.muscles = 50;
+					break;
+				case "slave overseer":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = -20;
+					V.PC.skill.warfare = -20;
+					V.PC.skill.slaving = 50;
+					V.PC.skill.engineering = -25;
+					V.PC.skill.medicine = -20;
+					V.PC.skill.combat = 30;
+					V.PC.muscles = 50;
+					break;
+				case "slave tender":
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.trading = -100;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -60;
+					V.PC.skill.hacking = -100;
+					V.PC.muscles = 10;
+					break;
+				case "engineer":
+					V.PC.skill.engineering = 100;
+					break;
+				case "construction":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = -25;
+					V.PC.skill.warfare = -50;
+					V.PC.skill.slaving = -25;
+					V.PC.skill.engineering = 50;
+					V.PC.skill.medicine = -25;
+					V.PC.skill.hacking = -20;
+					V.PC.muscles = 50;
+					break;
+				case "worksite helper":
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.trading = -80;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = 0;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -100;
+					break;
+				case "medicine":
+					V.PC.skill.medicine = 100;
+					V.PC.muscles = 0;
+					V.consumerDrugs = 1;
+					break;
+				case "medical assistant":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = -25;
+					V.PC.skill.warfare = -50;
+					V.PC.skill.slaving = -25;
+					V.PC.skill.engineering = -25;
+					V.PC.skill.medicine = 50;
+					V.PC.skill.hacking = -20;
+					V.PC.muscles = 0;
+					break;
+				case "nurse":
+					V.PC.intelligenceImplant = 5;
+					V.PC.skill.trading = -100;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.hacking = -20;
+					V.PC.muscles = 0;
+					break;
+				case "celebrity":
+					if (V.PC.vagina === 1) {
+						V.PC.vagina = 2;
+					}
+					V.PC.muscles = -20;
+					break;
+				case "rising star":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = -50;
+					V.PC.skill.warfare = -50;
+					V.PC.skill.slaving = -50;
+					V.PC.skill.engineering = -50;
+					V.PC.skill.medicine = -50;
+					V.PC.muscles = -20;
+					break;
+				case "child star":
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.trading = -100;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -20;
+					V.PC.muscles = 0;
+					break;
+				case "BlackHat":
+					V.PC.skill.hacking = 100;
+					V.PC.muscles = -20;
+					break;
+				case "hacker":
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = -50;
+					V.PC.skill.warfare = -50;
+					V.PC.skill.slaving = -50;
+					V.PC.skill.engineering = -50;
+					V.PC.skill.medicine = -50;
+					V.PC.skill.hacking = 50;
+					V.PC.muscles = -20;
+					break;
+				case "script kiddy":
+					V.PC.intelligenceImplant = 5;
+					V.PC.skill.trading = -80;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -80;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = 20;
+					V.PC.muscles = -20;
+					break;
+				case "escort":
+					if (V.PC.vagina >= 0) {
+						V.PC.vagina = 4;
+					}
+					V.PC.anus = 1;
+					V.PC.clothes = "a slutty outfit";
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = 50;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = 10;
+					V.PC.skill.hacking = 10;
+					V.PC.muscles = 0;
+					break;
+				case "prostitute":
+					if (V.PC.vagina >= 0) {
+						V.PC.vagina = 3;
+					}
+					V.PC.anus = 1;
+					V.PC.clothes = "a slutty outfit";
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -50;
+					V.PC.skill.hacking = -20;
+					V.PC.muscles = 0;
+					break;
+				case "child prostitute":
+					if (V.PC.vagina >= 0) {
+						V.PC.vagina = 2;
+					}
+					V.PC.anus = 1;
+					V.PC.clothes = "a slutty outfit";
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.trading = -50;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -80;
+					V.PC.muscles = -20;
+					break;
+				case "servant":
+					V.PC.clothes = "a nice maid outfit";
+					V.PC.intelligenceImplant = 0;
+					if (V.PC.vagina >= 1) {
+						V.PC.vagina = 3;
+					}
+					if (V.PC.vagina >= 0) {
+						V.PC.geneticQuirks.fertility = 2;
+					} else {
+						V.PC.geneticQuirks.fertility = 1;
+					}
+					V.PC.skill.trading = -100;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -100;
+					V.PC.muscles = 0;
+					V.PC.digestiveSystem = "atrophied";
+					break;
+				case "handmaiden":
+					V.PC.clothes = "a nice maid outfit";
+					V.PC.intelligenceImplant = 0;
+					if (V.PC.vagina >= 1) {
+						V.PC.vagina = 3;
+					}
+					if (V.PC.vagina >= 0) {
+						V.PC.geneticQuirks.fertility = 2;
+					} else {
+						V.PC.geneticQuirks.fertility = 1;
+					}
+					V.PC.skill.trading = -100;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -100;
+					V.PC.muscles = 0;
+					V.PC.geneticQuirks.fertility = 1;
+					V.PC.digestiveSystem = "atrophied";
+					break;
+				case "child servant":
+					V.PC.clothes = "a nice maid outfit";
+					V.PC.intelligenceImplant = 0;
+					if (V.PC.vagina >= 1) {
+						V.PC.vagina = 2;
+					}
+					if (V.PC.vagina >= 0) {
+						V.PC.geneticQuirks.fertility = 2;
+					} else {
+						V.PC.geneticQuirks.fertility = 1;
+					}
+					V.PC.skill.trading = -100;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -100;
+					V.PC.muscles = 0;
+					V.PC.geneticQuirks.fertility = 1;
+					V.PC.digestiveSystem = "atrophied";
+					break;
+				case "gang":
+					if (V.PC.vagina === 1) {
+						V.PC.vagina = 2;
+					}
+					V.PC.intelligenceImplant = 15;
+					V.PC.skill.trading = 50;
+					V.PC.skill.warfare = 50;
+					V.PC.skill.slaving = 50;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.hacking = 50;
+					V.PC.skill.combat = 50;
+					V.PC.muscles = 60;
+					break;
+				case "hoodlum":
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.warfare = -20;
+					V.PC.skill.slaving = -20;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -50;
+					V.PC.skill.hacking = 0;
+					V.PC.skill.combat = 30;
+					break;
+				case "street urchin":
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.trading = -20;
+					V.PC.skill.warfare = -40;
+					V.PC.skill.slaving = -80;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -100;
+					V.PC.skill.combat = 10;
+					break;
+				case "test subject":
+					V.PC.intelligenceImplant = 0;
+					V.PC.skill.trading = -100;
+					V.PC.skill.warfare = -100;
+					V.PC.skill.slaving = -100;
+					V.PC.skill.engineering = -100;
+					V.PC.skill.medicine = -100;
+					V.PC.skill.hacking = -100;
+					V.PC.muscles = -100;
+					V.PC.boobs = 50000;
+					V.PC.lactation = 1;
+					V.PC.lactationAdaptation = 100;
+					if (V.PC.pubertyXX === 1) {
+						V.PC.pregType = 100;
+						V.PC.preg = 27;
+					} else {
+						V.PC.bellyImplant = 800000;
+					}
+					V.PC.pregAdaptation = 200;
+					V.PC.hips = 3;
+					V.PC.butt = 20;
+					V.PC.dick = 50;
+					V.PC.balls = 100;
+					V.PC.weight = 200;
+					V.PC.digestiveSystem = "atrophied";
+					break;
+			}
+			if (V.PC.rumor === "diligence") {
+				V.PC.weight = 0;
+				if (V.PC.muscles < 30) {
+					V.PC.muscles += 20;
+				}
+			} else if (V.PC.rumor === "force") {
+				V.PC.muscles += 20;
+			}
+			// I hope this works
+			PCDatatypeCleanup(V.PC);
+
+			if (V.PC.dick >= 3) {
+				V.PC.geneticQuirks.wellHung = 2;
+			}
+			if (V.PC.title === 0) {
+				V.PC.hLength = 15;
+				V.PC.waist = -20;
+				V.PC.voice = 2;
+			}
+			if (V.PC.eye.right.vision === 1 || V.PC.eye.left.vision === 1) {
+				V.PC.eyewear = "corrective glasses";
+			}
+			if (V.PC.physicalAge >= 14) {
+				if (V.PC.balls > 0) {
+					V.PC.pubertyXY = 1;
+				}
+				if (V.PC.ovaries > 0) {
+					V.PC.pubertyXX = 1;
+				}
+			}
+			if (V.PC.pubertyXX === 0 && V.PC.pubertyXY === 0) {
+				if (V.PC.physicalAge < 11) {
+					V.PC.energy = 20;
+				} else if (V.PC.physicalAge < 12) {
+					V.PC.energy = 30;
+				} else if (V.PC.physicalAge < 13) {
+					V.PC.energy = 40;
+				}
+			}
+			if (V.PC.genes === "XX") {
+				if (V.PC.ovaries === 1 && V.PC.pubertyXX > 0) {
+					if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
+						V.PC.hormoneBalance = 10;
+					} else {
+						V.PC.hormoneBalance = 50;
+					}
+				} else if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
+					V.PC.hormoneBalance = -30;
+				} else {
+					V.PC.hormoneBalance = 10;
+				}
+			} else if (V.PC.genes === "XY") {
+				if (V.PC.ovaries === 1 && V.PC.pubertyXX > 0) {
+					if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
+						V.PC.hormoneBalance = -10;
+					} else {
+						V.PC.hormoneBalance = 30;
+					}
+				} else {
+					if (V.PC.balls > 0 && V.PC.pubertyXY > 0) {
+						V.PC.hormoneBalance = -50;
+					} else {
+						V.PC.hormoneBalance = -10;
+					}
+				}
+			}
+			if (V.PC.preg > 0 && V.PC.preg > V.PC.pregData.normalBirth / 2) {
+				V.PC.lactation = 1;
+			}
+			if (V.PC.pubertyXX === 1 && V.PC.physicalAge < V.PC.pubertyAgeXX) {
+				V.PC.pubertyAgeXX = 8;
+			}
+			if (V.PC.pubertyXY === 1 && V.PC.physicalAge < V.PC.pubertyAgeXY) {
+				V.PC.pubertyAgeXY = 8;
+			}
+			V.genePool.push(clone(V.PC));
+		}
+
+		V.PC.birthName = V.PC.slaveName;
+		V.PC.birthSurname = V.PC.slaveSurname;
+
+		if (V.saveImported === 1 && V.freshPC === 0 && V.PC.rules.living !== "luxurious") {
+			if (V.PC.rules.living === "spare") {
+				V.PC.rules.living = "normal";
+			} else {
+				V.PC.rules.living = "luxurious";
+			}
+		} else if (["celebrity", "child star", "rich kid", "rising star", "trust fund", "wealth"].includes(V.PC.career)) {
+			V.PC.rules.living = "normal";
+		} else {
+			V.PC.rules.living = "spare";
+		}
+		App.Intro.initNationalities();
+		SectorCounts(); // Update AProsperityCap
+	}
 };
 /**
  * @param {boolean} isIntro
diff --git a/src/gui/Encyclopedia/encyclopediaRAActivationEditor.js b/src/gui/Encyclopedia/encyclopediaRAActivationEditor.js
index 6347e8031d5b2a1d93336bb8f52cdd6c80913738..c1c0f27e0671298c3b51f7d9f49f834160f06e09 100644
--- a/src/gui/Encyclopedia/encyclopediaRAActivationEditor.js
+++ b/src/gui/Encyclopedia/encyclopediaRAActivationEditor.js
@@ -80,6 +80,9 @@ App.Encyclopedia.addArticle("RA Condition Editor", function() {
 
 	const acc = new SpacedTextAccumulator();
 
+	acc.push("<span class='bold'>Note:</span> For the simple mode only the section <span class='bold'>Data getters</span> is relevant.");
+	acc.toParagraph();
+
 	acc.push("Rule conditions consist of two types of elements, data getters and data transformers. Data getters can " +
 		"read out values from various places, which can then be used to base conditions on. Data transformers " +
 		"take one or more elements as input and transform the input values into a single new value. Together they " +
@@ -128,16 +131,20 @@ App.Encyclopedia.addArticle("RA Condition Editor", function() {
 
 	App.UI.DOM.appendNewElement("h3", c, "Custom getters");
 	acc.push("If greater freedom is required for the conditions needed, a custom data getter can be used.",
-		"It operates on a context object with the following properties: slave: The slave currently tested against.",
-		"It is required to explicitly set the return type. If the set type does not match the actual return type, " +
-		"the condition evaluation will fail!");
+		"It operates on a context object with the following properties:",
+		"<ul>",
+		"<li>slave: The slave currently tested against.</li>",
+		"</ul>",
+		"It is required to explicitly set the return type. If the set type does not match the actual return type, the condition evaluation will fail!");
 	acc.toParagraph();
 	acc.push("For example to get the slave name you can use");
 	acc.push(App.UI.DOM.makeElement("span", "context => context.slave.slaveName", ["monospace"]));
 	acc.push("and set the getter type to string.");
 	acc.toParagraph();
-	acc.push("Documentation for slave attributes can be found " +
-		"<a target='_blank' class='link-external' href='https://gitgud.io/pregmodfan/fc-pregmod/-/raw/pregmod-master/devNotes/legacy files/slave%20variables%20documentation.md'>here.</a>");
+	acc.push("Documentation for slave attributes can be found",
+		"<a target='_blank' class='link-external' href='https://gitgud.io/pregmodfan/fc-pregmod/-/raw/pregmod-master/devNotes/legacy files/slave%20variables%20documentation.md'>here.</a>",
+		"Alternatively you can look up the properties needed in the", "" +
+		"<a target='_blank' class='link-external' href='https://gitgud.io/pregmodfan/fc-pregmod/-/blob/pregmod-master/src/js/SlaveState.js'>actual definitions.</a>");
 	acc.toParagraph();
 
 	return acc.container();
diff --git a/src/gui/storyCaption.js b/src/gui/storyCaption.js
index 44219b7640a4133c1b451e77eea7e43e2ad0c242..60b633c15646395dfb9bee25c57533898e45196f 100644
--- a/src/gui/storyCaption.js
+++ b/src/gui/storyCaption.js
@@ -504,24 +504,38 @@ App.UI.storyCaption = function() {
 	}
 
 	function startingGirls() {
+		const f = new DocumentFragment();
+
 		// @ts-ignore // In starting girls we know that there is always an active slave
 		let cost = startingSlaveCost(V.activeSlave);
-		const p = document.createElement("p");
-
+		let p = document.createElement("p");
 		if (cost > V.cash) {
 			const div = document.createElement("div");
 			div.classList.add("cash", "dec");
 			div.append("This slave will cost ",
-				App.UI.DOM.makeElement("span", cashFormat(cost), ["bold"]), ".",
-				App.UI.DOM.makeElement("div", `You only have: ${cashFormat(V.cash)}.`));
+				App.UI.DOM.makeElement("span", cashFormat(cost), ["bold"]), ".");
 			p.append(div);
+
+			App.UI.DOM.appendNewElement("div", p, `You only have: ${cashFormat(V.cash)}.`);
 		} else {
 			const div = document.createElement("div");
 			div.append("This slave will cost ",
-				App.UI.DOM.makeElement("span", cashFormat(cost), ["cash"]), ".",
-				App.UI.DOM.makeElement("div", `You have ${cashFormat(V.cash)}.`));
+				App.UI.DOM.makeElement("span", cashFormat(cost), ["cash"]), ".");
 			p.append(div);
+
+			App.UI.DOM.appendNewElement("div", p, `You have ${cashFormat(V.cash)}.`);
 		}
-		return p;
+		f.append(p);
+
+		if (V.limitedCheatStart) {
+			p = document.createElement("p");
+			p.append("Edit cash: ", App.UI.DOM.makeTextBox(V.cash, cash => {
+				cashX(cash - V.cash, "cheating");
+				App.UI.reload();
+			}, true));
+			f.append(p);
+		}
+
+		return f;
 	}
 };
diff --git a/src/interaction/siCustom.js b/src/interaction/siCustom.js
index f28b71fe58d8d13c48802c26af89fe93d62561fc..71418245b010b8bf09fbaea3c431c9c2a7e1e8ad 100644
--- a/src/interaction/siCustom.js
+++ b/src/interaction/siCustom.js
@@ -33,6 +33,7 @@ App.UI.SlaveInteract.custom = function(slave, refresh) {
 		customTattoo(),
 		customOriginStory(),
 		customDescription(),
+		customSlaveTitle(),
 		customLabel()
 	);
 
@@ -86,10 +87,8 @@ App.UI.SlaveInteract.custom = function(slave, refresh) {
 						"",
 						v => {
 							slave.custom.title = v;
-							jQuery('#result').empty().append(
-								document.createTextNode(`${He}'ll try ${his} best to call you ${slave.custom.title}.`)
-							);
 							slave.custom.titleLisp = lispReplace(slave.custom.title);
+							refresh();
 						}
 					)
 				);
@@ -100,10 +99,8 @@ App.UI.SlaveInteract.custom = function(slave, refresh) {
 						slave.custom.title,
 						v => {
 							slave.custom.title = v;
-							jQuery('#result').empty().append(
-								document.createTextNode(`${He}'ll try ${his} best to call you ${slave.custom.title}.`)
-							);
 							slave.custom.titleLisp = lispReplace(slave.custom.title);
+							refresh();
 						}
 					)
 				);
@@ -111,11 +108,9 @@ App.UI.SlaveInteract.custom = function(slave, refresh) {
 					App.UI.DOM.link(
 						` Stop using a custom title`,
 						() => {
-							jQuery('#result').empty().append(
-								document.createTextNode(`${He} will no longer refer to you with a special title.`)
-							);
 							slave.custom.title = "";
 							slave.custom.titleLisp = "";
+							refresh();
 						}
 					)
 				);
@@ -641,6 +636,26 @@ App.UI.SlaveInteract.custom = function(slave, refresh) {
 		return el;
 	}
 
+	function customSlaveTitle() {
+		let el = document.createElement('p');
+		el.append(`Change ${his} custom slave title: `);
+		el.appendChild(
+			App.UI.DOM.makeTextBox(slave.custom.name,
+				v => {
+					slave.custom.name = v;
+					refresh();
+				}
+			)
+		);
+
+		let choices = document.createElement('div');
+		choices.className = "choices";
+		choices.appendChild(App.UI.DOM.makeElement('span', ` For best results, should fit into a sentence like: '${SlaveFullName(slave)} is a "slave title"'`, 'note'));
+		el.appendChild(choices);
+
+		return el;
+	}
+
 	function customLabel() {
 		let el = document.createElement('p');
 		el.append(`Change ${his} custom label: `);
diff --git a/src/interaction/siWardrobe.js b/src/interaction/siWardrobe.js
index 59e81ea3c8a644f3ee184e4bdfab9f33dfd63ddf..e4d54164b52e2a84cccf59e14ab9ca188d1fe4dd 100644
--- a/src/interaction/siWardrobe.js
+++ b/src/interaction/siWardrobe.js
@@ -60,21 +60,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 			[false, "Nice"],
 			[true, "Harsh"],
 		]);
-		let span = document.createElement("span");
-		span.classList.add("button-group");
-		for (const [bool, string] of niceFilters) {
-			const button = App.UI.DOM.makeElement("button", string);
-			if (T.filters.harsh === bool) {
-				button.classList.add("selected", "disabled");
-			} else {
-				button.onclick = () => {
-					T.filters.harsh = bool;
-					refresh();
-				};
-			}
-			span.append(button);
-		}
-		el.append(span);
+		el.append(filterButtons(niceFilters, "harsh"));
 
 		const exposureFilters = new Map([
 			[0, "Modest"],
@@ -83,21 +69,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 			[3, "Humiliating"],
 			[4, "Practically nude"],
 		]);
-		span = document.createElement("span");
-		span.classList.add("button-group");
-		for (const [num, string] of exposureFilters) {
-			const button = App.UI.DOM.makeElement("button", string);
-			if (T.filters.exposure === num) {
-				button.classList.add("selected", "disabled");
-			} else {
-				button.onclick = () => {
-					T.filters.exposure = num;
-					refresh();
-				};
-			}
-			span.append(button);
-		}
-		el.append(span);
+		el.append(filterButtons(exposureFilters, "exposure"));
 
 		const FSFilters = new Map([]);
 		for (const FS of App.Data.FutureSociety.fsNames) {
@@ -105,30 +77,39 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 				FSFilters.set(FS, App.Data.FutureSociety.records[FS].noun);
 			}
 		}
-		span = document.createElement("span");
+		el.append(filterButtons(FSFilters, "FSLoves"));
+
+		// clear filters
+		const resetButton = App.UI.DOM.makeElement("button", "Reset Filters");
+		resetButton.onclick = () => {
+			T.filters = {};
+			refresh();
+		};
+		App.UI.DOM.appendNewElement("span", el, resetButton, "button-group");
+		return el;
+	}
+
+	/**
+	 * @param {Map<number|boolean, string>} filters
+	 * @param {string} filterKey
+	 * @returns {HTMLSpanElement}
+	 */
+	function filterButtons(filters, filterKey) {
+		let span = document.createElement("span");
 		span.classList.add("button-group");
-		for (const [num, string] of FSFilters) {
+		for (const [num, string] of filters) {
 			const button = App.UI.DOM.makeElement("button", string);
-			if (T.filters.FSLoves === num) {
+			if (T.filters[filterKey] === num) {
 				button.classList.add("selected", "disabled");
 			} else {
 				button.onclick = () => {
-					T.filters.FSLoves = num;
+					T.filters[filterKey] = num;
 					refresh();
 				};
 			}
 			span.append(button);
 		}
-		el.append(span);
-
-		// clear filters
-		const resetButton = App.UI.DOM.makeElement("button", "Reset Filters");
-		resetButton.onclick = () => {
-			T.filters = {};
-			refresh();
-		};
-		App.UI.DOM.appendNewElement("span", el, resetButton, "button-group");
-		return el;
+		return span;
 	}
 
 	function chooseHerOwn() {
@@ -193,7 +174,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		label.append(`Collar: `, App.UI.DOM.spanWithTooltip(slave.collar, itemTooltip(slave.collar, "collar"), ["bold"]));
 		// Choose her own
 		if (slave.collar !== `none`) {
-			label.append(noneLink("collar"));
+			label.append(" ", noneLink("collar"));
 		}
 		clothingDiv.appendChild(label);
 
@@ -273,7 +254,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 		// Choose her own
 		if (slave.faceAccessory !== `none`) {
-			label.append(noneLink("faceAccessory"));
+			label.append(" ", noneLink("faceAccessory"));
 		}
 
 		el.appendChild(label);
@@ -316,7 +297,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 		// Choose her own
 		if (slave.mouthAccessory !== `none`) {
-			label.append(noneLink("mouthAccessory"));
+			label.append(" ", noneLink("mouthAccessory"));
 		}
 
 		el.appendChild(label);
@@ -347,7 +328,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 		// Choose her own
 		if (slave.armAccessory !== "none") {
-			label.append(noneLink("armAccessory"));
+			label.append(" ", noneLink("armAccessory"));
 		}
 
 		el.appendChild(label);
@@ -407,7 +388,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 		// Choose her own
 		if (slave.legAccessory !== "none") {
-			label.append(noneLink("legAccessory"));
+			label.append(" ", noneLink("legAccessory"));
 		}
 
 		App.UI.DOM.appendNewElement("div", el, generateRows(App.Data.slaveWear.legAccessory, "legAccessory", false), "choices");
@@ -444,7 +425,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 		// Choose her own
 		if (slave.bellyAccessory !== `none`) {
-			label.append(noneLink("bellyAccessory"));
+			label.append(" ", noneLink("bellyAccessory"));
 		}
 
 		// Options
@@ -475,7 +456,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		label.append(`Anal accessory: `, App.UI.DOM.spanWithTooltip(slave.buttplug, itemTooltip(slave.buttplug, "buttplug"), ["bold"]));
 
 		if (slave.buttplug !== `none`) {
-			label.append(noneLink("buttplug"));
+			label.append(" ", noneLink("buttplug"));
 		}
 		el.appendChild(label);
 
@@ -518,42 +499,20 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 	}
 
 	function buttplugAttachment() {
-		const el = document.createElement('div');
 		if (slave.buttplug === "none") {
-			return el;
+			return new DocumentFragment();
 		}
 
+		const el = document.createElement('div');
+
 		const label = document.createElement('div');
 		label.append(`Anal accessory attachment: `, App.UI.DOM.spanWithTooltip(slave.buttplugAttachment, itemTooltip(slave.buttplugAttachment, "buttplugAttachment"), ["bold"]));
-
 		if (slave.buttplugAttachment !== `none`) {
-			label.append(noneLink("buttplugAttachment"));
+			label.append(" ", noneLink("buttplugAttachment"));
 		}
 		el.appendChild(label);
 
-		let array = [];
-
-		for (const key of App.Data.slaveWear.buttplugAttachment.keys()) {
-			if (key === "none") {
-				// skip none in set, we set the link elsewhere.
-				continue;
-			}
-			array.push(key);
-		}
-
-		// Sort
-		array = array.sort((a, b) => (a > b) ? 1 : -1);
-		const sortedMap = new Map([]);
-		for (const name of array) {
-			sortedMap.set(name, App.Data.slaveWear.buttplugAttachment.get(name));
-		}
-
-		// Options
-		let links = document.createElement('div');
-		links.className = "choices";
-		links.appendChild(generateRows(sortedMap, "buttplugAttachment", true));
-		el.appendChild(links);
-
+		el.append(lowerAttachmentList(App.Data.slaveWear.buttplugAttachment, "buttplugAttachment"));
 		return el;
 	}
 
@@ -564,7 +523,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		label.append(`Vaginal accessory: `, App.UI.DOM.spanWithTooltip(slave.vaginalAccessory, itemTooltip(slave.vaginalAccessory, "vaginalAccessory"), ["bold"]));
 
 		if (slave.vaginalAccessory !== `none`) {
-			label.append(noneLink("vaginalAccessory"));
+			label.append(" ", noneLink("vaginalAccessory"));
 		}
 		el.appendChild(label);
 
@@ -614,43 +573,22 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 	}
 
 	function vaginalAttachment() {
-		let el = document.createElement('div');
+		// TODO: This check should occur when setting the accessory
 		if (dildoWidth(slave) === 0) {
 			slave.vaginalAttachment = "none";
-			return el;
+			return new DocumentFragment();
 		}
 
-		let label = App.UI.DOM.appendNewElement("div", el, `Vaginal accessory attachment: `);
-
-		label.append(App.UI.DOM.spanWithTooltip(slave.vaginalAttachment, itemTooltip(slave.vaginalAttachment, "vaginalAttachment"), ["bold"]));
+		let el = document.createElement('div');
+		const label = document.createElement('div');
+		label.append(`Vaginal accessory attachment: `, App.UI.DOM.spanWithTooltip(slave.vaginalAttachment, itemTooltip(slave.vaginalAttachment, "vaginalAttachment"), ["bold"]));
 
 		if (slave.vaginalAttachment !== `none`) {
-			label.append(noneLink("vaginalAttachment"));
-		}
-
-		let array = [];
-
-		for (const key of App.Data.slaveWear.vaginalAttachment.keys()) {
-			if (key === "none") {
-				// skip none in set, we set the link elsewhere.
-				continue;
-			}
-			array.push(key);
-		}
-
-		// Sort
-		array = array.sort((a, b) => (a > b) ? 1 : -1);
-		const sortedMap = new Map([]);
-		for (const name of array) {
-			sortedMap.set(name, App.Data.slaveWear.vaginalAttachment.get(name));
+			label.append(" ", noneLink("vaginalAttachment"));
 		}
+		el.append(label);
 
-		// Options
-		let links = document.createElement('div');
-		links.className = "choices";
-		links.appendChild(generateRows(sortedMap, "vaginalAttachment", true));
-		el.appendChild(links);
-
+		el.append(lowerAttachmentList(App.Data.slaveWear.vaginalAttachment, "vaginalAttachment"));
 		return el;
 	}
 
@@ -661,34 +599,41 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		label.append(`Dick accessory: `, App.UI.DOM.spanWithTooltip(slave.dickAccessory, itemTooltip(slave.dickAccessory, "dickAccessory"), ["bold"]));
 
 		if (slave.dickAccessory !== `none`) {
-			label.append(noneLink("dickAccessory"));
+			label.append(" ", noneLink("dickAccessory"));
 		}
 		el.appendChild(label);
 
-		let array = [];
+		el.append(lowerAttachmentList(App.Data.slaveWear.dickAccessory, "dickAccessory"));
+		return el;
+	}
 
-		for (const key of App.Data.slaveWear.dickAccessory.keys()) {
+	/**
+	 * @param {slaveWearCategory} data
+	 * @param {string} category
+	 * @returns {HTMLDivElement}
+	 */
+	function lowerAttachmentList(data, category) {
+		let keys = [];
+		for (const key of data.keys()) {
 			if (key === "none") {
 				// skip none in set, we set the link elsewhere.
 				continue;
 			}
-			array.push(key);
+			keys.push(key);
 		}
 
 		// Sort
-		// No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1);
+		keys = keys.sort((a, b) => (a > b) ? 1 : -1);
 
 		// Options
 		const sortedMap = new Map([]);
-		for (const name of array) {
-			sortedMap.set(name, App.Data.slaveWear.dickAccessory.get(name));
+		for (const name of keys) {
+			sortedMap.set(name, data.get(name));
 		}
-		let links = document.createElement('div');
+		let links = document.createElement("div");
 		links.className = "choices";
-		links.appendChild(generateRows(sortedMap, "dickAccessory", true));
-		el.appendChild(links);
-
-		return el;
+		links.appendChild(generateRows(sortedMap, category, true));
+		return links;
 	}
 
 	function chastity() {
@@ -716,7 +661,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		} else if (slave.chastityAnus === 1) {
 			chasCho = `anal chastity`;
 		} else if (slave.chastityAnus === 0 && slave.chastityPenis === 0 && slave.chastityVagina === 0) {
-			chasCho = `none `;
+			chasCho = `none`;
 		} else {
 			chasCho = `THERE HAS BEEN AN ERROR `;
 		}
@@ -724,9 +669,9 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		label.append(App.UI.DOM.spanWithTooltip(chasCho, itemTooltip(chasCho, "chastity"), ["bold"]));
 
 		if (slave.chastityAnus !== 0 || slave.chastityPenis !== 0 || slave.chastityVagina !== 0) {
-			label.append(
+			label.append(" ",
 				App.UI.DOM.link(
-					` None`,
+					`None`,
 					() => {
 						Object.assign(
 							slave,
@@ -830,15 +775,18 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 	/**
 	 * Figure out a tooltip text to use based on clothing name.
-	 * Described effects are mainly from saClothes.js some are from saLongTermMentalEffects.js or saLongTermPhysicalEffects.js
-	 * Potential fetish revelations are not mentioned.
-	 * Chastity options could mention that at least fucktoys can appreciate maintaining their virginity but I assume just choosing a hole to focus on has the same effect so it's not really a clothing effect.
-	 * what's the word for below 20 devotion slaves? Disobedient?
-	 * Also accepting is a bit weird for ones above, I think I've seen obedient being used instead.
+	 * - Described effects are mainly from saClothes.js some are from saLongTermMentalEffects.js or saLongTermPhysicalEffects.js
+	 * - Potential fetish revelations are not mentioned.
+	 * - Chastity options could mention that at least fucktoys can appreciate maintaining their virginity, but I assume
+	 *   just choosing a hole to focus on has the same effect, so it's not really a clothing effect.
+	 * - what's the word for below 20 devotion slaves? Disobedient?
+	 * - Also accepting is a bit weird for ones above, I think I've seen obedient being used instead.
 	 * @param {string} itemName
 	 * @param {string} category
+	 * @returns {string|HTMLElement}
 	 */
 	function itemTooltip(itemName, category) {
+		console.log(itemName, category);
 		if (itemName === "none" || ["armAccessory", "legAccessory"].includes(category)) {
 			return "No effect one way or another.";
 		}
@@ -874,10 +822,6 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 						case 0:
 							desc.push("Modest.");
 							break;
-						default:
-							if (!item.harsh) {
-								desc.push("Only nice (meaning non-obedients lose devotion and fear while obedients gain devotion and trust)");
-							}
 					}
 				}
 				break;
@@ -940,6 +884,13 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 					desc.push("Makes it more scary to wear a plug but might give humiliation fetish,");
 				}
 				break;
+			case "dickAccessory":
+				if (item.vibrates >= 2) {
+					desc.push("Increases devotion and affects a specific fetish, attraction or sex drive.");
+				} else if (item.vibrates === 1) {
+					desc.push("Increases devotion but weakens fetish and libido.");
+				}
+				break;
 		}
 
 		if (item) {
@@ -959,13 +910,24 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 							lovers.push(App.Data.FutureSociety.records[FS].noun);
 						}
 						if (lovers.length > 0) {
-							desc.push(`${toSentence(lovers)} will ${value} this look.`); // TODO: Please move tooltip to array when that becomes possible
+							desc.push(`${toSentence(lovers)} will ${value} this look.`);
 						}
 					}
 				}
 			}
 		}
-		return desc.join(" ");
+
+		if (desc.length === 0) {
+			return item;
+		}
+		if (desc.length <= 1) {
+			return desc[0];
+		}
+		const f = document.createElement("ul");
+		for (const line of desc) {
+			App.UI.DOM.appendNewElement("li", f, line);
+		}
+		return f;
 	}
 
 	/** Generate a row of choices
@@ -978,7 +940,8 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const linkArray = [];
 		for (const [name, item] of map) {
 			let link;
-			// Some items will never be in App.Data.slaveWear.slaveWear, especially "none" if it falls in between harsh and nice data sets. Trying to look it up would cause an error, which is what access check works around.
+			// Some items will never be in App.Data.slaveWear.slaveWear, especially "none" if it falls in between harsh
+			// and nice data sets. Trying to look it up would cause an error, which is what access check works around.
 			const unlocked = (accessCheck === true) ? isItemAccessible.entry(name, category, slave) : false;
 			if (accessCheck === false || unlocked) {
 				if (typeof unlocked === 'string') { // is it just text?
@@ -986,10 +949,12 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 				} else {
 					link = document.createElement('span');
 
+					console.log(name, category, itemTooltip(name, category));
+
 					// Set up the link
 					link.appendChild(
 						App.UI.DOM.link(
-							`${item.name} `,
+							`${item.name}`,
 							() => {
 								slave[category] = name;
 								if (category === "clothes") {
@@ -1004,7 +969,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 					);
 
 					if (item.fs && item.fs.unlocks) {
-						link.append(App.UI.DOM.spanWithTooltip(`FS`, FutureSocieties.displayAdj(item.fs.unlocks), ["note"]));
+						link.append(" ", App.UI.DOM.spanWithTooltip(`FS`, FutureSocieties.displayAdj(item.fs.unlocks), ["note"]));
 					}
 				}
 				linkArray.push(link);
@@ -1016,7 +981,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 	function noneLink(slaveSlot) {
 		return App.UI.DOM.link(
-			` None`,
+			`None`,
 			() => {
 				slave[slaveSlot] = "none";
 				refresh();
diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js
index 4954d4c97a55ef55b1a23726ccef77dcc8e7d06e..5224aead3fbdf748b80116a71209de4b6709e2c3 100644
--- a/src/js/SlaveState.js
+++ b/src/js/SlaveState.js
@@ -358,6 +358,8 @@ App.Entity.SlaveCustomAddonsState = class SlaveCustomAddonsState {
 		this.desc = "";
 		/** What the slave refers to you as. */
 		this.title = "";
+		/** Replaces SlaveTitle() if set. */
+		this.name = "";
 		/** What the slave refers to you as, with a lisp.*/
 		this.titleLisp = "";
 		/**
diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js
index 9c8b0a10ab35aac4bfe32206f0f371f151a3ab2f..27dc32ec846e18b806b890b087fffc514e23c3c7 100644
--- a/src/js/utilsDOM.js
+++ b/src/js/utilsDOM.js
@@ -87,6 +87,7 @@ App.UI.DOM.link = function(linkText, handler, args = [], passage = "", tooltip =
 	};
 
 	if (tooltip) {
+		link.classList.add("has-tooltip");
 		tippy(link, {
 			content: tooltip,
 		});
diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js
index 336c3ec997e80ef7ed4e14719942eb47fe7d8c63..9c0c46f67e867a423c5075296437431aeb5f795a 100644
--- a/src/js/utilsSlave.js
+++ b/src/js/utilsSlave.js
@@ -1592,6 +1592,9 @@ globalThis.PoliteRudeTitle = function(slave) {
  * @returns {string}
  */
 globalThis.SlaveTitle = function(slave, adjective = true, variability = true) {
+	if (slave.custom.name) {
+		return slave.custom.name;
+	}
 	let r;
 	if (V.newDescriptions === 1) {
 		if (slave.dick > 0 && slave.balls > 0 && slave.boobs > 300 && slave.vagina > -1 && slave.ovaries === 1) {
diff --git a/src/npc/descriptions/crotch/vagina.js b/src/npc/descriptions/crotch/vagina.js
index 3d2bbe3a17896d726f5ca655651fe7526543140f..1faf7ad00d5e7063ef9e36ad8c285a2f4d940339 100644
--- a/src/npc/descriptions/crotch/vagina.js
+++ b/src/npc/descriptions/crotch/vagina.js
@@ -66,7 +66,9 @@ App.Desc.vagina = function(slave) {
 		}
 
 		if (V.seeRace === 1) {
-			if (slave.race === "white") {
+			if (slave.geneticQuirks.albinism === 2) {
+				r.push(`${slave.albinismOverride.skin} pussylips.`);
+			} else if (slave.race === "white") {
 				r.push(`pink pussylips.`);
 			} else if (slave.race === "asian") {
 				r.push(`dark ${slave.race} pussylips.`);