diff --git a/README.md b/README.md
index 06adff9b1fa11db47e60243fd8064ce985bc50e8..51718d404b18472e0dcc953ee8bb4abc30e17dd6 100644
--- a/README.md
+++ b/README.md
@@ -4,75 +4,87 @@ Pregmod is a modification of the original [Free Cities](https://freecitiesblog.b
 
 ## Play the game
 
-You can download compiled files and source archives from the [Releases page](https://gitgud.io/pregmodfan/fc-pregmod/-/releases), and the [build](https://gitgud.io/pregmodfan/fc-pregmod/-/jobs/artifacts/pregmod-master/download?job=build) from the latest commit to the master branch.
-
-Alternatively, you can build the game yourself:
-
-First, clone the git repository:
-
-1. [Install Git for terminal](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) or a Git GUI of your choice.
-2. Clone the repo
-    * Via terminal: `git clone --single-branch https://gitgud.io/pregmodfan/fc-pregmod.git`
-3. Get updates
-    * Via terminal: `git pull`
-
-Compile the game:
-
-* Windows
-    * Run compile.bat
-    * Second run of compile.bat will overwrite without prompt
-
-* Linux/Mac
-    1. Ensure executable permission on file `devTools/tweeGo/tweego` (not tweego.exe!)
-    2. Ensure executable permission on file `compile.sh`
-    3. In the root dir of sources (where you see src, devTools, bin...) run command `./compile.sh` from console.
-       Alternatively, if you have make installed, run `make all` in the root directory.
-
-To play open FC_pregmod.html in bin/ (Recommendation: Drag it into incognito mode)
+1. Download the game
+   * [Current release](https://gitgud.io/pregmodfan/fc-pregmod/-/releases)
+   * [Latest build](https://gitgud.io/pregmodfan/fc-pregmod/-/jobs/artifacts/pregmod-master/download?job=build)
+2. Open the game in your preferred browser
+   * On PC, we recommend either Firefox or [FCHost](FCHost/documentation_FCHost.md).
+   * Recommendation: Drag it into incognito mode
+3. Have fun!
+
+### Compile the game yourself
+
+If you want to tweak the game a bit, you can easily download the files and compile it yourself.
+
+1. Clone the git repository:
+   1. [Install Git for terminal](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) or a Git GUI of your
+      choice.
+   2. Clone the repo
+       * Via terminal: `git clone --single-branch https://gitgud.io/pregmodfan/fc-pregmod.git`
+   3. Get updates
+       * Via terminal: `git pull`
+
+2. Compile the game:
+   * Windows
+     * Run compile.bat
+     * Second run of compile.bat will overwrite without prompt
+
+   * Linux/Mac
+     1. Ensure executable permission on file `devTools/tweeGo/tweego` (not tweego.exe!)
+     2. Ensure executable permission on file `compile.sh`
+     3. In the root dir of sources (where you see src, devTools, bin...) run command `./compile.sh` from console.
+        Alternatively, if you have make installed, run `make all` in the root directory.
+
+3. To play open FC_pregmod.html in bin/
 
 ## Common problems
 
 * If compiling takes a while or causes a noticeable increase in system resource utilisation.
-	- It might be worth checking your main Antivirus (AV) settings.
-	- If it is Windows Defender (currently tested with Windows 10): Start menu -> Windows Security -> Virus & threat protection -> Virus & threat protection settings -> Manage settings -> Exclusions (near the bottom) -> Add or remove exclusions -> Add an exclusion -> path to bin/.
+  - It might be worth checking your main Antivirus (AV) settings.
+  - If it is Windows Defender (currently tested with Windows 10):
+    * `Start menu` -> `Windows Security` -> `Virus & threat protection` -> `Virus & threat protection settings` ->
+      `Manage settings` -> `Exclusions (near the bottom)` -> `Add or remove exclusions` -> `Add an exclusion` ->
+      `path to bin/.`
 
 * `sessionStorage quota exceeded` / `localStorage quota exceeded` or something similar
-    - Your saves stored inside the browser are getting too large. There are multiple ways to solve this:
-        1. Delete saves stored in the browser. If you want to keep them, save them to disk first.
-        2. Disable autosave and delete the current one. Due to technical reasons autosaves are larger than normal saves,
-           so this may help more than expected.
-        3. If on Firefox, raise the storage limit: Type `about:config` in the address bar and search for
-           `dom.storage.default_quota`. Increase this value as needed. Default value is 5120 kilobytes / 5 MB.
-        4. Switch to a different browser. Recommended is either Firefox or FCHost, a custom HTML renderer specifically
-           for Pregmod. Further reading can be found [here](FCHost/documentation_FCHost.md).
-        5. If you absolutely need to use Google Chrome:
-            1. download and unzip [NW.js SDK](https://nwjs.io/downloads/) for your operative system.
-            2. copy the game file (FC_pregmod.html) into the `nwjs-sdk-v0.XX.Y-YOUR_OS` folder
-            3. in the same folder, create a text file with the following content:
-               ```
-               {
-                   "name": "Free Cities pregmod edition",
-                   "main": "FC_pregmod.html",
-                   "dom_storage_quota":30
-               }
-               ```
-               and save it as package.json. In this example, 30 is the limit (in MB) that is set for the storage quota,
-               but you can replace it with any number. Google Chrome has the same default value as Firefox.
-            4. Double click nw.exe to launch the game.
+  - Your saves stored inside the browser are getting too large. There are multiple ways to solve this:
+    1. Delete saves stored in the browser. If you want to keep them, save them to disk first.
+    2. Disable autosave and delete the current one. Due to technical reasons autosaves are larger than normal saves,
+       so this may help more than expected.
+    3. If on Firefox, raise the storage limit: Type `about:config` in the address bar and search for
+       `dom.storage.default_quota`. Increase this value as needed. Default value is 5120 kilobytes / 5 MB.
+    4. Switch to a different browser. Recommended is either Firefox or [FCHost](FCHost/documentation_FCHost.md), a
+       custom HTML renderer specifically for Pregmod.
+    5. If you absolutely need to use Google Chrome:
+       1. download and unzip [NW.js SDK](https://nwjs.io/downloads/) for your operative system.
+       2. copy the game file (FC_pregmod.html) into the `nwjs-sdk-v0.XX.Y-YOUR_OS` folder
+       3. in the same folder, create a text file with the following content:
+          ```
+          {
+              "name": "Free Cities pregmod edition",
+              "main": "FC_pregmod.html",
+              "dom_storage_quota":30
+          }
+          ```
+          and save it as package.json. In this example, 30 is the limit (in MB) that is set for the storage quota,
+          but you can replace it with any number. Google Chrome has the same default value as Firefox.
+       4. Double click nw.exe to launch the game.
 
 * Everything is broken!
-    - **Do not copy over your existing download** as it may leave old files behind, replace it entirely
+  - **Do not copy over your existing download** as it may leave old files behind, replace it entirely
 
 * I can't save more than once or twice.
-    - Known issue caused by SugarCube level changes. Save to file doesn't have this problem and will likely avoid the first problem as well.
-    - It is possible to increase the memory utilized by your browser to delay this
+  - Known issue caused by SugarCube level changes. Save to file doesn't have this problem and will likely avoid the
+    first problem as well.
+  - It is possible to increase the memory utilized by your browser to delay this
 
 * I wish to report a sanityCheck issue.
-    - Great, however a large majority of the results are false positives. That said, if you found an actual error it could be a great first contribution if you are interested. 
+  - Open an issue or, if you are interested, it could be a great first contribution. Be warned though, a large number
+    are false positives. 
 
 ## Contribute
 
-New Contributors are always welcome. Basic information before you start can be found [here](CONTRIBUTING.md)
+New Contributors are always welcome. Basic information before you start can be found [here](CONTRIBUTING.md).
 
 ## Submodules
 
diff --git a/css/general/layout.css b/css/general/layout.css
index 959c99af5c2e14c4f6fe402cf9adc2429e4764f1..9e7d5b61d4625c3970cee06aefcefb6bc292e44a 100644
--- a/css/general/layout.css
+++ b/css/general/layout.css
@@ -39,15 +39,29 @@ div.double-indent, p.double-indent {
 
 div.grid-2columns-auto {
 	display: grid;
-	grid-template-columns: max-content auto;
+	grid-template-columns: auto auto;
 	grid-column-gap: 1em;
 }
+@media only screen and (min-width: 768px) {
+	div.grid-2columns-auto {
+		grid-template-columns: max-content auto;
+	}
+}
 
 div.grid-3columns-auto {
 	display: grid;
-	grid-template-columns: max-content auto auto;
+	grid-template-columns: auto auto auto;
 	grid-column-gap: 1em;
 }
+@media only screen and (min-width: 768px) {
+	div.grid-3columns-auto {
+		grid-template-columns: max-content max-content auto;
+	}
+}
+
+div.grid-all-columns {
+	grid-column: 1 / -1;
+}
 
 .border-bottom {
 	border-bottom: 1px solid;
diff --git a/css/gui/options.css b/css/gui/options.css
index eb58e8fc6d38b45f2364ceb702c241983c14ca2f..4599529a7dc9e28ed209b18277d7fff954b932eb 100644
--- a/css/gui/options.css
+++ b/css/gui/options.css
@@ -1,9 +1,15 @@
 div.options-group {
 	display: grid;
-	grid-template-columns: max-content auto;
+	grid-template-columns: auto auto;
 	align-items: center;
 }
 
+@media only screen and (min-width: 768px) {
+	div.options-group {
+		grid-template-columns: max-content auto;
+	}
+}
+
 /* left side */
 div.options-group div.description {
 	margin-right: 10px;
diff --git a/devTools/types/FC/gameState.d.ts b/devTools/types/FC/gameState.d.ts
index 1f8e04625aa09294b95d587bcd800f33db544ced..0eeaaed949a2663c1947c0d71f58d33c43171f2a 100644
--- a/devTools/types/FC/gameState.d.ts
+++ b/devTools/types/FC/gameState.d.ts
@@ -152,6 +152,7 @@ declare namespace FC {
 		heroSlaves: SlaveTemplate[];
 		endweekFlag?: boolean;
 		limitedCheatStart?: Bool
+		lastCashTransaction?: number;
 	}
 
 	export interface GameVariables extends DefaultGameStateVariables, ResetOnNGPVariables,
diff --git a/devTools/types/FC/human.d.ts b/devTools/types/FC/human.d.ts
index c804ce0d2625f775a0e2f78b667c948fbae49731..8a2776e8ea9f25048462873842ab98dd3335d937 100644
--- a/devTools/types/FC/human.d.ts
+++ b/devTools/types/FC/human.d.ts
@@ -405,6 +405,8 @@ declare global {
 			 *
 			 * **macromastia + gigantomastia** - Breasts never stop growing. Increased growth rate, no shrink rate. */
 			gigantomastia: GeneticQuirk | 3;
+			/** sperm is much more likely to knock someone up */
+			potent: GeneticQuirk;
 			/** is prone to having twins, shorter pregnancy recovery rate */
 			fertility: GeneticQuirk;
 			/** is prone to having multiples, even shorter pregnancy recovery rate
@@ -441,6 +443,9 @@ declare global {
 			mGain: GeneticQuirk;
 			/** constantly loses muscle mass, easier to gain muscle. mGain + mLoss - muscle gain/loss amplified, passively lose muscle unless building */
 			mLoss: GeneticQuirk;
+			/** ova will split if room is available
+			 *  only affects fetuses */
+			twinning: GeneticQuirk;
 			/** slave can only ever birth girls */
 			girlsOnly: GeneticQuirk;
 			/** abnormal production of amniotic fluid
@@ -482,6 +487,8 @@ declare global {
 			fetish: Fetish;
 			spermY: number;
 			inbreedingCoeff?: number;
+			adultHeight: number;
+			artSeed: number;
 		}
 		//#endregion
 
diff --git a/js/rulesAssistant/conditionEditorSimple.js b/js/rulesAssistant/conditionEditorSimple.js
index 64a557a95a6c1a5711122843a60841f5700dc6b5..fd73f571066193ae803acbd91107f39fc0b99f96 100644
--- a/js/rulesAssistant/conditionEditorSimple.js
+++ b/js/rulesAssistant/conditionEditorSimple.js
@@ -201,7 +201,7 @@ App.RA.Activation.SimpleEditor = (function() {
 		} else if (currentRule.activeRuleType === "custom") {
 			const options = new App.UI.OptionsGroup();
 			options.addOption("Mode", "customMode", currentRule)
-				.addValueList([["Boolean", "b"], ["Number", "n"], ["String", "s"]]).addCallbackToEach(refreshEditor);
+				.addValueList([["Boolean", "b"], ["Number", "n"], ["String", "s"]]).addGlobalCallback(refreshEditor);
 			outerDiv.append(options.render());
 			const textArea = document.createElement("textarea");
 			textArea.classList.add("condition-custom");
@@ -253,7 +253,7 @@ App.RA.Activation.SimpleEditor = (function() {
 	function deserializeRule(rule) {
 		// About the TS errors in this function: we can assume a lot about the rule composition because we know it's in
 		// the simple format. The rule itself is still a normal FC.RA.PostFixRule which would allow a lot more.
-		// Therefore, TS is not happy even though we now everything's fine.
+		// Therefore, TS is not happy even though we know everything's fine.
 		/**
 		 * @type {RuleState}
 		 */
diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js
index 86917d4b34807cea99329f3261a336f25142af07..ccc8c2c2e2dee16ebc9920e85981302f31647bd9 100644
--- a/src/002-config/fc-version.js
+++ b/src/002-config/fc-version.js
@@ -2,5 +2,5 @@ App.Version = {
 	base: "0.10.7.1", // The vanilla version the mod is based off of, this should never be changed.
 	pmod: "4.0.0-alpha.23",
 	commitHash: null,
-	release: 1187, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js.
+	release: 1188, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js.
 };
diff --git a/src/Mods/Catmod/generateCatgirl.js b/src/Mods/Catmod/generateCatgirl.js
index 2bd8936d82b0b793efde344dbc5fec3d48a5d917..5724ff6500e8967a6ce6356437a18f54e3d0b9ce 100644
--- a/src/Mods/Catmod/generateCatgirl.js
+++ b/src/Mods/Catmod/generateCatgirl.js
@@ -41,9 +41,11 @@ globalThis.growCatgirl = function(sex, {
 	// they're genetically engineered and very expensive, so go ahead and make their genes conform a bit better to local expectations...
 	const arc = V.arcologies[0];
 	if (arc.FSStatuesqueGlorification !== "unset") {
-		slave.height = Math.min(slave.height + 10, 274);
+		slave.natural.height = Math.min(slave.natural.height + 10, 274);
+		slave.height = Height.forAge(slave.natural.height, slave);
 	} else if (arc.FSPetiteAdmiration !== "unset") {
-		slave.height = Math.max(slave.height - 10, 85);
+		slave.natural.height = Math.max(slave.natural.height - 10, 85);
+		slave.height = Height.forAge(slave.natural.height, slave);
 	}
 	if (arc.FSIntellectualDependency !== "unset") {
 		slave.intelligence = Math.max(slave.intelligence - 15, -100);
diff --git a/src/Mods/SecExp/js/securityReport.js b/src/Mods/SecExp/js/securityReport.js
index 4e4965936c5151e18916bebc87bc04d6129e1514..7d80e67f6acccf8f4116e6d5ce1704f60bf14aad 100644
--- a/src/Mods/SecExp/js/securityReport.js
+++ b/src/Mods/SecExp/js/securityReport.js
@@ -55,13 +55,13 @@ App.Mods.SecExp.securityReport = function(oldACitizens) {
 		r.push(`The extremely high number of residents makes their job a lot harder.`);
 		secGrowth -= 2;
 	}
-	if (V.SecExp.core.security == 3) {
+	if (V.SecExp.edicts.weaponsLaw == 3) {
 		r.push(`The completely free flow of weapons in your arcology makes security quite a bit more challenging.`);
 		secGrowth -= 1,5;
-	} else if (V.SecExp.core.security == 2) {
+	} else if (V.SecExp.edicts.weaponsLaw == 2) {
 		r.push(`The somewhat lax flow of weapons makes securing ${V.arcologies[0].name} moderately harder.`);
 		secGrowth -= 1;
-	} else if (V.SecExp.core.security == 1) {
+	} else if (V.SecExp.edicts.weaponsLaw == 1) {
 		r.push(`The restrictive nature of your weapon laws leaves few instances of violent crime that security has to deal with.`);
 		secGrowth = 0;
 	} else {
diff --git a/src/art/webgl/art.js b/src/art/webgl/art.js
index d1ca2f14c228623d830c03ab233c2f28a7bc0ca6..d3d801ba068f1c2592eca21eb7a5d5e401d72b27 100644
--- a/src/art/webgl/art.js
+++ b/src/art/webgl/art.js
@@ -9,6 +9,11 @@ App.Art.hexToRgb = function(hex) {
 
 App.Art.seed = 0;
 
+App.Art.setSeed = function(slave, offset) {
+	App.Art.seed = slave.natural.artSeed + offset;
+	return App.Art.seed;
+};
+
 App.Art.random = function() {
 	App.Art.seed += 1;
 	let x = Math.sin(App.Art.seed) * 10000;
@@ -82,7 +87,7 @@ App.Art.getArtParams = function(slave) {
 };
 
 App.Art.applyFigures = function(slave, scene, p) {
-	App.Art.seed = slave.ID;
+	App.Art.seed = App.Art.setSeed(slave, 0);
 	let figures = [];
 
 	switch (slave.clothes) {
@@ -1133,7 +1138,7 @@ App.Art.applyFigures = function(slave, scene, p) {
 };
 
 App.Art.applySurfaces = function(slave, scene, p) {
-	App.Art.seed = slave.ID + 1000;
+	App.Art.seed = App.Art.setSeed(slave, 1000);
 
 	let glansFutaliciousShellLayers = [];
 	let shaftFutaliciousShellLayers = [];
@@ -1294,28 +1299,30 @@ App.Art.applySurfaces = function(slave, scene, p) {
 	}
 
 	let pubicStyle = "";
-	switch (slave.pubicHStyle) {
-		case "hairless":
-		case "waxed":
-		case "bald":
-			break;
-		case "neat":
-			pubicStyle = "PubicNeat";
-			break;
-		case "in a strip":
-			pubicStyle = "PubicStrip";
-			break;
-		case "bushy":
-			pubicStyle = "PubicBushy";
-			break;
-		case "very bushy":
-			pubicStyle = "PubicVeryBushy";
-			break;
-		case "bushy in the front and neat in the rear":
-			pubicStyle = "PubicBushyFront";
-			break;
-		default:
-			break;
+	if (slave.physicalAge >= slave.pubertyAge) {
+		switch (slave.pubicHStyle) {
+			case "hairless":
+			case "waxed":
+			case "bald":
+				break;
+			case "neat":
+				pubicStyle = "PubicNeat";
+				break;
+			case "in a strip":
+				pubicStyle = "PubicStrip";
+				break;
+			case "bushy":
+				pubicStyle = "PubicBushy";
+				break;
+			case "very bushy":
+				pubicStyle = "PubicVeryBushy";
+				break;
+			case "bushy in the front and neat in the rear":
+				pubicStyle = "PubicBushyFront";
+				break;
+			default:
+				break;
+		}
 	}
 
 	if (pubicStyle !== "") {
@@ -1637,7 +1644,7 @@ App.Art.applySurfaces = function(slave, scene, p) {
 };
 
 App.Art.applyMaterials = function(slave, scene, p) {
-	App.Art.seed = slave.ID + 2000;
+	App.Art.seed = App.Art.setSeed(slave, 2000);
 
 	let materials = [];
 
@@ -2172,29 +2179,31 @@ App.Art.applyMaterials = function(slave, scene, p) {
 	materials.push(["TemplateGenitalia", "Ni", Ni]);
 	materials.push(["TemplateGenitalia", "map_Ka", "base/skin/" + skin + "Torso.jpg"]);
 
-	let pubicColor = App.Art.hexToRgb(extractColor(slave.pubicHColor));
-	switch (slave.pubicHStyle) {
-		case "hairless":
-		case "waxed":
-		case "bald":
-			break;
-		case "neat":
-			materials.push(["PubicNeat", "Ka", pubicColor]);
-			break;
-		case "in a strip":
-			materials.push(["PubicStrip", "Ka", pubicColor]);
-			break;
-		case "bushy":
-			materials.push(["PubicBushy", "Ka", pubicColor]);
-			break;
-		case "very bushy":
-			materials.push(["PubicVeryBushy", "Ka", pubicColor]);
-			break;
-		case "bushy in the front and neat in the rear":
-			materials.push(["PubicBushyFront", "Ka", pubicColor]);
-			break;
-		default:
-			break;
+	if (slave.physicalAge >= slave.pubertyAge) {
+		const pubicColor = App.Art.hexToRgb(extractColor(slave.pubicHColor));
+		switch (slave.pubicHStyle) {
+			case "hairless":
+			case "waxed":
+			case "bald":
+				break;
+			case "neat":
+				materials.push(["PubicNeat", "Ka", pubicColor]);
+				break;
+			case "in a strip":
+				materials.push(["PubicStrip", "Ka", pubicColor]);
+				break;
+			case "bushy":
+				materials.push(["PubicBushy", "Ka", pubicColor]);
+				break;
+			case "very bushy":
+				materials.push(["PubicVeryBushy", "Ka", pubicColor]);
+				break;
+			case "bushy in the front and neat in the rear":
+				materials.push(["PubicBushyFront", "Ka", pubicColor]);
+				break;
+			default:
+				break;
+		}
 	}
 
 	switch (slave.vaginaLube) {
@@ -2596,7 +2605,7 @@ App.Art.getAnimState = function(slave, scene, p, morphs, isAnimTick) {
 };
 
 App.Art.applyMorphs = function(slave, scene, p, isAnimating) {
-	App.Art.seed = slave.ID + 3000;
+	App.Art.seed = App.Art.setSeed(slave, 3000);
 
 	let morphs = [];
 
diff --git a/src/budget/loans.js b/src/budget/loans.js
index 855278661f8a2fb0ae63c7d6d694ead5b0f1d60d..8c0e1cf421432ec3c0eb411adeb05af29bdbfb89 100644
--- a/src/budget/loans.js
+++ b/src/budget/loans.js
@@ -78,45 +78,37 @@ App.Budget.loans = function() {
 		const values = [10000, 100000, 1000000];
 		const disabledReasons = [];
 		const links = [];
-		const text = [];
-
-		let allowed = true;
 
-		text.push(`You can take out a loan from one of the credit unions in the Free City, if you have the reputation for them to trust you.`);
+		div.append(`You can take out a loan from one of the credit unions in the Free City, if you have the reputation for them to trust you.`);
+		App.UI.DOM.appendNewElement("div", div,
+			`If for any reason you lack the credits, sectors of ${V.arcologies[0].name} will be used in lieu of payment.`,
+			["note", "indent"]);
 
 		if (V.rep < 10000) {
 			disabledReasons.push(`You need at least ${num(10000)} reputation to take a loan from this lender.`);
-			allowed = false;
 		}
 		if (loan('bank')) {
 			disabledReasons.push(`You have already taken out a loan from this lender.`);
-			allowed = false;
 		}
 
-		if (allowed) {
-			values.map(val => links.push(App.UI.DOM.link(cashFormat(val), () => {
-				const term = Math.max(val / 50000, 4);
-				const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
-				const interest = val * (term / 52) * (apr / 100);
-				const full = val + interest;
-				V.loans.push({
-					name: 'bank',
-					principal: val,
-					deadline: V.week + term,
-					installments: term,
-					apr,
-					interest,
-					full,
-				});
-				cashX(val, "loan");
-
-				App.UI.reload();
-			}, [], '', terms('bank', val))));
+		if (disabledReasons.length === 0) {
+			for (const amount of values) {
+				const loan = createLoan("bank", amount);
+				const f = new DocumentFragment();
+				f.append(App.UI.DOM.link(cashFormat(amount), () => {
+					V.loans.push(loan);
+					cashX(amount, "loan");
+					App.UI.reload();
+				}));
+				const info = new DocumentFragment();
+				App.Events.addNode(info, [`${cashFormatColor(loan.full)} over ${num(loan.deadline - V.week)} weeks`]);
+				f.append(" – ", App.UI.DOM.spanWithTooltip(info, terms("bank", loan)));
+				links.push(f);
+			}
 		} else {
 			values.map(val => links.push(App.UI.DOM.disabledLink(cashFormat(val), disabledReasons)));
 		}
 
-		div.append(text.join(' '));
 		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
 
 		return div;
@@ -127,67 +119,82 @@ App.Budget.loans = function() {
 		const values = [10000, 100000, 1000000];
 		const disabledReasons = [];
 		const links = [];
-		const text = [];
-
-		let allowed = true;
 
-		text.push(`If you're not quite reputable enough, you can also borrow money from one of the local loansharks in the area.`);
+		div.append(`If you're not quite reputable enough, you can also borrow money from one of the local loan-sharks in the area.`);
+		App.UI.DOM.appendNewElement("div", div,
+			`If for any reason you miss a payment the lender will send his men to collect – forcibly, if necessary.`,
+			["note", "indent"]);
 
 		if (V.rep < 2000) {
 			disabledReasons.push(`You need at least ${num(2000)} reputation to take a loan from this lender.`);
-			allowed = false;
 		}
 		if (loan('shark')) {
 			disabledReasons.push(`You have already taken out a loan from this lender.`);
-			allowed = false;
 		}
 
-		if (allowed) {
-			values.map(val => links.push(App.UI.DOM.link(cashFormat(val), () => {
-				const term = Math.max(val / 50000, 4);
-				const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
-				const interest = (val * (term / 52) * (apr / 100)) * 3;
-				const full = val + interest;
-				V.loans.push({
-					name: 'shark',
-					principal: val,
-					deadline: V.week + (Math.max(val / 50000, 4)),
-					installments: 1,
-					apr,
-					interest,
-					full,
-				});
-				cashX(val, "loan");
-
-				App.UI.reload();
-			}, [], '', terms('shark', val))));
+		if (disabledReasons.length === 0) {
+			for (const amount of values) {
+				const loan = createLoan("shark", amount);
+				const f = new DocumentFragment();
+				f.append(App.UI.DOM.link(cashFormat(amount), () => {
+					V.loans.push(loan);
+					cashX(amount, "loan");
+
+					App.UI.reload();
+				}));
+				const info = new DocumentFragment();
+				App.Events.addNode(info, [`${cashFormatColor(loan.full)} after ${num(loan.deadline - V.week)} weeks`]);
+				f.append(" – ", App.UI.DOM.spanWithTooltip(info, terms("shark", loan)));
+				links.push(f);
+			}
 		} else {
 			values.map(val => links.push(App.UI.DOM.disabledLink(cashFormat(val), disabledReasons)));
 		}
 
-		div.append(text.join(' '));
 		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
 
 		return div;
 	}
 
 	/**
-	 * @param {Lender} lender
+	 * @param {"bank"|"shark"}lender
 	 * @param {number} amount
+	 * @returns {FC.Loan}
 	 */
-	function terms(lender, amount) {
+	function createLoan(lender, amount) {
 		const term = Math.max(amount / 50000, 4);
 		const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
-		const interest = amount * (term / 52) * (apr / 100);
+		let interest;
+		let installments;
+		if (lender === "shark") {
+			interest = (amount * (term / 52) * (apr / 100)) * 3;
+			installments = 1;
+		} else {
+			interest = amount * (term / 52) * (apr / 100);
+			installments = term;
+		}
 		const full = amount + interest;
-		const text = [];
 
+		return {
+			name: 'shark',
+			principal: amount,
+			deadline: V.week + term,
+			installments,
+			apr,
+			interest,
+			full: Math.trunc(full),
+		};
+	}
+
+	/**
+	 * @param {Lender} lender
+	 * @param {FC.Loan} loan
+	 */
+	function terms(lender, loan) {
 		if (lender === 'bank') {
-			text.push(`You will pay about ${cashFormat(Math.trunc(full / term))} per week for ${num(term)} weeks until you have paid off the entire balance. If for any reason you lack the credits, sectors of ${V.arcologies[0].name} will be used in lieu of payment. You will end up paying back about ${cashFormat(Math.trunc(full))} after interest.`);
+			return `You will pay about ${cashFormat(Math.trunc(loan.full / loan.deadline - V.week))} per week for ${num(loan.deadline - V.week)} weeks until you have paid off the entire balance. You will end up paying back about ${cashFormat(Math.trunc(loan.full))} after interest.`;
 		} else {
-			text.push(`You will have ${num(term)} weeks to pay off the full amount, after which the lender will send his men to collect – forcibly, if necessary. You will end up paying back about ${cashFormat(Math.trunc(amount + (interest * 3)))} after interest.`);
+			return `You will have ${num(loan.deadline - V.week)} weeks to pay off the full amount. You will end up paying back about ${cashFormat(Math.trunc(loan.full))} after interest.`;
 		}
-
-		return text.join(' ');
 	}
 };
diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js
index 5a46884413b8b20276015fceefefbe42d95e5b48..033ec6041b41ae7f5d3da5637140dd411ab52abd 100644
--- a/src/data/backwardsCompatibility/backwardsCompatibility.js
+++ b/src/data/backwardsCompatibility/backwardsCompatibility.js
@@ -1546,6 +1546,16 @@ App.Update.slaveRecords = function(node) {
 				if (child.spermY === undefined) {
 					child.spermY = normalRandInt(50, 5);
 				}
+				if (!child.natural) {
+					child.natural = new App.Entity.GeneticState();
+					if (child.geneticQuirks.dwarfism === 2 && child.geneticQuirks.gigantism !== 2) {
+						child.natural.height = Height.randomAdult(child, {limitMult: [-4, -1], spread: 0.15});
+					} else if (child.geneticQuirks.gigantism === 2) {
+						child.natural.height = Height.randomAdult(child, {limitMult: [3, 10], spread: 0.15});
+					} else {
+						child.natural.height = Height.randomAdult(child);
+					}
+				}
 				App.Facilities.Nursery.InfantDatatypeCleanup(child);
 				child.inbreedingCoeff = ibc.coeff(child);
 			} else {
@@ -2391,8 +2401,6 @@ App.Update.oldVersions = function(node) {
 			}
 		}
 
-		WombInit(newPC);
-
 		V.PC = clone(newPC);
 
 		if (typeof V.PC.name === "undefined") {
@@ -2445,6 +2453,22 @@ App.Update.oldVersions = function(node) {
 			V.PC.skill.combat = 10;
 		}
 	}
+	if (!V.PC.natural) {
+		V.PC.natural = new App.Entity.GeneticState();
+		if (V.PC.physicalAge >= 20) {
+			V.PC.natural.height = V.PC.height - V.PC.heightImplant * 10;
+		} else {
+			// find and set a reasonable natural height for this immature player
+			if (V.PC.geneticQuirks.dwarfism === 2 && V.PC.geneticQuirks.gigantism !== 2) {
+				V.PC.natural.height = Height.randomAdult(V.PC, {limitMult: [-4, -1], spread: 0.15});
+			} else if (V.PC.geneticQuirks.gigantism === 2) {
+				V.PC.natural.height = Height.randomAdult(V.PC, {limitMult: [3, 10], spread: 0.15});
+			} else {
+				V.PC.natural.height = Height.randomAdult(V.PC);
+			}
+		}
+	}
+	WombInit(V.PC);
 
 	if (V.releaseID < 1185) {
 		if (V.nurseryNannies > 0) {
diff --git a/src/data/backwardsCompatibility/updateSlaveObject.js b/src/data/backwardsCompatibility/updateSlaveObject.js
index 23cfd18dde559a74cb2e38f67e768b5ae82c8b04..862d8e041712ea59dac07705fdf4f22ab720c037 100644
--- a/src/data/backwardsCompatibility/updateSlaveObject.js
+++ b/src/data/backwardsCompatibility/updateSlaveObject.js
@@ -1319,12 +1319,12 @@ App.Update.Slave = function(slave, genepool = false) {
 						}
 						break;
 					}
-					case "mother":
+					case "daughter":
 						// we know your mother. that's easy.
 						slave.mother = slave.relationTarget;
 						V.relationLinks[slave.ID] = {mother: slave.mother, father: 0};
 						break;
-					case "daughter":
+					case "mother":
 						// we know you are your daughter's mother. keep track of that in case she's forgotten somehow.
 						if (!V.relationLinks[slave.relationTarget]) {
 							V.relationLinks[slave.relationTarget] = {mother: slave.ID, father: 0};
@@ -1433,8 +1433,25 @@ App.Update.Slave = function(slave, genepool = false) {
 	}
 
 	if (V.releaseID < 1182) {
-		if (slave.skill.combat === 1) {
+		if (slave.skill?.combat === 1) {
 			slave.skill.combat = 70;
 		}
 	}
+
+	if (!slave.natural) {
+		slave.natural = new App.Entity.GeneticState();
+		slave.natural.artSeed = slave.ID; // used to use the ID as the seed; copy it on old slaves so they don't suddenly change appearance
+		if (slave.physicalAge >= 20) {
+			slave.natural.height = slave.height - slave.heightImplant * 10;
+		} else {
+			// find and set a reasonable natural height for this immature slave
+			if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
+				slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -1], spread: 0.15});
+			} else if (slave.geneticQuirks.gigantism === 2) {
+				slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 10], spread: 0.15});
+			} else {
+				slave.natural.height = Height.randomAdult(slave);
+			}
+		}
+	}
 };
diff --git a/src/endWeek/events/expire.js b/src/endWeek/events/expire.js
index cc8d0c61f5c53a08d97f3d0a8f1b1832179e9c94..e49b9b62f53b9b7ccae2ae0154da91cdc04fffeb 100644
--- a/src/endWeek/events/expire.js
+++ b/src/endWeek/events/expire.js
@@ -79,16 +79,13 @@ App.Events.SEExpiration = class SEExpiration extends App.Events.BaseEvent {
 				r.push(`${He} ${hasAnyLegs(slave) ? 'stands' : 'sits'} before you dumbly, betraying no reaction to the prospect of becoming free from sexual slavery. In situations like this, it is perfectly acceptable to subject ${him} to another indenture for ${his} own good.`);
 
 				if (V.cash > 1000) {
-					App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link(
-						`Plead necessity and reactivate ${his} indenture`,
-						() => {
-							keepSlave(-1000);
-							jQuery(result).empty().append(`You plead necessity and place ${him} under another indenture, paying the trivial fees left over once ${he} has been charged for ${his} own forecasted upkeep. Naturally, ${he} offers no response at all to any of this.`);
-						},
-						[],
-						"",
-						`This costs ${cashFormat(1000)}`
-					));
+					const div = document.createElement("div");
+					div.append(App.UI.DOM.link(`Plead necessity and reactivate ${his} indenture`, () => {
+						keepSlave(-1000);
+						jQuery(result).empty().append(`You plead necessity and place ${him} under another indenture, paying the trivial fees left over once ${he} has been charged for ${his} own forecasted upkeep. Naturally, ${he} offers no response at all to any of this.`);
+					}));
+					App.UI.DOM.appendNewElement("span", div, ` This costs ${cashFormat(1000)}`, ["note"]);
+					result.append(div);
 				} else {
 					App.UI.DOM.appendNewElement("div", result, `You cannot afford to do this`, ["note"]);
 				}
@@ -109,33 +106,30 @@ App.Events.SEExpiration = class SEExpiration extends App.Events.BaseEvent {
 				}
 
 				if (V.cash > 1000) {
-					App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link(
-						`Enslave ${him}`,
-						() => {
-							const el = new DocumentFragment();
-							const r = [];
-							r.push(`${He}'s beside ${himself} with joy when you accept ${his} plea and enslave ${him}. ${He}'s given you the finest proof of loyalty a slave possibly can, having tasted a moment of freedom under the law, and thrown it away with utter contempt.`);
-							if (hasAnyEyes(slave)) {
-								r.push(`${His} ${App.Desc.eyesColor(slave)}`);
-								if (canSee(slave)) {
-									r.push(`${hasBothEyes(slave) ? 'watch' : 'watches'} you with`);
-								} else {
-									r.push(`${hasBothEyes(slave) ? 'are' :'is'} wide with`);
-								}
+					const div = document.createElement("div");
+					div.append(App.UI.DOM.link(`Enslave ${him}`, () => {
+						const el = new DocumentFragment();
+						const r = [];
+						r.push(`${He}'s beside ${himself} with joy when you accept ${his} plea and enslave ${him}. ${He}'s given you the finest proof of loyalty a slave possibly can, having tasted a moment of freedom under the law, and thrown it away with utter contempt.`);
+						if (hasAnyEyes(slave)) {
+							r.push(`${His} ${App.Desc.eyesColor(slave)}`);
+							if (canSee(slave)) {
+								r.push(`${hasBothEyes(slave) ? 'watch' : 'watches'} you with`);
 							} else {
-								r.push(`${His} face shows`);
+								r.push(`${hasBothEyes(slave) ? 'are' : 'is'} wide with`);
 							}
-							r.push(`eager anticipation, radiating gladness that the prospect of separation from you has gone.`);
-							App.Events.addNode(el, r);
-							slave.indenture = -1;
-							slave.indentureRestrictions = 0;
-							keepSlave(-1000);
-							jQuery(result).empty().append(el);
-						},
-						[],
-						"",
-						`This costs ${cashFormat(1000)}`
-					));
+						} else {
+							r.push(`${His} face shows`);
+						}
+						r.push(`eager anticipation, radiating gladness that the prospect of separation from you has gone.`);
+						App.Events.addNode(el, r);
+						slave.indenture = -1;
+						slave.indentureRestrictions = 0;
+						keepSlave(-1000);
+						jQuery(result).empty().append(el);
+					}));
+					App.UI.DOM.appendNewElement("span", div, ` This costs ${cashFormat(1000)}`, ["note"]);
+					result.append(div);
 				} else {
 					App.UI.DOM.appendNewElement("div", result, `You cannot afford to do this`, ["note"]);
 				}
@@ -154,16 +148,13 @@ App.Events.SEExpiration = class SEExpiration extends App.Events.BaseEvent {
 				}
 
 				if (V.cash > cost) {
-					App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link(
-						`Offer ${him} a one year supplementary indenture`,
-						() => {
-							keepSlave(cost);
-							jQuery(result).empty().append(`${He} smiles almost shyly when you offer ${him} a one year supplementary indenture. The price is reasonable, but definitely favorable to you. ${He} accepts it anyway, and you transfer the money into an escrow account to be held for ${him} until ${his} new indenture is done. Your sex slave once again, ${he} awaits your pleasure without a hint of fear.`);
-						},
-						[],
-						"",
-						`This costs ${cashFormat(cost)}`
-					));
+					const div = document.createElement("div");
+					div.append(App.UI.DOM.link(`Offer ${him} a one year supplementary indenture`, () => {
+						keepSlave(cost);
+						jQuery(result).empty().append(`${He} smiles almost shyly when you offer ${him} a one year supplementary indenture. The price is reasonable, but definitely favorable to you. ${He} accepts it anyway, and you transfer the money into an escrow account to be held for ${him} until ${his} new indenture is done. Your sex slave once again, ${he} awaits your pleasure without a hint of fear.`);
+					}));
+					App.UI.DOM.appendNewElement("span", div, ` This costs ${cashFormat(cost)}`, ["note"]);
+					result.append(div);
 				} else {
 					App.UI.DOM.appendNewElement("div", result, `You cannot afford to do this`, ["note"]);
 				}
@@ -172,16 +163,13 @@ App.Events.SEExpiration = class SEExpiration extends App.Events.BaseEvent {
 				r.push(`${!hasAnyLegs(slave) ? 'Propped up' : 'Standing before you'} at the moment of ${his} scheduled emancipation, ${he} seems willing to consider a short term continuation of service.`);
 
 				if (V.cash > cost) {
-					App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link(
-						`Offer ${him} a one year supplementary indenture`,
-						() => {
-							keepSlave(cost);
-							jQuery(result).empty().append(`${He} looks pensive when you offer ${him} a one year supplementary indenture. The price reflects the market, and is a reasonable compensation for a year of sexual slavery. ${He} accepts it after some consideration, and you transfer the money into an escrow account to be held for ${him} until ${his} new indenture is done. Your sex slave once again, ${he} awaits orders with complacency.`);
-						},
-						[],
-						"",
-						`This costs ${cashFormat(cost)}`
-					));
+					const div = document.createElement("div");
+					div.append(App.UI.DOM.link(`Offer ${him} a one year supplementary indenture`, () => {
+						keepSlave(cost);
+						jQuery(result).empty().append(`${He} looks pensive when you offer ${him} a one year supplementary indenture. The price reflects the market, and is a reasonable compensation for a year of sexual slavery. ${He} accepts it after some consideration, and you transfer the money into an escrow account to be held for ${him} until ${his} new indenture is done. Your sex slave once again, ${he} awaits orders with complacency.`);
+					}));
+					App.UI.DOM.appendNewElement("span", div, ` This costs ${cashFormat(cost)}`, ["note"]);
+					result.append(div);
 				} else {
 					App.UI.DOM.appendNewElement("div", result, `You cannot afford to do this`, ["note"]);
 				}
diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js
index f4d433d5478147dc3868e7261e0fe92a1724c891..7fee81272282a2bff1ebe5a4877e67cda1f66707 100644
--- a/src/endWeek/nextWeek/nextWeek.js
+++ b/src/endWeek/nextWeek/nextWeek.js
@@ -39,7 +39,7 @@ App.EndWeek.nextWeek = function() {
 					V.PC.visualAge++;
 					V.PC.ovaryAge += either(0.8, 0.9, 0.9, 1.0, 1.0, 1.0, 1.1);
 				}
-				if (V.PC.physicalAge <= 18 && V.loliGrow > 0) {
+				if (V.PC.physicalAge <= 20 && V.loliGrow > 0) {
 					App.EndWeek.Shared.physicalDevelopment(V.PC, true);
 				}
 				agePCEffects();
diff --git a/src/endWeek/player/prDrugs.js b/src/endWeek/player/prDrugs.js
index 7385a8de254f83be27803563bd2f424f539750e4..eb3188b48b8b8672994018e1b371b9ac2765f5f5 100644
--- a/src/endWeek/player/prDrugs.js
+++ b/src/endWeek/player/prDrugs.js
@@ -879,9 +879,9 @@ App.EndWeek.Player.drugs = function(PC = V.PC) {
 					// evaluate against expected height, with neoteny comparing against expected height for 12 year olds...
 					let heightDiff;
 					if (PC.geneticQuirks.neoteny === 2 && PC.physicalAge > 12) {
-						heightDiff = (PC.height - PC.heightImplant * 10) / Height.mean(PC.nationality, PC.race, PC.genes, 12);
+						heightDiff = (PC.height - PC.heightImplant * 10) / Height.forAge(PC.natural.height, 12, PC.genes);
 					} else {
-						heightDiff = (PC.height - PC.heightImplant * 10) / Height.mean(PC);
+						heightDiff = (PC.height - PC.heightImplant * 10) / Height.forAge(PC.natural.height, PC);
 					}
 					// if you are taller than the expected height the growth is reduced, if shorter accelerated proportionally to the distance from the expected height
 					heightDiff = 1 - heightDiff;
diff --git a/src/endWeek/reports/incubatorReport.js b/src/endWeek/reports/incubatorReport.js
index ac5dc09d1fc551356cea0e6c5c5451797cc7f6b7..a3f138fee6a7cd656f86d76022ac9c5339471aaa 100644
--- a/src/endWeek/reports/incubatorReport.js
+++ b/src/endWeek/reports/incubatorReport.js
@@ -156,23 +156,23 @@ App.EndWeek.incubatorReport = function() {
 
 		r = [];
 		if (V.incubator.upgrade.growthStims === 1 && V.incubator.setting.growthStims !== 0) {
-			let heightLimit = Math.clamp((Height.mean(tank) * 1.25), 0, 274);
-			let heightLimitAge = Height.mean(tank);
+			let heightLimit = Math.clamp((Height.forAge(tank.natural.height, tank) * 1.25), 0, 274);
+			let heightLimitAge = Height.forAge(tank.natural.height, tank);
 			if (tank.geneticQuirks.dwarfism === 2 && tank.geneticQuirks.gigantism !== 2) {
-				heightLimit = Math.clamp((Height.mean(tank) * 0.95), 0, 160);
+				heightLimit = Math.clamp((Height.forAge(tank.natural.height, tank) * 0.95), 0, 160);
 			} else if (tank.geneticQuirks.gigantism === 2 && tank.geneticQuirks.dwarfism !== 2) {
-				heightLimit = Math.clamp((Height.mean(tank) * 1.75), 0, 274);
+				heightLimit = Math.clamp((Height.forAge(tank.natural.height, tank) * 1.75), 0, 274);
 			}
 			if (tank.geneMods.NCS === 1) {
 				/* NCS should block physical growth beyond that of a toddler, but some players might like
 				 * a little more or less. So using V.minimumSlaveAge or 8, whichever is lesser.	*/
 				const limitAge = Math.min(8, V.minimumSlaveAge);
-				/* Generate new average height for slave of age limitAge */
-				heightLimitAge = Height.mean(tank.nationality, tank.race, tank.genes, limitAge);
-				heightLimit = heightLimitAge; /* TODO: Add some variation, right now all NCS slaves will be the exact same height */
+				/* scale height to age 8 */
+				heightLimitAge = Height.forAge(tank.natural.height, limitAge);
+				heightLimit = heightLimitAge;
 			} else if (tank.geneticQuirks.neoteny === 2 && tank.physicalAge > 12) {
-				/* Generate new average height for slave of age 12 */
-				heightLimitAge = Height.mean(tank.nationality, tank.race, tank.genes, 12);
+				/* scale height to age 12 */
+				heightLimitAge = Height.forAge(tank.natural.height, 12);
 				heightLimit = Math.clamp((heightLimitAge * 1.25), 0, 274);
 			}
 			if (tank.height >= heightLimit) {
diff --git a/src/endWeek/reports/spaReport.js b/src/endWeek/reports/spaReport.js
index 804768e12af2eb22c834d054b5a6fed9c0b26a53..89d0ce00b63451843bf1c4d1b9152919d1c9813a 100644
--- a/src/endWeek/reports/spaReport.js
+++ b/src/endWeek/reports/spaReport.js
@@ -305,7 +305,7 @@ App.EndWeek.spaReport = function() {
 	if (S.Attendant) {
 		const slave = App.SlaveAssignment.reportSlave(S.Attendant);
 		tired(slave);
-		if (isFertile(slave) && slave.preg !== -1 && App.EndWeek.saVars.poolJizz > (canSee(S.Attendant) ? 5000 : 1000)) { // Free swimming sperm do not respect chastity and the Attendant can not avoid going in the pool.
+		if (isFertile(slave) && slave.preg !== -1 && App.EndWeek.saVars.poolJizz > (canSee(S.Attendant) ? 5000 : 1000)) { // Free swimming sperm do not respect chastity and the Attendant cannot avoid going in the pool.
 			const spermAtt = weightedRandom(App.EndWeek.saVars.poolJizzers);
 			if (canBreed(slave, getSlave(spermAtt.ID))) {
 				knockMeUp(slave, 25, 2, spermAtt.ID);
diff --git a/src/endWeek/saDrugs.js b/src/endWeek/saDrugs.js
index c03bba400e049622c79ae92511f68bb56005c652..13c74177ab9f3151ec12e3eedbd5d05e743ebe5c 100644
--- a/src/endWeek/saDrugs.js
+++ b/src/endWeek/saDrugs.js
@@ -930,9 +930,9 @@ App.SlaveAssignment.drugs = function saDrugs(slave) {
 					// evaluate against slave expected height, with neoteny slaves comparing against expected height for 12 year olds...
 					let heightDiff;
 					if (slave.geneticQuirks.neoteny === 2 && slave.physicalAge > 12) {
-						heightDiff = (slave.height - slave.heightImplant * 10) / Height.mean(slave.nationality, slave.race, slave.genes, 12);
+						heightDiff = (slave.height - slave.heightImplant * 10) / Height.forAge(slave.natural.height, 12, slave.genes);
 					} else {
-						heightDiff = (slave.height - slave.heightImplant * 10) / Height.mean(slave);
+						heightDiff = (slave.height - slave.heightImplant * 10) / Height.forAge(slave.natural.height, slave);
 					}
 					// if ${he} is taller than the expected height the growth is reduced, if shorter accelerated proportionally to the distance from the expected height
 					heightDiff = 1 - heightDiff;
diff --git a/src/endWeek/saPregnancy.js b/src/endWeek/saPregnancy.js
index 20a2c114ea03a67e04ef1b8dd7fef860973d5479..02e08dc3c95cd56643ef2f2f5bd83636706f5b93 100644
--- a/src/endWeek/saPregnancy.js
+++ b/src/endWeek/saPregnancy.js
@@ -1767,7 +1767,7 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) {
 						// Sperm mod leavings around the penthouse. Gives servants more of a point too.
 						let slobs = V.slaves.filter(s => canFemImpreg(slave, s) && isSlaveAvailable(s) && s.geneMods.aggressiveSperm === 1 && (s.fetish === "mindbroken" || s.energy > 95 || (s.devotion < -20 && s.trust > 20) || (s.intelligence + s.intelligenceImplant < -10)));
 						if (slobs.length > (totalServantCapacity() / 5)) {
-							knockMeUp(slave, -50, 2, slobs.random());
+							tryKnockMeUp(slave, -50, 2, slobs.random());
 						}
 					}
 			} /* closes assignment checks */
diff --git a/src/endWeek/saSharedVariables.js b/src/endWeek/saSharedVariables.js
index 79c9462c8fac022ad9f7dd50355bbfcd99d3fe78..c982d402d25aa50cec20994927942fbb1a55d995 100644
--- a/src/endWeek/saSharedVariables.js
+++ b/src/endWeek/saSharedVariables.js
@@ -22,9 +22,9 @@ App.EndWeek.SASharedVariables = class {
 		this.whorePriceAdjustment = {};
 		/** How many slaves can the designated stud still impregnate? */
 		this.StudCum = 0;
-		/** Are slaves with the agressive sperm gene mod jacking off or having sex in the spa pool? */
+		/** Are slaves with the aggressive sperm gene mod jacking off or having sex in the spa pool? */
 		this.poolJizz = 0;
-		/** Which agressive sperm slaves are knocking up the spa bathers? */
+		/** Which aggressive sperm slaves are knocking up the spa bathers? */
 		this.poolJizzers = [];
 		/** How much energy does the player have left to fuck slaves who need it? */
 		this.freeSexualEnergy = 0;
diff --git a/src/endWeek/shared/physicalDevelopment.js b/src/endWeek/shared/physicalDevelopment.js
index 6b7e98562c4d8c389e9b934b090f55923bc91a94..3765d58dfe0aa2c4b1a09ef33d9f7d7a69b97db0 100644
--- a/src/endWeek/shared/physicalDevelopment.js
+++ b/src/endWeek/shared/physicalDevelopment.js
@@ -5,7 +5,6 @@ App.EndWeek.Shared.physicalDevelopment = function(actor, player = false) {
 	const rearQuirkDivider = rearQuirk === 0 ? 1 : rearQuirk;
 	const dickMod = (actor.geneticQuirks.wellHung === 2 ? 2 : 1);
 	let physicalAgeSwap;
-	const tallerPC = (player && actor.height >= Height.mean(actor) + 5 && actor.bodySwap === 0);
 
 	if (actor.geneticQuirks.progeria === 2) {
 		// since progeria increases .physicalAge, we need to work around it.
@@ -15,1557 +14,109 @@ App.EndWeek.Shared.physicalDevelopment = function(actor, player = false) {
 		physicalAgeSwap = actor.physicalAge;
 	}
 	if (actor.geneMods.NCS !== 1) {
-		/* NCS completely blocks all natural physical growth: no height increases. It also blocks all hormonal secondary sexual * characteristics. So, on the female side: no boobs, no butt, no hips, and no labia. And on the male side: no dick, no clit, no balls, no scrotum, no shoulders. */
+		/* NCS completely blocks all natural physical growth: no height increases. It also blocks all hormonal secondary sexual
+		 * characteristics. So, on the female side: no boobs, no butt, no hips, and no labia. And on the male side: no dick, no clit, no balls, no scrotum, no shoulders. */
 		/* so this is a big old NO-OP to skip the physical development. */
-		if (actor.geneticQuirks.androgyny === 2) { /* takes a mix of both to create a very androgynous slave */
-			if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) {
-				increaseHeightDwarf(actor);
-			} else if (actor.geneticQuirks.gigantism === 2) {
-				increaseHeightGiant(actor);
-			} else if (actor.geneticQuirks.neoteny === 2) {
-				increaseHeightNeoteny(actor);
-			} else {
-				increaseHeightXX(actor);
-			}
-			if (actor.geneticQuirks.neoteny !== 2) {
-				if (actor.boobs - actor.boobsImplant <= 300) {
-					increaseBoobsXX(actor);
-				}
-				if (actor.dick.isBetween(0, 3) || actor.geneticQuirks.wellHung === 2) {
-					increaseDick(actor);
-				}
-				if (actor.balls.isBetween(0, 3)) {
-					increaseBalls(actor);
-				}
-				if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) {
-					increaseWetness(actor);
-				}
-				if (actor.waist < 10) {
-					increaseWaistXY(actor);
-				}
-				if (actor.hips - actor.hipsImplant < 0) {
-					increaseHipsXX(actor);
-				}
-				if (actor.butt - actor.buttImplant < 3) {
-					increaseButtXX(actor);
-				}
-			}
-			increasePregAdaptationXX(actor);
-		} else if (actor.genes === "XX") { /* loli becoming a woman */
-			if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) {
-				increaseHeightDwarf(actor);
-			} else if (actor.geneticQuirks.gigantism === 2) {
-				increaseHeightGiant(actor);
-			} else if (actor.geneticQuirks.neoteny === 2) {
-				increaseHeightNeoteny(actor);
-			} else {
-				increaseHeightXX(actor);
-			}
-			if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) {
-				increaseFaceXX(actor);
-				if (actor.voice > 1) {
-					increaseVoiceXX(actor);
-				}
-			}
-			if (actor.geneticQuirks.neoteny !== 2) {
-				increaseBoobsXX(actor);
-				if (actor.clit > 0) {
-					increaseClit(actor);
-				}
-				if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) {
-					increaseWetness(actor);
-				}
-				increaseWaistXX(actor);
-				increaseHipsXX(actor);
-				increaseButtXX(actor);
-			}
-			increasePregAdaptationXX(actor);
-		} else {
-			/* shota becoming a man */
-			if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) {
-				increaseHeightDwarf(actor);
-			} else if (actor.geneticQuirks.gigantism === 2) {
-				increaseHeightGiant(actor);
-			} else if (actor.geneticQuirks.neoteny === 2) {
-				increaseHeightNeoteny(actor);
-			} else {
-				increaseHeightXY(actor);
-			}
-			if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) {
-				increaseFaceXY(actor);
-				if (actor.voice > 1) {
-					increaseVoiceXY(actor);
-				}
-			}
-			if (actor.geneticQuirks.neoteny !== 2) {
-				increaseBoobsXY(actor);
-				if (actor.dick > 0) {
-					increaseDick(actor);
-				}
-				if (actor.balls > 0) {
-					increaseBalls(actor);
-				}
-				increaseWaistXY(actor);
-				increaseHipsXY(actor);
-				increaseButtXY(actor);
-			}
-			increasePregAdaptationXY(actor);
-		}
-	}
-
-	/**
-	 * @param {FC.HumanState} actor
-	 */
-	function increaseHeightXX(actor) {
-		if (actor.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 91) {
-					actor.height += jsEither([8, 8, 9, 9]);
-				} else if (actor.height <= 101) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 101) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 109) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 116) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 116) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 124) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 131) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 163) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 163) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 168) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 168) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 171) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 171) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 173) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			}
-		} else if (actor.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 91) {
-					actor.height += jsEither([8, 8, 9, 9, 9]);
-				} else if (actor.height <= 101) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 101) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 109) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 116) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 116) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 124) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([7, 7, 8, 8, 8]);
-				} else if (actor.height <= 131) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 163) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 163) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 168) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 168) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 171) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 171) {
-					actor.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (actor.height <= 173) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			}
-		} else if (actor.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 91) {
-					actor.height += jsEither([9, 9, 9, 10, 10]);
-				} else if (actor.height <= 101) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 101) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 109) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 116) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 116) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 124) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([8, 8, 8, 9, 9]);
-				} else if (actor.height <= 131) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 163) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 163) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 168) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 168) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 171) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 171) {
-					actor.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (actor.height <= 173) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			}
-		} else if (actor.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 91) {
-					actor.height += jsEither([8, 9, 9, 10, 10]);
-				} else if (actor.height <= 101) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 101) {
-					actor.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (actor.height <= 109) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (actor.height <= 116) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 116) {
-					actor.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (actor.height <= 124) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([7, 8, 8, 9, 9]);
-				} else if (actor.height <= 131) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([4, 5, 5, 6, 6]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (actor.height <= 163) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 163) {
-					actor.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (actor.height <= 168) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 168) {
-					actor.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (actor.height <= 171) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 171) {
-					actor.height += jsEither([4, 5, 5, 6, 6]);
-				} else if (actor.height <= 173) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			}
+		if (actor.geneticQuirks.neoteny === 2) {
+			// special case for neoteny (genetic target height does not take it into account)
+			increaseHeightNeoteny(actor);
 		} else {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 91) {
-					actor.height += jsEither([8, 8, 9, 9, 9, 10]);
-				} else if (actor.height <= 101) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 101) {
-					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (actor.height <= 109) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([6, 6, 7, 7, 7, 8]);
-				} else if (actor.height <= 116) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 116) {
-					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (actor.height <= 124) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([7, 7, 8, 8, 8, 9]);
-				} else if (actor.height <= 131) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([4, 4, 5, 5, 5, 6]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([6, 6, 7, 7, 7, 8]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (actor.height <= 163) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 163) {
-					actor.height += jsEither([6, 6, 7, 7, 7, 8]);
-				} else if (actor.height <= 168) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 168) {
-					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (actor.height <= 171) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 171) {
-					actor.height += jsEither([4, 4, 5, 5, 5, 6]);
-				} else if (actor.height <= 173) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 174) {
-					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			}
+			// giant/dwarf/sex/race/etc is already taken into account by the target height. just need to take one step towards it.
+			increaseHeight(actor);
 		}
-		// experiment - Let's see if this keeps players on average above average height or if it makes them too tall in the long run.
-		if (tallerPC) {
-			actor.height += random(0, 3);
-		}
-	}
-
-	/**
-	 * @param {FC.HumanState} actor
-	 */
-	function increaseHeightXY(actor) {
-		if (actor.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 93) {
-					actor.height += jsEither([9, 9, 10, 10]);
-				} else if (actor.height <= 103) {
-					actor.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 103) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 110) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 110) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 117) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 117) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 124) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 131) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 150) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 150) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 162) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 162) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 170) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 170) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 177) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 177) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 184) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 184) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 185) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 186) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			}
-		} else if (actor.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 93) {
-					actor.height += jsEither([9, 9, 9, 10, 10]);
-				} else if (actor.height <= 103) {
-					actor.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 103) {
-					actor.height += jsEither([7, 7, 8, 8, 8]);
-				} else if (actor.height <= 110) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 110) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 117) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 117) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 124) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 131) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 150) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 150) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (actor.height <= 162) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 162) {
-					actor.height += jsEither([7, 7, 8, 8, 8]);
-				} else if (actor.height <= 170) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 170) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 177) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 177) {
-					actor.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (actor.height <= 184) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 184) {
-					actor.height += jsEither([2, 2, 3, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 185) {
-					actor.height += jsEither([1, 1, 2, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 186) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			}
-		} else if (actor.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 93) {
-					actor.height += jsEither([10, 10, 11, 11]);
-				} else if (actor.height <= 103) {
-					actor.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 103) {
-					actor.height += jsEither([8, 8, 9, 9]);
-				} else if (actor.height <= 110) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 110) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 117) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 117) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 124) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 131) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 150) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 150) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([6, 6, 7, 7]);
-				} else if (actor.height <= 162) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 162) {
-					actor.height += jsEither([8, 8, 9, 9]);
-				} else if (actor.height <= 170) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 170) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 177) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 177) {
-					actor.height += jsEither([7, 7, 8, 8]);
-				} else if (actor.height <= 184) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 184) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 185) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 186) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				}
-			}
-		} else if (actor.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 93) {
-					actor.height += jsEither([10, 10, 10, 11, 11]);
-				} else if (actor.height <= 103) {
-					actor.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 103) {
-					actor.height += jsEither([8, 8, 8, 9, 9]);
-				} else if (actor.height <= 110) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 110) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 117) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 117) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 124) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 131) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 150) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 150) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (actor.height <= 162) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 162) {
-					actor.height += jsEither([8, 8, 8, 9, 9]);
-				} else if (actor.height <= 170) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 170) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 177) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 177) {
-					actor.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (actor.height <= 184) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 184) {
-					actor.height += jsEither([3, 3, 3, 4, 4]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 185) {
-					actor.height += jsEither([2, 2, 2, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 186) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 93) {
-					actor.height += jsEither([9, 9, 10, 10, 10, 11]);
-				} else if (actor.height <= 103) {
-					actor.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 103) {
-					actor.height += jsEither([7, 7, 8, 8, 9, 9]);
-				} else if (actor.height <= 110) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 110) {
-					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (actor.height <= 117) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 117) {
-					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (actor.height <= 124) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 124) {
-					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (actor.height <= 131) {
-					actor.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 131) {
-					actor.height += jsEither([5, 5, 6, 6, 7, 7]);
-				} else if (actor.height <= 137) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 137) {
-					actor.height += jsEither([4, 4, 5, 5, 5, 6]);
-				} else if (actor.height <= 144) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 144) {
-					actor.height += jsEither([5, 5, 6, 6, 7, 7]);
-				} else if (actor.height <= 150) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 150) {
-					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (actor.height <= 156) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 156) {
-					actor.height += jsEither([5, 5, 6, 6, 7, 7]);
-				} else if (actor.height <= 162) {
-					actor.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 162) {
-					actor.height += jsEither([7, 7, 8, 8, 9, 9]);
-				} else if (actor.height <= 170) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 170) {
-					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (actor.height <= 177) {
-					actor.height += 4;
+		// physical development EXCEPT for height stops at 18; height keeps going until 20.
+		if (physicalAgeSwap <= 18) {
+			if (actor.geneticQuirks.androgyny === 2) { /* takes a mix of both to create a very androgynous slave */
+				if (actor.geneticQuirks.neoteny !== 2) {
+					if (actor.boobs - actor.boobsImplant <= 300) {
+						increaseBoobsXX(actor);
+					}
+					if (actor.dick.isBetween(0, 3) || actor.geneticQuirks.wellHung === 2) {
+						increaseDick(actor);
+					}
+					if (actor.balls.isBetween(0, 3)) {
+						increaseBalls(actor);
+					}
+					if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) {
+						increaseWetness(actor);
+					}
+					if (actor.waist < 10) {
+						increaseWaistXY(actor);
+					}
+					if (actor.hips - actor.hipsImplant < 0) {
+						increaseHipsXX(actor);
+					}
+					if (actor.butt - actor.buttImplant < 3) {
+						increaseButtXX(actor);
+					}
 				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 177) {
-					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (actor.height <= 184) {
-					actor.height += 4;
+				increasePregAdaptationXX(actor);
+			} else if (actor.genes === "XX") { /* loli becoming a woman */
+				if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) {
+					increaseFaceXX(actor);
+					if (actor.voice > 1) {
+						increaseVoiceXX(actor);
+					}
 				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 184) {
-					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
+				if (actor.geneticQuirks.neoteny !== 2) {
+					increaseBoobsXX(actor);
+					if (actor.clit > 0) {
+						increaseClit(actor);
+					}
+					if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) {
+						increaseWetness(actor);
+					}
+					increaseWaistXX(actor);
+					increaseHipsXX(actor);
+					increaseButtXX(actor);
 				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 185) {
-					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
+				increasePregAdaptationXX(actor);
+			} else { /* shota becoming a man */
+				if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) {
+					increaseFaceXY(actor);
+					if (actor.voice > 1) {
+						increaseVoiceXY(actor);
+					}
 				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 186) {
-					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+				if (actor.geneticQuirks.neoteny !== 2) {
+					increaseBoobsXY(actor);
+					if (actor.dick > 0) {
+						increaseDick(actor);
+					}
+					if (actor.balls > 0) {
+						increaseBalls(actor);
+					}
+					increaseWaistXY(actor);
+					increaseHipsXY(actor);
+					increaseButtXY(actor);
 				}
+				increasePregAdaptationXY(actor);
 			}
 		}
-		// experiment - Let's see if this keeps players on average above average height or if it makes them too tall in the long run.
-		if (tallerPC) {
-			actor.height += random(0, 3);
-		}
 	}
 
 	/**
 	 * @param {FC.HumanState} actor
 	 */
-	function increaseHeightDwarf(actor) {
-		if (actor.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 80) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				} else if (actor.height <= 84) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 84) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 90) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 90) {
-					actor.height += jsEither([8, 8, 9, 9]);
-				} else if (actor.height <= 100) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 100) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				} else if (actor.height <= 105) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 105) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				} else if (actor.height <= 109) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				} else if (actor.height <= 114) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 114) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				} else if (actor.height <= 118) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 118) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				} else if (actor.height <= 122) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 122) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				} else if (actor.height <= 127) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 127) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				} else if (actor.height <= 132) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 132) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				} else if (actor.height <= 135) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 135) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				} else if (actor.height <= 138) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 138) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				} else if (actor.height <= 141) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1]);
-				}
-			}
-		} else if (actor.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 80) {
-					actor.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (actor.height <= 84) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 84) {
-					actor.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (actor.height <= 90) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 90) {
-					actor.height += jsEither([8, 8, 9, 9, 9]);
-				} else if (actor.height <= 100) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 100) {
-					actor.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (actor.height <= 105) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 105) {
-					actor.height += jsEither([2, 2, 3, 3, 3]);
-				} else if (actor.height <= 109) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (actor.height <= 114) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 114) {
-					actor.height += jsEither([2, 2, 3, 3, 3]);
-				} else if (actor.height <= 118) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 118) {
-					actor.height += jsEither([2, 2, 3, 3, 3]);
-				} else if (actor.height <= 122) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 122) {
-					actor.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (actor.height <= 127) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 127) {
-					actor.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (actor.height <= 132) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 132) {
-					actor.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (actor.height <= 135) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 135) {
-					actor.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (actor.height <= 138) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 138) {
-					actor.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (actor.height <= 141) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			}
-		} else if (actor.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 80) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				} else if (actor.height <= 84) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 84) {
-					actor.height += jsEither([5, 5, 6, 6]);
-				} else if (actor.height <= 90) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 90) {
-					actor.height += jsEither([9, 9, 10, 10]);
-				} else if (actor.height <= 100) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 100) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 105) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 105) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				} else if (actor.height <= 109) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 114) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 114) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				} else if (actor.height <= 118) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 118) {
-					actor.height += jsEither([3, 3, 4, 4]);
-				} else if (actor.height <= 122) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 122) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 127) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 127) {
-					actor.height += jsEither([4, 4, 5, 5]);
-				} else if (actor.height <= 132) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 132) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				} else if (actor.height <= 135) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 135) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				} else if (actor.height <= 138) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 138) {
-					actor.height += jsEither([2, 2, 3, 3]);
-				} else if (actor.height <= 141) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([1, 1, 2, 2]);
-				}
-			}
-		} else if (actor.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 80) {
-					actor.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (actor.height <= 84) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 84) {
-					actor.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (actor.height <= 90) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 90) {
-					actor.height += jsEither([9, 9, 9, 10, 10]);
-				} else if (actor.height <= 100) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 100) {
-					actor.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (actor.height <= 105) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 105) {
-					actor.height += jsEither([3, 3, 3, 4, 4]);
-				} else if (actor.height <= 109) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (actor.height <= 114) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 114) {
-					actor.height += jsEither([3, 3, 3, 4, 4]);
-				} else if (actor.height <= 118) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 118) {
-					actor.height += jsEither([3, 3, 3, 4, 4]);
-				} else if (actor.height <= 122) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 122) {
-					actor.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (actor.height <= 127) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 127) {
-					actor.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (actor.height <= 132) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 132) {
-					actor.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (actor.height <= 135) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 135) {
-					actor.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (actor.height <= 138) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 138) {
-					actor.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (actor.height <= 141) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 3) {
-				if (actor.height <= 80) {
-					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (actor.height <= 84) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (actor.height <= 84) {
-					actor.height += jsEither([4, 4, 5, 5, 6, 6]);
-				} else if (actor.height <= 90) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (actor.height <= 90) {
-					actor.height += jsEither([8, 8, 9, 9, 10, 10]);
-				} else if (actor.height <= 100) {
-					actor.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (actor.height <= 100) {
-					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (actor.height <= 105) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (actor.height <= 105) {
-					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
-				} else if (actor.height <= 109) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (actor.height <= 109) {
-					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (actor.height <= 114) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (actor.height <= 114) {
-					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
-				} else if (actor.height <= 118) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (actor.height <= 118) {
-					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
-				} else if (actor.height <= 122) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (actor.height <= 122) {
-					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (actor.height <= 127) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (actor.height <= 127) {
-					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (actor.height <= 132) {
-					actor.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (actor.height <= 132) {
-					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (actor.height <= 135) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (actor.height <= 135) {
-					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (actor.height <= 138) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (actor.height <= 138) {
-					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (actor.height <= 141) {
-					actor.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (actor.height <= 143) {
-					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
-				}
-			}
+	function increaseHeight(actor) {
+		const unalteredHeight = actor.height - actor.heightImplant * 10;
+		const lastYearsTarget = Height.forAge(actor.natural.height, physicalAgeSwap - 1, actor.genes);
+		const thisYearsTarget = Height.forAge(actor.natural.height, physicalAgeSwap, actor.genes);
+		// by default, grow by the difference in natural height targets, +1/-2 cm
+		// slightly undershooting on average is intentional, since we can't shrink but we CAN have growth spurts
+		let thisYearsGrowth = thisYearsTarget - lastYearsTarget + jsRandom(-2, 1);
+		// if we're way ahead of target or way behind target, adjust towards it a bit harder
+		// if the player doesn't interfere, this mechanism should always end up within 2cm of the target at age 20, with slightly "spurty" growth
+		const deltaFromTarget = thisYearsTarget - (unalteredHeight + thisYearsGrowth);
+		const yearsLeft = Math.min(5, 21 - physicalAgeSwap);
+		if (deltaFromTarget >= yearsLeft) {
+			thisYearsGrowth = Math.max(0, thisYearsGrowth) + 2;
+		} else if (deltaFromTarget <= -yearsLeft) {
+			thisYearsGrowth = Math.min(0, thisYearsGrowth) - 2;
 		}
-	}
-
-	/**
-	 * @param {FC.HumanState} actor
-	 */
-	function increaseHeightGiant(actor) {
-		if (actor.hormoneBalance >= 200) {
-			if (physicalAgeSwap < 16) {
-				if (actor.height <= 270) {
-					actor.height += random(5, 12);
-				}
-			} else {
-				if (actor.height <= 270) {
-					actor.height += random(3, 7);
-				}
-			}
-		} else if (actor.hormoneBalance >= 100) {
-			if (physicalAgeSwap < 16) {
-				if (actor.height <= 270) {
-					actor.height += random(7, 15);
-				}
-			} else {
-				if (actor.height <= 270) {
-					actor.height += random(5, 7);
-				}
-			}
-		} else if (actor.hormoneBalance <= -200) {
-			if (physicalAgeSwap < 16) {
-				if (actor.height <= 270) {
-					actor.height += random(10, 25);
-				}
-			} else {
-				if (actor.height <= 270) {
-					actor.height += random(7, 13);
-				}
-			}
-		} else if (actor.hormoneBalance <= -100) {
-			if (physicalAgeSwap < 16) {
-				if (actor.height <= 270) {
-					actor.height += random(7, 22);
-				}
-			} else {
-				if (actor.height <= 270) {
-					actor.height += random(7, 12);
-				}
-			}
-		} else {
-			if (physicalAgeSwap < 16) {
-				if (actor.height <= 270) {
-					actor.height += random(7, 20);
-				}
-			} else {
-				if (actor.height <= 270) {
-					actor.height += random(5, 10);
-				}
-			}
+		// never shrink
+		if (thisYearsGrowth > 0) {
+			actor.height += Math.round(thisYearsGrowth);
 		}
 	}
 
diff --git a/src/events/RE/reShippingContainer.js b/src/events/RE/reShippingContainer.js
index 05661da1cce1360648a1a5bc84d48be39fa86094..60e1c5f5e0003565b11b29f9b201bf41fe7561fd 100644
--- a/src/events/RE/reShippingContainer.js
+++ b/src/events/RE/reShippingContainer.js
@@ -17,7 +17,7 @@ App.Events.REShippingContainer = class REShippingContainer extends App.Events.Ba
 
 		const newSlaves = [];
 		for (let reShip = 0; reShip < 5; reShip++) {
-			const slave = GenerateNewSlave("XX");
+			const slave = GenerateNewSlave((V.seeDicks !== 100) ? "XX" : "XY");
 			slave.origin = "$He arrived at your arcology in an undocumented shipping container.";
 			slave.devotion = random(-90, -75);
 			slave.trust = -20;
diff --git a/src/events/intro/acquisition.js b/src/events/intro/acquisition.js
index 1129083c2b8c42871c9a9115fb4ac07bb0499ffa..f8718ee8367229eec565273633a4e38b2d5eddc4 100644
--- a/src/events/intro/acquisition.js
+++ b/src/events/intro/acquisition.js
@@ -373,14 +373,12 @@ App.Intro.acquisition = function() {
 			V.PC.trueVirgin = 1;
 		}
 		if (V.PC.geneticQuirks.albinism === 2) {
-			V.PC.albinismOverride = makeAlbinismOverride(V.PC.race);
 			V.PC.skin = getGeneticSkinColor(V.PC);
 			V.PC.hColor = getGeneticHairColor(V.PC);
 			resetEyeColor(V.PC, "both");
 		}
 	}
 
-
 	function parentSetup() {
 		/** @type {Map<number, number>} */
 		const missingMap = new Map();
@@ -1003,6 +1001,7 @@ App.Intro.acquisition = function() {
 							slave.geneticQuirks.dwarfism = 2;
 						}
 					}
+					slave.natural.height = slave.height;
 				}
 				slave.skill.oral = random(35, 65);
 				slave.skill.anal = random(15, 35);
@@ -1035,6 +1034,7 @@ App.Intro.acquisition = function() {
 							slave.geneticQuirks.gigantism = 2;
 						}
 					}
+					slave.natural.height = slave.height;
 				}
 				slave.skill.oral = random(15, 35);
 				slave.skill.anal = random(15, 35);
diff --git a/src/events/intro/introSummary.js b/src/events/intro/introSummary.js
index b4e33818e101639220a3e459711d8ad3cf9e8f9d..5baa94df043d8b12de14a8b660184dff5644ad0a 100644
--- a/src/events/intro/introSummary.js
+++ b/src/events/intro/introSummary.js
@@ -5,6 +5,7 @@ App.Intro.summary = function() {
 	V.FSCreditCount = variableAsNumber(V.FSCreditCount, 4, 7, 5);
 	V.PC.actualAge = variableAsNumber(V.PC.actualAge, 10, 80, 35);
 	V.PC.height = variableAsNumber(V.PC.height, 85, 305, 185);
+	V.PC.natural.height = variableAsNumber(V.PC.natural.height, 85, 305, 185);
 	V.PC.boobs = variableAsNumber(V.PC.boobs, 100, 50000, 200);
 	V.PC.pubertyAgeXX = variableAsNumber(V.PC.pubertyAgeXX, 8, 13, 13);
 	V.PC.pubertyAgeXY = variableAsNumber(V.PC.pubertyAgeXY, 8, 13, 13);
diff --git a/src/events/intro/pcAppearance.js b/src/events/intro/pcAppearance.js
index ad43fb8b35dbf43a49feb3f73284b39471cbc15d..82a7f7df9c1f3b9ec89fddcf5f957f9919196d6c 100644
--- a/src/events/intro/pcAppearance.js
+++ b/src/events/intro/pcAppearance.js
@@ -18,19 +18,44 @@ App.UI.Player.appearance = function(options, summary = false) {
 	options.addOption("You are genetically", "genes", V.PC)
 		.addValue("XY").addValue("XX");
 
-	options.addOption(`You are`, "height", V.PC).showTextBox({unit: "cm"})
-		.addRange(145, 150, "<", "Petite")
-		.addRange(155, 160, "<", "Short")
-		.addRange(165, 170, "<", "Average")
-		.addRange(180, 185, "<", "Tall")
-		.addRange(190, 185, ">=", "Very tall")
-		.addComment(`Average height for a ${V.PC.physicalAge} year old is ${heightToEitherUnit(Height.mean(V.PC))}`);
+	if (V.PC.physicalAge >= 20) {
+		options.addOption(`You are`, "height", V.PC.natural).showTextBox({unit: "cm"})
+			.addRange(145, 150, "<", "Petite")
+			.addRange(155, 160, "<", "Short")
+			.addRange(165, 170, "<", "Average")
+			.addRange(180, 185, "<", "Tall")
+			.addRange(190, 185, ">=", "Very tall")
+			.addComment(`Average height is ${heightToEitherUnit(Height.mean(V.PC))}`)
+			.addCallback(() => V.PC.height = V.PC.natural.height);
+	} else {
+		options.addOption(`When full-grown, you will be`, "height", V.PC.natural).showTextBox({unit: "cm"})
+			.addRange(145, 150, "<", "Petite")
+			.addRange(155, 160, "<", "Short")
+			.addRange(165, 170, "<", "Average")
+			.addRange(180, 185, "<", "Tall")
+			.addRange(190, 185, ">=", "Very tall");
+	}
 	option = options.addCustomOption()
 		.addButton(
 			"Make average",
 			() => resyncSlaveHeight(V.PC),
 			""
 		);
+	if (V.PC.physicalAge < 20) {
+		options.addOption(`But right now, you are`, "height", V.PC).showTextBox({unit: "cm"})
+			.addRange(Height.forAge(145, V.PC), Height.forAge(150, V.PC), "<", "Petite for your age")
+			.addRange(Height.forAge(155, V.PC), Height.forAge(160, V.PC), "<", "Short for your age")
+			.addRange(Height.forAge(165, V.PC), Height.forAge(170, V.PC), "<", "Average for your age")
+			.addRange(Height.forAge(180, V.PC), Height.forAge(185, V.PC), "<", "Tall for your age")
+			.addRange(Height.forAge(190, V.PC), Height.forAge(185, V.PC), ">=", "Very tall for your age")
+			.addComment(`Average height for a ${V.PC.physicalAge} year old is ${heightToEitherUnit(Height.mean(V.PC))}`);
+		option = options.addCustomOption()
+			.addButton(
+				"Scale for age from adult height",
+				() => V.PC.height = Height.forAge(V.PC.natural.height, V.PC),
+				""
+			);
+	}
 
 	options.addOption("Your skin tone is", "skin", V.PC).showTextBox()
 		.addValueList(makeAList(V.PC.race === "catgirl" ? App.Medicine.Modification.catgirlNaturalSkins : App.Medicine.Modification.naturalSkins));
@@ -76,6 +101,7 @@ App.UI.Player.appearance = function(options, summary = false) {
 				["An albino", 2],
 				["Not an albino", 0],
 			])
+			.addGlobalCallback((val) => induceAlbinism(V.PC, val))
 			.addComment("Once this is set, you may change your hair/eyes/skin without worry. You will generate as an albino.");
 	}
 
@@ -298,7 +324,7 @@ App.UI.Player.syncAgeBasedParameters = function() {
 	V.PC.physicalAge = V.PC.actualAge;
 	V.PC.visualAge = V.PC.actualAge;
 	V.PC.ovaryAge = V.PC.actualAge;
-	V.PC.height = Height.random(V.PC, {limitMult: [1, 2]});
+	V.PC.height = Height.forAge(V.PC.natural.height, V.PC);
 	if (V.PC.genes === "XY") {
 		if (V.PC.physicalAge <= 13) {
 			V.PC.hips = -2;
diff --git a/src/events/nonRandom/pAidResult.js b/src/events/nonRandom/pAidResult.js
index 7882f1e68ce43da45bc76975ffed1ae716fe9df0..b845aa3e6354a187ea14b8a770fa61a0a624ba12 100644
--- a/src/events/nonRandom/pAidResult.js
+++ b/src/events/nonRandom/pAidResult.js
@@ -249,7 +249,8 @@ App.Events.pAidResult = class pAidResult extends App.Events.BaseEvent {
 				slave = GenerateNewSlave("XX", {
 					disableDisability: 1, ageOverridesPedoMode: 1, minAge: 18, maxAge: 18
 				});
-				slave.height = Height.random(slave, {skew: 1, limitMult: [0, 2]});
+				slave.natural.height = Height.randomAdult(slave, {skew: 1, limitMult: [0.5, 2.5]});
+				slave.height = Height.forAge(slave.natural.height, slave);
 				slave.origin = "$He was a volleyball player you enslaved when you evacuated $him from a broken down bus.";
 				slave.career = "a student athlete";
 				generateSalonModifications(slave);
diff --git a/src/events/nonRandom/pSchoolSuggestion.js b/src/events/nonRandom/pSchoolSuggestion.js
index ead7004b8f2f95c516aa6ddf45e527627fe461d7..8af37ebfa4d037394ac77c7179c636280ab5870b 100644
--- a/src/events/nonRandom/pSchoolSuggestion.js
+++ b/src/events/nonRandom/pSchoolSuggestion.js
@@ -17,10 +17,11 @@ App.Events.PSchoolSuggestion = class PSchoolSuggestion extends App.Events.BaseEv
 
 		App.Events.addParagraph(node, [`It seems a young, thin woman in a modern business suit was concluding her own argument when you arrived. "In summation, I propose we offer our support for Nueva Universidad de Libertad," says the woman, who you now realize is a very feminine man. "Nullification may seem extreme, but serves to expand the potential market amongst more... traditional slaveowners," says the man, who you <i>now</i> realize is a woman who merely looks like a very feminine man.`]);
 
-		App.Events.addParagraph(node, [`"I believe what you need in a slave is a good base. As such, The Utopian Orphanage is the best. They offer slaves who were raised with careful attention; they're beautiful, smart, well-educated and unspoiled." The young surgeon continues. "No traumas, a happy childhood, obedient and trusting. You can then mold them to your will as you please; I have enough faith in my skills to achieve the results I desire myself."`]);
-
 		if (V.seeDicks !== 100) {
+			App.Events.addParagraph(node, [`"I believe what you need in a slave is a good base. As such, The Utopian Orphanage is the best. They offer girls who were raised with careful attention; they're beautiful, smart, well-educated and unspoiled." The young surgeon continues. "No traumas, a happy childhood, obedient and trusting. You can then mold them to your will as you please; I have enough faith in my skills to achieve the results I desire myself."`]);
+
 			App.Events.addParagraph(node, [`"The Slave School for me," says a portly man with a thriving slave breaking business down in the markets. "Their girls are pretty, skilled, and innocent, without any of that weird crap the other schools go in for. Besides, all that special stuff drives up the prices. TSS girls are cheap for what you get. When you're tired of one, just buy another." He turns to his friend and business partner, a much thinner man. "Though I'm sure you disagree with me."`]);
+
 			App.Events.addParagraph(node, [`"Of course I do, we've been having this debate every day for ten years." The thin man laughs. "Hasn't hurt our company, though. Anyway, I'm a GRI man. It's much harder to change a girl's body than it is to train her mind. The Growth Research Institute might sell their girls with no training and some nasty flaws, but you can fix those faster than you can grow a well-trained skinny girl's tits out to <i>here</i>," and he gestures far out in front of his own chest.`]);
 
 			App.Events.addParagraph(node, [`An older woman standing across from him sniffs. "St. Claver's knows how to do both. They train them right, and if they aren't perfectly made, well, that's what plastic surgery is for." She favors the group with a sharp smile. "The best part is that between the silicone and their, ahem, strict training, they're all the same. Once you get used to their girls, you can always rely on them to give you more of what you like."`]);
diff --git a/src/events/reRecruit/orphanFemboy.js b/src/events/reRecruit/orphanFemboy.js
index 3224281851eb8294fcc23ad08a4f17acf4d60143..c7c8ca064a44c8e8aa2217b112a0e338f2b4f764 100644
--- a/src/events/reRecruit/orphanFemboy.js
+++ b/src/events/reRecruit/orphanFemboy.js
@@ -73,7 +73,8 @@ App.Events.recOrphanFemboy = class recOrphanFemboy extends App.Events.BaseEvent
 			slave.scrotum = slave.balls;
 			slave.pubicHStyle = "waxed";
 			slave.underArmHStyle = "waxed";
-			slave.height = random(140, 170);
+			slave.natural.height = random(140, 170);
+			slave.height = Height.forAge(slave.natural.height, slave);
 			slave.hips = random(-1, 0);
 			slave.butt = 1;
 			slave.anus = 1;
diff --git a/src/events/reRecruit/racerDgChaser.js b/src/events/reRecruit/racerDgChaser.js
index 06347da66a3ad7dc638aee4b96d741a3612ec738..ab40f18f094331484412fb201a8db1d9b8acadb0 100644
--- a/src/events/reRecruit/racerDgChaser.js
+++ b/src/events/reRecruit/racerDgChaser.js
@@ -74,7 +74,8 @@ App.Events.recRacerDgChaser = class recRacerDgChaser extends App.Events.BaseEven
 			slave.dick = random(4, 5);
 			slave.balls = random(3, 4);
 			slave.scrotum = slave.balls;
-			slave.height = Height.forAge(random(180, 200), slave);
+			slave.natural.height = random(180, 200);
+			slave.height = Height.forAge(slave.natural.height, slave);
 			slave.weight = 0;
 			slave.muscles = 50;
 			slave.intelligence = random(-50, 50);
diff --git a/src/events/reRecruit/racerLoser.js b/src/events/reRecruit/racerLoser.js
index dd73371cc025768fe3fad3550d8b152bd2088462..59e9a315772d5990822e467f8257387439b58ea5 100644
--- a/src/events/reRecruit/racerLoser.js
+++ b/src/events/reRecruit/racerLoser.js
@@ -85,7 +85,8 @@ App.Events.recRacerLoser = class recRacerLoser extends App.Events.BaseEvent {
 			WombImpregnate(slave, slave.pregType, slave.pregSource, 0);
 			slave.pubicHStyle = "waxed";
 			slave.underArmHStyle = "waxed";
-			slave.height = Height.forAge(random(180, 200), slave);
+			slave.natural.height = random(180, 200);
+			slave.height = Height.forAge(slave.natural.height, slave);
 			slave.hips = -1;
 			slave.butt = 0;
 			slave.anus = 0;
diff --git a/src/events/reRecruit/racerWinner.js b/src/events/reRecruit/racerWinner.js
index 7f6fce10e2d4e6554fa7265042981ef848ff8529..911dadacc49bd697ca57da1e3dae8661d196231c 100644
--- a/src/events/reRecruit/racerWinner.js
+++ b/src/events/reRecruit/racerWinner.js
@@ -84,7 +84,8 @@ App.Events.recRacerWinner = class recRacerWinner extends App.Events.BaseEvent {
 			slave.preg = -1;
 			slave.pubicHStyle = "waxed";
 			slave.underArmHStyle = "waxed";
-			slave.height = Height.forAge(random(180, 200), slave);
+			slave.natural.height = random(180, 200);
+			slave.height = Height.forAge(slave.natural.height, slave);
 			slave.shoulders = random(-1, 1);
 			slave.hips = -1;
 			slave.butt = 0;
diff --git a/src/events/reRecruit/starvingArtist.js b/src/events/reRecruit/starvingArtist.js
index 4b62ba3121aa7b07f70b12953d96bc938feace7c..372a873f9ed6f09bbb570fd43e890d52c6a047d5 100644
--- a/src/events/reRecruit/starvingArtist.js
+++ b/src/events/reRecruit/starvingArtist.js
@@ -59,7 +59,8 @@ App.Events.recStarvingArtist = class recStarvingArtist extends App.Events.BaseEv
 			slave.origin = "$He offered $himself to you for enslavement out of devotion to $his artistic 'craft'.";
 			slave.boobs = random(4, 6) * 50;
 			slave.weight = -20;
-			slave.height = Height.forAge(random(160, 200), slave);
+			slave.natural.height = random(160, 200);
+			slave.height = Height.forAge(slave.natural.height, slave);
 			slave.face = random(15, 100);
 			slave.butt = random(1, 2);
 			slave.lips = 0;
diff --git a/src/events/recETS/recetsIncestBrotherBrother.js b/src/events/recETS/recetsIncestBrotherBrother.js
index f32c9036ae9b21ea231589f0d2062833c2d5e8a7..3744891a0881ad67a3ce65f364077e351cbb1fcc 100644
--- a/src/events/recETS/recetsIncestBrotherBrother.js
+++ b/src/events/recETS/recetsIncestBrotherBrother.js
@@ -37,7 +37,6 @@ App.Events.recetsIncestBrotherBrother = class recetsIncestBrotherBrother extends
 		brother1.relationship = 3;
 
 		const brother2 = generateRelatedSlave(brother1, "younger brother");
-		brother2.height += random(-5, 5);
 		brother2.pubicHStyle = "shaved";
 		brother2.dick += 2;
 		brother2.balls += 2;
diff --git a/src/events/recETS/recetsIncestTwinBrother.js b/src/events/recETS/recetsIncestTwinBrother.js
index 8ab785f01258588c744138c8b8ef81215b3bfdfa..c7f204555c0cbd59da0fe394edb8462c9e904f42 100644
--- a/src/events/recETS/recetsIncestTwinBrother.js
+++ b/src/events/recETS/recetsIncestTwinBrother.js
@@ -37,7 +37,6 @@ App.Events.recetsIncestTwinBrother = class recetsIncestTwinBrother extends App.E
 		brother1.relationship = 3;
 
 		const brother2 = generateRelatedSlave(brother1, "twin");
-		brother2.height += random(-5, 5);
 		brother2.energy = Math.max(brother2.energy, 40);
 		brother2.attrXY = Math.max(brother2.attrXY, 70);
 		if (brother2.behavioralFlaw === "hates men") {
diff --git a/src/events/recETS/recetsIncestTwinSister.js b/src/events/recETS/recetsIncestTwinSister.js
index 091551daba1c0aa53aff34f6db38158740bd63df..8ee9b5161889c50dd933b4682e5ab9210895b54b 100644
--- a/src/events/recETS/recetsIncestTwinSister.js
+++ b/src/events/recETS/recetsIncestTwinSister.js
@@ -39,7 +39,6 @@ App.Events.recetsIncestTwinSister = class recetsIncestTwinSister extends App.Eve
 
 		const sis2 = generateRelatedSlave(sis1, "twin");
 		sis2.slaveName = sis2.birthName;
-		sis2.height += random(-5, 5);
 		sis2.energy = Math.max(sis2.energy, 40);
 		sis2.attrXX = Math.max(sis2.attrXX, 70);
 		if (sis2.behavioralFlaw === "hates women") {
diff --git a/src/events/recETS/recetsIncestTwinsMixed.js b/src/events/recETS/recetsIncestTwinsMixed.js
index b8f46f391e77f63a4c5b6854ae8a61af278e4013..6bcb38c8bae197ce47d8ff93ba1bca10b396b7ae 100644
--- a/src/events/recETS/recetsIncestTwinsMixed.js
+++ b/src/events/recETS/recetsIncestTwinsMixed.js
@@ -40,7 +40,6 @@ App.Events.recetsIncestTwinsMixed = class recetsIncestTwinsMixed extends App.Eve
 		sis.relationship = 3;
 
 		const bro = generateRelatedSlave(sis, "twin", true);
-		bro.height += random(-5, 5);
 		bro.vagina = -1;
 		bro.dick = 2;
 		bro.foreskin = 2;
diff --git a/src/events/recFS/recfsPetiteAdmiration.js b/src/events/recFS/recfsPetiteAdmiration.js
index c016347525bcdf4ff3badbea79524b455ee4740e..5d7e091ed0c7b3fc874eddb4261f8f59252d7e32 100644
--- a/src/events/recFS/recfsPetiteAdmiration.js
+++ b/src/events/recFS/recfsPetiteAdmiration.js
@@ -11,15 +11,16 @@ App.Events.recFSPetiteAdmiration = class recFSPetiteAdmiration extends App.Event
 		const slave = GenerateNewSlave(null, {minAge: 13, maxAge: 22, disableDisability: 1});
 		generateSalonModifications(slave);
 		slave.origin = "$He offered $himself for voluntary enslavement to avoid being singled out by ruthless slavers.";
-		if (slave.height >= Height.forAge(150, slave)) {
-			slave.height = Height.random(slave, {limitMult: [-2, 0]});
-			if (slave.height >= Height.forAge(150, slave)) {
-				slave.height = Height.random(slave, {limitMult: [-3, -1]});
-				if (slave.height >= Height.forAge(150, slave)) {
-					slave.height = Height.forAge(random(90, 130), slave);
+		if (slave.natural.height >= 150) {
+			slave.natural.height = Height.randomAdult(slave, {limitMult: [-2, 0]});
+			if (slave.natural.height >= 150) {
+				slave.natural.height = Height.randomAdult(slave, {limitMult: [-3, -1]});
+				if (slave.natural.height >= 150) {
+					slave.natural.height = random(90, 130);
 					slave.geneticQuirks.dwarfism = 2;
 				}
 			}
+			slave.height = Height.forAge(slave.natural.height, slave);
 		}
 		setHealth(slave, jsRandom(20, 40), undefined, undefined, 0, 0);
 		slave.face = Math.clamp(slave.face+80, -100, 100);
diff --git a/src/events/recFS/recfsPetiteAdmirationTwo.js b/src/events/recFS/recfsPetiteAdmirationTwo.js
index 4f1bf7ca5f1b82ed6de92bec910e359724b97b21..294e55743373d75de419f2f9d983a8cb55f171e7 100644
--- a/src/events/recFS/recfsPetiteAdmirationTwo.js
+++ b/src/events/recFS/recfsPetiteAdmirationTwo.js
@@ -20,7 +20,8 @@ App.Events.recFSPetiteAdmirationTwo = class recFSPetiteAdmirationTwo extends App
 		slave.career = "a porn star";
 		generateSalonModifications(slave);
 		slave.origin = "$He offered $himself to you for enslavement because $he felt your arcology would be a nice place to retire to.";
-		slave.height = random(90, 100);
+		slave.natural.height = random(90, 100);
+		slave.height = slave.natural.height;
 		slave.geneticQuirks.dwarfism = 2;
 		slave.boobsImplant += random(4, 6)*200;
 		slave.boobs += slave.boobsImplant;
diff --git a/src/events/recFS/recfsSlimnessEnthusiast.js b/src/events/recFS/recfsSlimnessEnthusiast.js
index 64dd26301cde6c9690bacb209ee0b893e2f0c46a..c0a04697fd137ec2c6e9ed2ac641fe61ece3f7c1 100644
--- a/src/events/recFS/recfsSlimnessEnthusiast.js
+++ b/src/events/recFS/recfsSlimnessEnthusiast.js
@@ -22,7 +22,8 @@ App.Events.recFSSlimnessEnthusiast = class recFSSlimnessEnthusiast extends App.E
 		slave.origin = "$He offered $himself to you for enslavement because $he felt your arcology was the best place for a $woman of $his appearance.";
 		slave.boobs = random(4, 6)*50;
 		slave.weight = -20;
-		slave.height = random(160, 200);
+		slave.natural.height = random(160, 200);
+		slave.height = slave.natural.height;
 		slave.face = random(15, 100);
 		slave.butt = random(1, 2);
 		slave.lips = 0;
diff --git a/src/events/recFS/recfsSlimnessEnthusiastTwo.js b/src/events/recFS/recfsSlimnessEnthusiastTwo.js
index 069960a74a3c6b3161e1a9becf47878c717950da..b8660fa09b4136981c7458db1661ad014680c565 100644
--- a/src/events/recFS/recfsSlimnessEnthusiastTwo.js
+++ b/src/events/recFS/recfsSlimnessEnthusiastTwo.js
@@ -13,7 +13,8 @@ App.Events.recFSSlimnessEnthusiastTwo = class recFSSlimnessEnthusiastTwo extends
 		slave.origin = "$He offered $himself to you for enslavement to escape having plastic surgery foisted on $him.";
 		slave.boobs = random(4, 6)*50;
 		slave.weight = -20;
-		slave.height = random(160, 200);
+		slave.natural.height = random(160, 200);
+		slave.height = slave.natural.height;
 		slave.face = random(15, 100);
 		slave.butt = random(1, 2);
 		slave.lips = 0;
diff --git a/src/events/recFS/recfsStatuesqueGlorification.js b/src/events/recFS/recfsStatuesqueGlorification.js
index a8701cd3b7b499207e9c4cdb148589c803017a85..9e22ea676caa876e6e0547bf9a5cd610d6abb3bd 100644
--- a/src/events/recFS/recfsStatuesqueGlorification.js
+++ b/src/events/recFS/recfsStatuesqueGlorification.js
@@ -18,7 +18,8 @@ App.Events.recFSStatuesqueGlorification = class recFSStatuesqueGlorification ext
 		const slave = GenerateNewSlave(null, {disableDisability: 1});
 		generateSalonModifications(slave);
 		slave.origin = "$He offered $himself for voluntary enslavement to avoid being singled out by ruthless slavers.";
-		slave.height = Height.forAge(random(200, 264), slave);
+		slave.natural.height = random(200, 264);
+		slave.height = Height.forAge(slave.natural.height, slave);
 		setHealth(slave, jsRandom(20, 40), undefined, undefined, 0, 0);
 		slave.geneticQuirks.gigantism = 2;
 		slave.devotion = random(15, 20);
diff --git a/src/events/recFS/recfsStatuesqueGlorificationTwo.js b/src/events/recFS/recfsStatuesqueGlorificationTwo.js
index 7ba3ebf7ab06a76a9aae4573ac6d916ec1635587..dfd7bcefebbdd31d290b0cde529092d8a6d5afcb 100644
--- a/src/events/recFS/recfsStatuesqueGlorificationTwo.js
+++ b/src/events/recFS/recfsStatuesqueGlorificationTwo.js
@@ -10,7 +10,8 @@ App.Events.recFSStatuesqueGlorificationTwo = class recFSStatuesqueGlorificationT
 		let r = [];
 		const slave = GenerateNewSlave(null, {disableDisability: 1});
 		slave.origin = "$He offered $himself for voluntary enslavement knowing $he would only fit in with your help.";
-		slave.height = 165;
+		slave.natural.height = 165;
+		slave.height = Height.forAge(slave.natural.height, slave);
 		setHealth(slave, jsRandom(20, 40), undefined, undefined, 0, 0);
 		slave.shoes = "extreme heels";
 		slave.devotion = random(30, 45);
diff --git a/src/events/scheduled/assholeKnight.js b/src/events/scheduled/assholeKnight.js
index 98014450cd255ce3def4a3e0de6e0eeefd78d4ce..77123c11534d50412c50298f47abb69514402b0d 100644
--- a/src/events/scheduled/assholeKnight.js
+++ b/src/events/scheduled/assholeKnight.js
@@ -23,7 +23,8 @@ App.Events.SEAssholeKnight = class SEAssholeKnight extends App.Events.BaseEvent
 		assholeKnight.behavioralQuirk = "none";
 		assholeKnight.trust = random(-30, -20);
 		assholeKnight.butt = random(0, 1);
-		assholeKnight.height = random(175, 195);
+		assholeKnight.natural.height = random(175, 195);
+		assholeKnight.height = assholeKnight.natural.height;
 		assholeKnight.fetish = "sadist";
 		assholeKnight.fetishStrength = 80;
 		assholeKnight.preg = 0;
diff --git a/src/events/scheduled/seCustomSlaveDelivery.js b/src/events/scheduled/seCustomSlaveDelivery.js
index 3fc0fa58f9759c7f164ee6f7592142c0b6488932..6fce1c98df4fb76f06b4edd8b87279b10dfae3f7 100644
--- a/src/events/scheduled/seCustomSlaveDelivery.js
+++ b/src/events/scheduled/seCustomSlaveDelivery.js
@@ -193,16 +193,17 @@ App.Events.SEcustomSlaveDelivery = class SEcustomSlaveDelivery extends App.Event
 
 			/* I have no clue what I'm doing here */
 			if (V.customSlave.heightMod === "greatly below average") {
-				delivery.height = Height.random(delivery, {skew: -5, spread: 0.15, limitMult: [-5, -2]});
+				delivery.natural.height = Height.randomAdult(delivery, {skew: -5, spread: 0.15, limitMult: [-5, -2]});
 			} else if (V.customSlave.heightMod === "below average") {
-				delivery.height = Height.random(delivery, {skew: -1, limitMult: [-2, 0]});
+				delivery.natural.height = Height.randomAdult(delivery, {skew: -1, limitMult: [-2, 0]});
 			} else if (V.customSlave.heightMod === "normal") {
-				delivery.height = Height.random(delivery, {limitMult: [-1, 1]});
+				delivery.natural.height = Height.randomAdult(delivery, {limitMult: [-1, 1]});
 			} else if (V.customSlave.heightMod === "above average") {
-				delivery.height = Height.random(delivery, {skew: 1, limitMult: [0, 2]});
+				delivery.natural.height = Height.randomAdult(delivery, {skew: 1, limitMult: [0, 2]});
 			} else {
-				delivery.height = Height.random(delivery, {skew: 5, spread: 0.15, limitMult: [2, 5]});
+				delivery.natural.height = Height.randomAdult(delivery, {skew: 5, spread: 0.15, limitMult: [2, 5]});
 			}
+			delivery.height = Height.forAge(delivery.natural.height, delivery);
 
 			if (V.customSlave.intelligence === 3) {
 				delivery.intelligence = random(96, 100);
diff --git a/src/events/scheduled/seRecruiterSuccess.js b/src/events/scheduled/seRecruiterSuccess.js
index 68e7acbdab755d1592829856f8816e08a77d3daa..3855c82e52d666c3c86367128e173aeeedbc81f8 100644
--- a/src/events/scheduled/seRecruiterSuccess.js
+++ b/src/events/scheduled/seRecruiterSuccess.js
@@ -141,7 +141,8 @@ App.Events.SERecruiterSuccess = class SERecruiterSuccess extends App.Events.Base
 				slave.intelligence = Intelligence.random({limitIntelligence: [40, 100]});
 			}
 			if (V.policies.SMR.eugenics.heightSMR === 1) {
-				slave.height = Height.mean(slave) + random(15, 30);
+				slave.natural.height = Height.mean(slave.nationality, slave.race, slave.genes, 20) + random(15, 30);
+				slave.height = Height.forAge(slave.natural.height, slave);
 			}
 			if (V.policies.SMR.eugenics.faceSMR === 1) {
 				slave.face = random(40, 100);
diff --git a/src/facilities/nursery/utils/nurseryUtils.js b/src/facilities/nursery/utils/nurseryUtils.js
index 914c006e347d7d037271d8193429749f809e9660..7240d517b2f56b2e21aa0bdfd110963ff4121a18 100644
--- a/src/facilities/nursery/utils/nurseryUtils.js
+++ b/src/facilities/nursery/utils/nurseryUtils.js
@@ -200,7 +200,6 @@ App.Facilities.Nursery.infantToChild = function infantToChild(child) {
 	setHealth(child, jsRandom(80, 100), 0, 0, 0, 0);
 	child.hears = 0;
 	child.heels = 0;
-	child.height = jsRandom(85, 105);
 	child.hips = 0;
 	child.hormoneBalance = 0;
 	child.hormones = 0;
@@ -354,6 +353,7 @@ App.Facilities.Nursery.infantToChild = function infantToChild(child) {
 	child.wombImplant = "none";
 	resetEyeColor(child, "both");
 	generatePronouns(child);
+	child.height = Height.forAge(child.natural.height, child);
 
 	return child;
 };
diff --git a/src/facilities/salon/salonPassage.js b/src/facilities/salon/salonPassage.js
index 0e73768577eea7e04a69458f8c8d7a5310db09b9..b9ca05d00c7fbfa9bb9608adc584afd45c4b6d48 100644
--- a/src/facilities/salon/salonPassage.js
+++ b/src/facilities/salon/salonPassage.js
@@ -517,7 +517,7 @@ App.UI.salon = function(slave, cheat = false, startingGirls = false) {
 				option.addValue("Match the hair", slave.hColor);
 			}
 			option.addValueList(makeAList(App.Medicine.Modification.Color.Primary.map(color => color.value)));
-			option.addCallbackToEach(billMod);
+			option.addGlobalCallback(billMod);
 			option.pulldown();
 
 			// Style
@@ -567,7 +567,7 @@ App.UI.salon = function(slave, cheat = false, startingGirls = false) {
 				option.addValue("Match the curtains", slave.hColor);
 			}
 			option.addValueList(makeAList(App.Medicine.Modification.Color.Primary.map(color => color.value)))
-				.addCallbackToEach(billMod)
+				.addGlobalCallback(billMod)
 				.pulldown();
 		}
 		if (hasPubes || cheat) {
@@ -606,7 +606,7 @@ App.UI.salon = function(slave, cheat = false, startingGirls = false) {
 				option.addValue("Match the hair", slave.hColor);
 			}
 			option.addValueList(makeAList(App.Medicine.Modification.Color.Primary.map(color => color.value)))
-				.addCallbackToEach(billMod)
+				.addGlobalCallback(billMod)
 				.pulldown();
 		}
 		if (hasPitHair || cheat) {
diff --git a/src/facilities/surgery/analyzePregnancy.js b/src/facilities/surgery/analyzePregnancy.js
index d8ca35ebedbe1f7a3ccf56111499bbd30ac3d809..5f25ca40354f5d78474c2a69712cb0d818013704 100644
--- a/src/facilities/surgery/analyzePregnancy.js
+++ b/src/facilities/surgery/analyzePregnancy.js
@@ -62,6 +62,10 @@ globalThis.analyzePregnancies = function(mother, cheat) {
 				if (cheat) {
 					option.showTextBox();
 				}
+				option = options.addOption(`Expected adult height: ${heightToEitherUnit(genes.adultHeight)}`, "adultHeight", genes);
+				if (cheat) {
+					option.showTextBox();
+				}
 				option = options.addOption(`Eye Color: ${capFirstChar(genes.eyeColor)}`, "eyeColor", genes);
 				if (cheat) {
 					option.showTextBox().pulldown();
diff --git a/src/facilities/surgery/geneticQuirks.js b/src/facilities/surgery/geneticQuirks.js
index 62966baa269fd62a8c24b15bbe8a2c8ea7533f0d..cbb3e25451eb6e1adb46138cbef5b8873d7c6b63 100644
--- a/src/facilities/surgery/geneticQuirks.js
+++ b/src/facilities/surgery/geneticQuirks.js
@@ -35,7 +35,7 @@ App.UI.SlaveInteract.geneticQuirks = function(slave, allInactive, filter) {
 				}
 			}
 			if (key === "albinism" && "albinismOverride" in slave) {
-				option.addCallbackToEach((val) => induceAlbinism(slave, val));
+				option.addGlobalCallback((val) => induceAlbinism(slave, val));
 			}
 		}
 	}
diff --git a/src/futureSocieties/fsDecoration.js b/src/futureSocieties/fsDecoration.js
index 323cb9744ebbb137af4ccefb6b911a211c5eeb68..e1d3df46d0d3160b664ea23c37a33bae719ed828 100644
--- a/src/futureSocieties/fsDecoration.js
+++ b/src/futureSocieties/fsDecoration.js
@@ -24,7 +24,7 @@ App.UI.facilityRedecoration = function() {
 			option.addValue("Distribute Evenly", "even");
 		}
 	}
-	option.addCallbackToEach(value => {
+	option.addGlobalCallback(value => {
 		console.log(value);
 		let totalCost = 0;
 		if (value === "even") { // Cycles through the list of available FS decorations, and distributes them to facilities round robin style.
@@ -56,7 +56,7 @@ App.UI.facilityRedecoration = function() {
 		options.addOption(`The decoration style of ${facility.name} is`, "decoration", facility)
 			.addValue("Standard", "standard")
 			.addValueList(decorationNames)
-			.addCallbackToEach(value => {
+			.addGlobalCallback(value => {
 				if (value !== "standard") {
 					cashX(-5000, "capEx");
 				}
diff --git a/src/gui/Encyclopedia/encyclopedia.js b/src/gui/Encyclopedia/encyclopedia.js
index f46c242bea316ddc81671d534d32c9f8ecb3128f..11b23a3c5765834f1f2a5d2d9be1ebb966fd54de 100644
--- a/src/gui/Encyclopedia/encyclopedia.js
+++ b/src/gui/Encyclopedia/encyclopedia.js
@@ -1,6 +1,5 @@
 App.Encyclopedia.ui = function() {
 	const f = document.createElement("div");
-	const topLinks = [];
 	if (V.encyclopedia !== "Table of Contents") {
 		App.UI.DOM.appendNewElement("div", f, App.Encyclopedia.link("Table of Contents"), ["center"]);
 	}
@@ -29,35 +28,35 @@ App.Encyclopedia.ui = function() {
 	return f;
 };
 
-	/** Create a link to an encyclopedia dialog for a given article with the given text
-	 * @param {string} text Text for link
-	 * @param {string} [article] Encyclopedia article to link to (if not supplied than text is capitalized.)
-	 * @param {string} [classNames] CSS Class to add to the link
-	 * @returns {HTMLElement} DOM link element
-	 */
-	App.Encyclopedia.link = function(text, article = capFirstChar(text), classNames) {
-		const link = App.UI.DOM.link(text, () => showArticleInDialog(article));
-		if (!classNames) {
-			return link;
-		}
-		// Wrap in a span for coloring, more reliable when hovering over the link
-		const span = document.createElement("span");
-		span.className += classNames;
-		span.append(link);
-		return span;
+/** Create a link to an encyclopedia dialog for a given article with the given text
+ * @param {string} text Text for link
+ * @param {string} [article] Encyclopedia article to link to (if not supplied than text is capitalized.)
+ * @param {string} [classNames] CSS Class to add to the link
+ * @returns {HTMLElement} DOM link element
+ */
+App.Encyclopedia.link = function(text, article = capFirstChar(text), classNames) {
+	const link = App.UI.DOM.link(text, () => showArticleInDialog(article));
+	if (!classNames) {
+		return link;
+	}
+	// Wrap in a span for coloring, more reliable when hovering over the link
+	const span = document.createElement("span");
+	span.className += classNames;
+	span.append(link);
+	return span;
 
 	/** Show a given encyclopedia article in the encyclopedia dialog
 	 * @param {string} article
 	 */
-		function showArticleInDialog(article) {
-			const origEncyclopedia = V.encyclopedia;
-			if (Dialog.isOpen()) {
-				Dialog.close();
-			}
-			Dialog.setup("Encyclopedia", "encyclopedia");
-			V.encyclopedia = article;
-			Dialog.append(App.Encyclopedia.ui());
-			Dialog.open();
-			V.encyclopedia = origEncyclopedia;
+	function showArticleInDialog(article) {
+		const origEncyclopedia = V.encyclopedia;
+		if (Dialog.isOpen()) {
+			Dialog.close();
 		}
-	};
+		Dialog.setup("Encyclopedia", "encyclopedia");
+		V.encyclopedia = article;
+		Dialog.append(App.Encyclopedia.ui());
+		Dialog.open();
+		V.encyclopedia = origEncyclopedia;
+	}
+};
diff --git a/src/gui/Encyclopedia/encyclopediaFacilites.js b/src/gui/Encyclopedia/encyclopediaFacilites.js
index 73d51f16dcdaa80ae59813c1a0e78d352e542bef..88d750202a7fd7a97cc64f8b35cda075ae8fb881 100644
--- a/src/gui/Encyclopedia/encyclopediaFacilites.js
+++ b/src/gui/Encyclopedia/encyclopediaFacilites.js
@@ -169,7 +169,8 @@ App.Encyclopedia.addArticle("Nursery", function() {
 	return f;
 }, "facilities");
 
-App.Encyclopedia.addArticle("Farmyard", function() {// TODO: this will need more information
+App.Encyclopedia.addArticle("Farmyard", function() {
+	// TODO: this will need more information
 	const f = new DocumentFragment();
 	const r = new SpacedTextAccumulator(f);
 	r.push("The", App.UI.DOM.makeElement("span", "Farmyard", ["bold"]), "is where the majority of the", App.Encyclopedia.link("food"), `in your arcology is grown, once it is built. It also allows you to house animals${V.seeBestiality === 1 ? ', which you can have interact with your slaves' : ''}. The Farmyard can be furnished according to`, App.Encyclopedia.link("future society", "Future Societies"), "styles, and doing so can add a slight", App.Encyclopedia.link("devotion", "From Rebellious to Devoted", "hotpink"), "boost to slaves working there."); // TODO: this may need to be changed
@@ -239,7 +240,6 @@ App.Encyclopedia.addCategory("facilities", function() {
 
 function noteFacilityName(...text) {
 	const f = new DocumentFragment();
-	const r = new SpacedTextAccumulator(f);
 	App.Events.addNode(f, text, "span", ["note"]);
 	return f;
 }
diff --git a/src/gui/Encyclopedia/encyclopediaFutureSocities.js b/src/gui/Encyclopedia/encyclopediaFutureSocities.js
index b9e55545697844d5660acc6a198aee618f45fe1b..f2beeb7c1a9bccd90b2a498d062c3b2424625883 100644
--- a/src/gui/Encyclopedia/encyclopediaFutureSocities.js
+++ b/src/gui/Encyclopedia/encyclopediaFutureSocities.js
@@ -1,460 +1,507 @@
 App.Encyclopedia.addArticle("Future Societies", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		"The evolution of society has never been linear.",
+	App.Events.addNode(t, ["The evolution of society has never been linear.",
 		"Times of unrest and upheaval produce rapid change, followed by long periods of stasis in the absence of the necessary ingredients for further change.",
-		"The world is undoubtedly in the midst of a time of great change: society is certainly evolving. But into what?"
-	], "div", ["note"]);
+		"The world is undoubtedly in the midst of a time of great change: society is certainly evolving. But into what?"], "div", ["note"]);
 
-	App.Events.addNode(t, [
-		"Not since antiquity have single persons held as much practical power over the direction of society as Free Cities arcology owners now have.",
+	App.Events.addNode(t, ["Not since antiquity have single persons held as much practical power over the direction of society as Free Cities arcology owners now have.",
 		"Naturally, different Free Cities notables are going different ways with their great power.",
-		"Many are building new societies as different from each other as they are from the old world."
-], "div", ["note"]);
+		"Many are building new societies as different from each other as they are from the old world."], "div", ["note"]);
 
-App.Events.addNode(t, [
-	"One arcology might hold a society that is moving towards a fundamentalist interpretation of an old slaveholding religious tradition.",
-	"Another might pay homage to historical racially segregated societies.",
-	"A third might see intentional manipulation of gender roles that have held since the start of recorded history.",
-	"And these three arcologies might well be each other's neighbors."
-], "div", ["note"]);
+	App.Events.addNode(t, ["One arcology might hold a society that is moving towards a fundamentalist interpretation of an old slaveholding religious tradition.",
+		"Another might pay homage to historical racially segregated societies.",
+		"A third might see intentional manipulation of gender roles that have held since the start of recorded history.",
+		"And these three arcologies might well be each other's neighbors."], "div", ["note"]);
 
 	App.Encyclopedia.addArticleSource(t, "Guide to Modern Slavery, Online Edition. Accessed April 2, 2032", "Lawrence, W. G.");
 
 	App.Events.addNode(t, [
 		App.UI.DOM.makeElement("span", "Future Society Models", ["bold"]), `are societal goals the player can select and pursue for the arcology.",
 		"It is possible to maintain four future society goals at once.",
-		"The first is unlocked after week 5 for players with greater than rumored/${num(3000)}`, App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "or at game start with the Social Engineering character option; the rest unlock as the player achieves higher", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "levels."
-	], "p");
+		"The first is unlocked after week 5 for players with greater than rumored/${num(3000)}`,
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"or at game start with the Social Engineering character option; the rest unlock as the player achieves higher",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "levels."], "p");
 
-	App.Events.addNode(t, [
-		"All societies approve of specific things, usually slaves with specific characteristics; some societies also have dislikes.",
-		"All societies are advanced by the things they approve of and slowed by the things they disapprove of, and all societies give and take", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "when approving and disapproving.",
-		"All societies unlock unique events, arcology upgrades, and slave behaviors; some even unlock special clothing."
-], "p");
+	App.Events.addNode(t, ["All societies approve of specific things, usually slaves with specific characteristics; some societies also have dislikes.",
+		"All societies are advanced by the things they approve of and slowed by the things they disapprove of, and all societies give and take",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "when approving and disapproving.",
+		"All societies unlock unique events, arcology upgrades, and slave behaviors; some even unlock special clothing."], "p");
 
-App.Events.addNode(t, [
-	App.Encyclopedia.link("Money", "Money", "yellowgreen"), "can be expended to directly advance future societies; the spending level can be set from the future society submenu of the arcology management menu.",
-	"These funds are automatically spent each week.",
-	"Once a future society is fully adopted (as noted on the future society submenu), this spending does not advance the society further.",
-	"However, it can provide a guarantee against loss of progress should the player do something the society strongly disapproves of.",
-	"Also, the spending is applied equally to all active future society models, meaning that there is no loss of efficiency in spending if the player has two maximized models and one still under development."
-], "p");
+	App.Events.addNode(t, [App.Encyclopedia.link("Money", "Money", "yellowgreen"),
+		"can be expended to directly advance future societies; the spending level can be set from the future society submenu of the arcology management menu.",
+		"These funds are automatically spent each week.",
+		"Once a future society is fully adopted (as noted on the future society submenu), this spending does not advance the society further.",
+		"However, it can provide a guarantee against loss of progress should the player do something the society strongly disapproves of.",
+		"Also, the spending is applied equally to all active future society models, meaning that there is no loss of efficiency in spending if the player has two maximized models and one still under development."], "p");
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Ethnic Supremacy", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Ethnic Supremacy", ["bold"]), "is a future society model which approves of",
-		"slaves not of the chosen race and disapproves of slaves of the chosen race."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Ethnic Supremacy", ["bold"]),
+		"is a future society model which approves of",
+		"slaves not of the chosen race and disapproves of slaves of the chosen race."], "div");
 	App.Events.addNode(t, ["Improves the perceived beauty of racially superior slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Drastically lowers the desire of racially superior slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to affect the ethnic balance and economics seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for slaves of inferior races from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for slaves of inferior races from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Ethnic Subjugationism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Ethnic Subjugationism", ["bold"]), "is a future society model which approves of slaves of the chosen race."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Ethnic Subjugationism", ["bold"]),
+		"is a future society model which approves of slaves of the chosen race."], "div");
 	App.Events.addNode(t, ["Reduces the perceived beauty of racially inferior slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Drastically increases the desire to use racially inferior slaves."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for slaves of the disfavored race from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for slaves of the disfavored race from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Gender Radicalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Gender Radicalism", ["bold"]), "is a future society model which approves of",
-		"hormonal and surgical feminization and slaves with dicks."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Gender Radicalism", ["bold"]),
+		"is a future society model which approves of",
+		"hormonal and surgical feminization and slaves with dicks."], "div");
 	App.Events.addNode(t, ["Improves the value of slaves with dicks and slaves with balls."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to affect the biology seen in the slave market, and subtly influence arcology society."], "div", ["indent"]);
-	App.Events.addNode(t, [`Provides demand for; slaves with dicks, hormonally treated slaves and futanari${V.seeDicks !== 0 ? ' and ballsless bitches' : ''} from`, App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Gender Fundamentalism"), ".")]);
+	App.Events.addNode(t, [`Provides demand for; slaves with dicks, hormonally treated slaves and futanari${V.seeDicks !== 0 ? ' and ballsless bitches' : ''} from`,
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Gender Fundamentalism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Gender Fundamentalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Gender Fundamentalism", ["bold"]), "is a future society model which approves of",
-		"pregnancy and fertility and disapproves of slaves who retain testicles."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Gender Fundamentalism", ["bold"]),
+		"is a future society model which approves of",
+		"pregnancy and fertility and disapproves of slaves who retain testicles."], "div");
 	App.Events.addNode(t, ["Reduces the slave value penalty due to pregnancy and reduces the beauty of slaves with dicks, though gelding can ameliorate this."], "div", ["indent"]);
 	App.Events.addNode(t, ["Like Gender Radicalism, can be developed to affect the biology seen in the slave market, and subtly influence arcology society."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for naturally female slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Gender Radicalism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for naturally female slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Gender Radicalism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Paternalism", function() {
 	const t = new DocumentFragment();
-	const r = new SpacedTextAccumulator(t);
-	const devotion = (text = "devotion", colour="hotpink") => App.Encyclopedia.link(text, "From Rebellious to Devoted", colour);
-	const PaternalismApproval = [devotion(), "slaves choosing their own assignments", "good education", "mental health treatment", App.Encyclopedia.link("high health", "Health")];
-
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Paternalism", ["bold"]), "is a future society model which approves of",
-		App.UI.DOM.toSentence(PaternalismApproval), "while stupidity and undereducation is disapproved."
-	], "div");
-	App.Events.addNode(t, ["Applies a small", devotion(), "boost to all slaves and increases fines paid by citizens who injure whores and public servants."], "div", ["indent"]);
-	App.Events.addNode(t, ["Increases the", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "penalty for operating an arcade."], "div", ["indent"]);
+	const devotion = (text = "devotion", colour = "hotpink") => App.Encyclopedia.link(text, "From Rebellious to Devoted", colour);
+	const PaternalismApproval = [devotion(), "slaves choosing their own assignments", "good education",
+		"mental health treatment", App.Encyclopedia.link("high health", "Health")];
+
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Paternalism", ["bold"]),
+		"is a future society model which approves of", App.UI.DOM.toSentence(PaternalismApproval),
+		"while stupidity and undereducation is disapproved."], "div");
+	App.Events.addNode(t, ["Applies a small", devotion(),
+		"boost to all slaves and increases fines paid by citizens who injure whores and public servants."], "div", ["indent"]);
+	App.Events.addNode(t, ["Increases the", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"penalty for operating an arcade."], "div", ["indent"]);
 	App.Events.addNode(t, ["Slows increases in the ratio of slaves to citizens."], "div", ["indent"]);
-	App.Events.addNode(t, ["Can be developed to build a", App.Encyclopedia.link("trusting", "Trust", "mediumaquamarine"), "society that welcomes new slaves."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for careful slave breaking and gentle cosmetic surgeries from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Degradationism"), ".")]);
+	App.Events.addNode(t, ["Can be developed to build a",
+		App.Encyclopedia.link("trusting", "Trust", "mediumaquamarine"),
+		"society that welcomes new slaves."], "div", ["indent"]);
+	App.Events.addNode(t, ["Provides demand for careful slave breaking and gentle cosmetic surgeries from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Degradationism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Degradationism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Degradationism", ["bold"]), "is a future society model which approves of",
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Degradationism", ["bold"]),
+		"is a future society model which approves of",
 		"frightened or mindbroken slaves, glory holes, the arcade, and heavy tattoos and piercings;",
-		"it disapproves of", App.Encyclopedia.link("trusting", "Trust", "mediumaquamarine"), "(except for the Head Girl and Recruiter) and slaves choosing their own assignments."
-	], "div");
+		"it disapproves of", App.Encyclopedia.link("trusting", "Trust", "mediumaquamarine"),
+		"(except for the Head Girl and Recruiter) and slaves choosing their own assignments."], "div");
 	App.Events.addNode(t, ["Makes intelligent slaves less attractive and stupid slaves more attractive."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can apply unique names to slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Drives an increase in the ratio of slaves to citizens."], "div", ["indent"]);
-	App.Events.addNode(t, ["Eliminates the", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "penalty for operating an arcade along with fining citizens who injure whores and public servants."], "div", ["indent"]);
+	App.Events.addNode(t, ["Eliminates the", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"penalty for operating an arcade along with fining citizens who injure whores and public servants."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to increase demand for glory holes and arcades."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for: brutal slave breaking, stupid slaves and cruelly altered slaves from the", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Paternalism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for: brutal slave breaking, stupid slaves and cruelly altered slaves from the",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Paternalism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Body Purism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Body Purism", ["bold"]), "is a future society model which approves of",
-		"unimplanted slaves and no heavy tattoos or piercings; disapproves of implants."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Body Purism", ["bold"]),
+		"is a future society model which approves of",
+		"unimplanted slaves and no heavy tattoos or piercings; disapproves of implants."], "div");
 	App.Events.addNode(t, ["Improves value of slaves without implants."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to affect goods seen in the slave market and work towards a solution to the long term effects of drug use."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for slaves without implants from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Transformation Fetishism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for slaves without implants from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Transformation Fetishism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Transformation Fetishism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Transformation Fetishism", ["bold"]), "is a future society model which approves of",
-		"implants and extreme surgery; disapproves of slaves without implants."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Transformation Fetishism", ["bold"]),
+		"is a future society model which approves of",
+		"implants and extreme surgery; disapproves of slaves without implants."], "div");
 	App.Events.addNode(t, ["Reduces value of slaves without implants."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to radically affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for slaves with implants from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Body Purism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for slaves with implants from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Body Purism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Maturity Preferentialism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Maturity Preferentialism", ["bold"]), "is a future society model which approves of older slaves."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Maturity Preferentialism", ["bold"]),
+		"is a future society model which approves of older slaves."], "div");
 	App.Events.addNode(t, ["Improves value of older slaves, but reduces value of young slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Will not entirely eliminate the usual preference for younger slaves."], "div", ["indent"]);
-	App.Events.addNode(t, ["Can be developed to make it easier for older player characters to maintain", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "and advance the arcology's prosperity."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for older slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Youth Preferentialism"), ".")]);
+	App.Events.addNode(t, ["Can be developed to make it easier for older player characters to maintain",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"and advance the arcology's prosperity."], "div", ["indent"]);
+	App.Events.addNode(t, ["Provides demand for older slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Youth Preferentialism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Youth Preferentialism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Youth Preferentialism", ["bold"]), "is a future society model which approves of younger slaves."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Youth Preferentialism", ["bold"]),
+		"is a future society model which approves of younger slaves."], "div");
 	App.Events.addNode(t, ["Improves value of younger slaves, but reduces value of old slaves."], "div", ["indent"]);
-	App.Events.addNode(t, ["Can be developed to make it easier for younger player characters to maintain", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "and advance the arcology's prosperity."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for young slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Maturity Preferentialism"), ".")]);
+	App.Events.addNode(t, ["Can be developed to make it easier for younger player characters to maintain",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"and advance the arcology's prosperity."], "div", ["indent"]);
+	App.Events.addNode(t, ["Provides demand for young slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Maturity Preferentialism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Slimness Enthusiasm", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Slimness Enthusiasm", ["bold"]), "is a future society model which approves of",
-		"slaves with girlish figures; disapproves of slaves with stacked figures."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Slimness Enthusiasm", ["bold"]),
+		"is a future society model which approves of",
+		"slaves with girlish figures; disapproves of slaves with stacked figures."], "div");
 	App.Events.addNode(t, ["Improves value of slim slaves, but reduces value of stacked slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to affect goods seen in the slave market and improve slave health."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for unexpanded slaves at a healthy weight from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Asset Expansionism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for unexpanded slaves at a healthy weight from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Asset Expansionism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Asset Expansionism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Asset Expansionism", ["bold"]), "is a future society model which approves of slaves with very large body parts."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Asset Expansionism", ["bold"]),
+		"is a future society model which approves of slaves with very large body parts."], "div");
 	App.Events.addNode(t, ["Improves value of stacked slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to radically affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for asset expansion from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Slimness Enthusiasm"), ".")]);
+	App.Events.addNode(t, ["Provides demand for asset expansion from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Slimness Enthusiasm"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Pastoralism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Pastoralism", ["bold"]), "is a future society model which approves of lactation, cockmilking, and the dairy."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Pastoralism", ["bold"]),
+		"is a future society model which approves of lactation, cockmilking, and the dairy."], "div");
 	App.Events.addNode(t, ["Improves value of milk and semen."], "div", ["indent"]);
 	App.Events.addNode(t, ["Drives an increase in the ratio of slaves to citizens."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to massively improve value of milk and semen."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for production focused asset expansion from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for production focused asset expansion from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Physical Idealism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Physical Idealism", ["bold"]), "is a future society model which approves of musculature, height, and health."
-	], "div");
-	App.Events.addNode(t, ["Improves value of slaves with", App.UI.DOM.combineNodes(App.Encyclopedia.link("muscles", "Musculature"), ".")]);
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Physical Idealism", ["bold"]),
+		"is a future society model which approves of musculature, height, and health."], "div");
+	App.Events.addNode(t, ["Improves value of slaves with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("muscles", "Musculature"), ".")]);
 	App.Events.addNode(t, ["Can be developed to affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for muscular slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Hedonistic Decadence"), ".")]);
+	App.Events.addNode(t, ["Provides demand for muscular slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Hedonistic Decadence"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Chattel Religionism", function() {
 	const t = new DocumentFragment();
 	const devotion = (text = "devotion") => App.Encyclopedia.link(text, "From Rebellious to Devoted", "hotpink");
-	const chattelReligionism = ["appropriate clothing", devotion("high devotion"), App.Encyclopedia.link("slave marriages", "Slave marriages")];
-
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Chattel Religionism", ["bold"]), "is a future society model which approves of",
-		App.UI.DOM.toSentence(chattelReligionism), "while disapproving of slutty clothing."
-	], "div");
-	App.Events.addNode(t, ["Applies a small", devotion(), "boost to all slaves, and can remove the weekly", devotion(), "gain cap."], "div", ["indent"]);
+	const chattelReligionism = ["appropriate clothing", devotion("high devotion"),
+		App.Encyclopedia.link("slave marriages", "Slave marriages")];
+
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Chattel Religionism", ["bold"]),
+		"is a future society model which approves of", App.UI.DOM.toSentence(chattelReligionism),
+		"while disapproving of slutty clothing."], "div");
+	App.Events.addNode(t, ["Applies a small", devotion(), "boost to all slaves, and can remove the weekly", devotion(),
+		"gain cap."], "div", ["indent"]);
 	App.Events.addNode(t, ["Drives an increase in the ratio of slaves to citizens."], "div", ["indent"]);
-	App.Events.addNode(t, ["Can be developed to permanently boost", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "and quicken slaves' mental conditioning."], "div", ["indent"]);
+	App.Events.addNode(t, ["Can be developed to permanently boost",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"and quicken slaves' mental conditioning."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to prefer nudity over conservative clothing."]);
-	App.Events.addNode(t, ["Provides demand for sexual training from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Multiculturalism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for sexual training from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Multiculturalism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Multiculturalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Multiculturalism", ["bold"]), "is a future society model which approves of",
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Multiculturalism", ["bold"]),
+		"is a future society model which approves of",
 		"is a future society model which advances differently than other models: it is improved by the investment of more future society model slots, which can be withdrawn individually if desired.",
-		"No other advancement occurs and all benefits at each level are available instantly."
-	], "div");
-	App.Events.addNode(t, ["Each week provides free", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "and increases arcology prosperity."], "div", ["indent"]);
+		"No other advancement occurs and all benefits at each level are available instantly."], "div");
+	App.Events.addNode(t, ["Each week provides free",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"and increases arcology prosperity."], "div", ["indent"]);
 	App.Events.addNode(t, ["Helps prevent citizens from falling into slavery, slowing population drift towards slaves."], "div", ["indent"]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Chattel Religionism"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Chattel Religionism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Roman Revivalism", function() {
 	const t = new DocumentFragment();
-	const r = new SpacedTextAccumulator(t);
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Roman Revivalism", ["bold"]), "is a future society model which approves of",
-		"good leadership qualities like wealth and strong defense; disapproves of debt."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Roman Revivalism", ["bold"]),
+		"is a future society model which approves of",
+		"good leadership qualities like wealth and strong defense; disapproves of debt."], "div");
 	App.Events.addNode(t, ["Improves rate of prosperity gain and at high levels will drive down all slave prices."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can apply unique names to slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Slows increases in the ratio of slaves to citizens."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to greatly improve the arcology's resistance to insurrection."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for basic educations from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for basic educations from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Mutually exclusive with the other Revivalist models."], "div", ["indent"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Egyptian Revivalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Egyptian Revivalism", ["bold"]), "is a future society model which approves of",
-		"keeping a large harem, slave incest, and having a wide racial variety of public slaves."
-	], "div");
-	App.Events.addNode(t, ["Improves value of slaves in incestuous relationships and efficiency of fucktoys in improving", App.Encyclopedia.link("reputation.", "Arcologies and Reputation", "green")]);
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Egyptian Revivalism", ["bold"]),
+		"is a future society model which approves of",
+		"keeping a large harem, slave incest, and having a wide racial variety of public slaves."], "div");
+	App.Events.addNode(t, ["Improves value of slaves in incestuous relationships and efficiency of fucktoys in improving",
+		App.Encyclopedia.link("reputation.", "Arcologies and Reputation", "green")]);
 	App.Events.addNode(t, ["Can apply unique names to slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Slows increases in the ratio of slaves to citizens."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to improve the Head Girl position, with an additional bonus for Head Girls married to the Concubine, and a massive bonus if the Head Girl is also related to the Concubine."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for exotic accents from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for exotic accents from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Mutually exclusive with the other Revivalist models."], "div", ["indent"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Edo Revivalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Edo Revivalism", ["bold"]), "is a future society model which approves of",
-		"provision for the arcology's cultural development by providing a large number of public servants or club girls, which increases with", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "and disapproves of failure to do so."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Edo Revivalism", ["bold"]),
+		"is a future society model which approves of",
+		"provision for the arcology's cultural development by providing a large number of public servants or club girls, which increases with",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"and disapproves of failure to do so."], "div");
 	App.Events.addNode(t, ["Improves efficiency of public servants and club girls."], "div", ["indent"]);
 	App.Events.addNode(t, ["Greatly improves beauty of Japanese slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to greatly improve the efficiency of direct spending on future societies."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for unaccented slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for unaccented slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Mutually exclusive with the other Revivalist models."], "div", ["indent"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Arabian Revivalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Arabian Revivalism", ["bold"]), "is a future society model which approves of",
-		"keeping a large number of fucktoys and slaves in the master suite, which increases with", App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"), "and disapproves of failure to do so."
-], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Arabian Revivalism", ["bold"]),
+		"is a future society model which approves of",
+		"keeping a large number of fucktoys and slaves in the master suite, which increases with",
+		App.Encyclopedia.link("reputation", "Arcologies and Reputation", "green"),
+		"and disapproves of failure to do so."], "div");
 	App.Events.addNode(t, ["Grants a bonus to the price received when selling slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to improve the efficiency of direct spending on future societies and moderately increase rents."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for more", App.Encyclopedia.link("devoted", "From Rebellious to Devoted", "hotpink"), "slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for more",
+		App.Encyclopedia.link("devoted", "From Rebellious to Devoted", "hotpink"), "slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Mutually exclusive with the other Revivalist models."], "div", ["indent"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Chinese Revivalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Chinese Revivalism", ["bold"]), "is a future society model which approves of",
-		"maintaining a solid imperial administration by keeping a Head Girl, a Recruiter, and a Bodyguard; disapproves of failure to do so."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Chinese Revivalism", ["bold"]),
+		"is a future society model which approves of",
+		"maintaining a solid imperial administration by keeping a Head Girl, a Recruiter, and a Bodyguard; disapproves of failure to do so."], "div");
 	App.Events.addNode(t, ["Increases prosperity growth when all three of these positions are staffed."], "div", ["indent"]);
 	App.Events.addNode(t, ["Greatly improves beauty of Chinese slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to permit the Head Girl to see to an additional slave each week."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for", App.UI.DOM.makeElement("span", "intelligence", ["cyan"]), "from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for", App.UI.DOM.makeElement("span", "intelligence", ["cyan"]), "from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Mutually exclusive with the other Revivalist models."], "div", ["indent"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Repopulationism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Repopulation Focus", ["bold"]), "is a future society model. It:"], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Repopulation Focus", ["bold"]),
+		"is a future society model. It:"], "div");
 	App.Events.addNode(t, ["Approves of pregnant slaves and slaves that have given birth."], "div", ["indent"]);
 	App.Events.addNode(t, ["Improves value and beauty of pregnant slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to radically affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for lactating slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for lactating slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Provides demand for young slaves from the corporation."], "div", ["indent"]);
-	App.Events.addNode(t, ["Is mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Eugenics", "Eugenics Focus"), ".")]);
-	App.Events.addNode(t, [
-		"Repopulationism is a difficult Future Society and not recommended for beginners.",
-		"Try to keep as many slaves as possible visibly pregnant; if they're pregnant but not showing yet, Pregnancy Biometrics Collars can help."
-	], "p", ["note", "yellow"]);
+	App.Events.addNode(t, ["Is mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Eugenics", "Eugenics Focus"), ".")]);
+	App.Events.addNode(t, ["Repopulationism is a difficult Future Society and not recommended for beginners.",
+		"Try to keep as many slaves as possible visibly pregnant; if they're pregnant but not showing yet, Pregnancy Biometrics Collars can help."], "p", ["note",
+		"yellow"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Eugenics Focus", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Eugenics", ["bold"]), "is a future society model. It:"], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Eugenics", ["bold"]),
+		"is a future society model. It:"], "div");
 	App.Events.addNode(t, ["Disapproves of slave reproduction."], "div", ["indent"]);
 	App.Events.addNode(t, ["Drastically reduces value and beauty of pregnant slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Opens benefits exclusive to the connections made by the powerful individuals attracted to the arcology."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for; gelded, skilled and smart slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Is mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Repopulation Focus", "Repopulationism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for; gelded, skilled and smart slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Is mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Repopulation Focus", "Repopulationism"), ".")]);
 	App.Events.addNode(t, ["It is made up of four to five social classes: Slaves, low class citizens, chosen slaves, elite citizens, and the Societal Elite: a group of individuals with vast connections and wealth attracted by the promises of a society built around them. Low class citizens are encouraged to face testing and join the ranks of the elite, though the cost of failing the test is sterilization; a detail that is not revealed until after the test is complete."], "div", ["indent"]);
-	App.Events.addNode(t, [
-			"Eugenics is a difficult Future Society and not recommended for beginners.",
-			"For a more complete guide to playing with a Eugenics arcology, see the", App.UI.DOM.combineNodes(App.Encyclopedia.link("Guide to Eugenics"), ".")
-	], "p", ["note", "yellow"]);
+	App.Events.addNode(t, ["Eugenics is a difficult Future Society and not recommended for beginners.",
+		"For a more complete guide to playing with a Eugenics arcology, see the",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Guide to Eugenics"), ".")], "p", ["note", "yellow"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Slave Professionalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Slave Professionalism", ["bold"]), "is a future society model. It:"], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Slave Professionalism", ["bold"]),
+		"is a future society model. It:"], "div");
 	App.Events.addNode(t, ["Approves of intelligent, well-trained slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Improves value and beauty of smart slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Dislikes slaves ruled by their libido."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to radically affect goods seen in the slave market"], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for; smart, educated and trained", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Is mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Intellectual Dependency"), ".")]);
+	App.Events.addNode(t, ["Provides demand for; smart, educated and trained",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Is mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Intellectual Dependency"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Intellectual Dependency", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Intellectual Dependency", ["bold"]), "is a future society model. It:"], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Intellectual Dependency", ["bold"]),
+		"is a future society model. It:"], "div");
 	App.Events.addNode(t, ["Approves of horny, vapid slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Improves value and beauty of moronic slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to adore bimbo bodies or radically affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Allows for", App.Encyclopedia.link("the Schoolroom", "Schoolroom"), "to be radically redesigned."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for; idiotic, young and uneducated slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Is mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Slave Professionalism"), ".")]);
+	App.Events.addNode(t, ["Allows for", App.Encyclopedia.link("the Schoolroom", "Schoolroom"),
+		"to be radically redesigned."], "div", ["indent"]);
+	App.Events.addNode(t, ["Provides demand for; idiotic, young and uneducated slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Is mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Slave Professionalism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Petite Admiration", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Petite Admiration", ["bold"]), "is a future society model. It:"], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Petite Admiration", ["bold"]),
+		"is a future society model. It:"], "div");
 	App.Events.addNode(t, [`Approves of slaves shorter than ${lengthToEitherUnit(160)}.`]);
 	App.Events.addNode(t, ["Improves value and beauty of sufficiently short slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to accept relative shortness or radically affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for shorter slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Is mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Statuesque Glorification"), ".")]);
+	App.Events.addNode(t, ["Provides demand for shorter slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Is mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Statuesque Glorification"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Statuesque Glorification", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Statuesque Glorification", ["bold"]), "is a future society model. It:"], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Statuesque Glorification", ["bold"]),
+		"is a future society model. It:"], "div");
 	App.Events.addNode(t, [`Approves of slaves taller than ${lengthToEitherUnit(170)}.`]);
 	App.Events.addNode(t, ["Improves value and beauty of sufficiently tall slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to accept relative tallness or radically affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for taller slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Is mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Petite Admiration"), ".")]);
+	App.Events.addNode(t, ["Provides demand for taller slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Is mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Petite Admiration"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Hedonistic Decadence", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Hedonistic Decadence", ["bold"]), "is a future society model. It:"], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Hedonistic Decadence", ["bold"]),
+		"is a future society model. It:"], "div");
 	App.Events.addNode(t, ["Approves of overindulgence and luxury."], "div", ["indent"]);
 	App.Events.addNode(t, ["Improves value and beauty of heavyset slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to radically affect goods seen in the slave market."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for pampered and skilled slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
-	App.Events.addNode(t, ["Mutually exclusive with", App.UI.DOM.combineNodes(App.Encyclopedia.link("Physical Idealism"), ".")]);
+	App.Events.addNode(t, ["Provides demand for pampered and skilled slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Mutually exclusive with",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("Physical Idealism"), ".")]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Aztec Revivalism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Aztec Revivalism", ["bold"]), "is a future society model which approves of",
-		"qualities like good military education and an older leader."
-	], "div");
-	App.Events.addNode(t, ["Improves all military acquisitions of slaves and allows for the sacrifice of slaves for", App.Encyclopedia.link("reputation.", "Arcologies and Reputation", "green")]);
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Aztec Revivalism", ["bold"]),
+		"is a future society model which approves of",
+		"qualities like good military education and an older leader."], "div");
+	App.Events.addNode(t, ["Improves all military acquisitions of slaves and allows for the sacrifice of slaves for",
+		App.Encyclopedia.link("reputation.", "Arcologies and Reputation", "green")]);
 	App.Events.addNode(t, ["Can apply unique names to slaves."], "div", ["indent"]);
 	App.Events.addNode(t, ["Slows increases in the ratio of slaves to citizens."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to greatly rely on the Head Girl position as an advisor and assistant."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for menial slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for menial slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Mutually exclusive with the other Revivalist models."], "div", ["indent"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Neo-Imperialism", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		App.UI.DOM.makeElement("span", "Neo-Imperialism", ["bold"]), "is a future society model which approves of",
-		"high wealth, prosperity, and personal combat skills and disapproves of weakness and poverty in leaders."
-	], "div");
+	App.Events.addNode(t, [App.UI.DOM.makeElement("span", "Neo-Imperialism", ["bold"]),
+		"is a future society model which approves of",
+		"high wealth, prosperity, and personal combat skills and disapproves of weakness and poverty in leaders."], "div");
 	App.Events.addNode(t, ["Improves rate of prosperity gain and can be developed to increase rents via Imperial Barons."], "div", ["indent"]);
 	App.Events.addNode(t, ["Slows increases in the ratio of slaves to citizens."], "div", ["indent"]);
 	App.Events.addNode(t, ["Can be developed to improve the Arcology's combat prowess and resistance to insurrection via Imperial Knights."], "div", ["indent"]);
-	App.Events.addNode(t, ["Provides demand for healthy slaves from", App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
+	App.Events.addNode(t, ["Provides demand for healthy slaves from",
+		App.UI.DOM.combineNodes(App.Encyclopedia.link("The Corporation"), ".")]);
 	App.Events.addNode(t, ["Mutually exclusive with all Revivalist models."], "div", ["indent"]);
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Gender Radicalism Research", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		"Advanced Gender Radicalist societies can fund research to produce modified uteri and ovaries designed to be implanted into male slaves to grant them the ability to become pregnant, thus leaving no gender specific traits remaining."
-	], "div");
+	App.Events.addNode(t, ["Advanced Gender Radicalist societies can fund research to produce modified uteri and ovaries designed to be implanted into male slaves to grant them the ability to become pregnant, thus leaving no gender specific traits remaining."], "div");
 	return t;
 }, "FutureSocities");
 
@@ -472,11 +519,9 @@ App.Encyclopedia.addArticle("Transformation Fetishism Research", function() {
 
 App.Encyclopedia.addArticle("Asset Expansionist Research", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		"Advanced Asset Expansionist societies can fund research to produce extremely powerful growth drugs capable of growing body parts to previously undocumented sizes.",
+	App.Events.addNode(t, ["Advanced Asset Expansionist societies can fund research to produce extremely powerful growth drugs capable of growing body parts to previously undocumented sizes.",
 		"Drugs are also standardized in slave diets to prevent loss of asset size.",
-	 "Due to the rapid growth in said assets, and the strength of the drug cocktails, slaves are more likely to develop side effects of excessive drug use."
-	], "div");
+		"Due to the rapid growth in said assets, and the strength of the drug cocktails, slaves are more likely to develop side effects of excessive drug use."], "div");
 	return t;
 }, "FutureSocities");
 
@@ -492,23 +537,21 @@ App.Encyclopedia.addArticle("Slimness Enthusiast Research", function() {
 
 App.Encyclopedia.addArticle("Youth Preferentialism Research", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		"Specialized creams built off of stem cells and several ingredients known for reducing the ravages of age.",
-		"Steady use leaves a slave looking younger, though the effects are literally skin deep; several gossip pieces have run about celebrities bedding youthful slaves just to accidentally find their efforts resulting in a broken hip."
-	], "div");
+	App.Events.addNode(t, ["Specialized creams built off of stem cells and several ingredients known for reducing the ravages of age.",
+		"Steady use leaves a slave looking younger, though the effects are literally skin deep; several gossip pieces have run about celebrities bedding youthful slaves just to accidentally find their efforts resulting in a broken hip."], "div");
 	return t;
 }, "FutureSocities");
 
 App.Encyclopedia.addArticle("Hedonistic Decadence Research", function() {
 	const t = new DocumentFragment();
-	App.Events.addNode(t, [
-		"Advanced Hedonistic Decadence societies can purchase plans for specialized slave food.",
-	 "Said food is shaped to resemble actual food and flavored accordingly, however, its texture can only be described as gooey or gummy.",
+	App.Events.addNode(t, ["Advanced Hedonistic Decadence societies can purchase plans for specialized slave food.",
+		"Said food is shaped to resemble actual food and flavored accordingly, however, its texture can only be described as gooey or gummy.",
 		"A plus if that is how the food should be, but a shocker otherwise, given how tantalizing that steak looks after nothing but liquid slave food for so long.",
-		"Since the food is essentially compacted liquid slave food, it is highly addictive thanks to the, typically, low presence of aphrodisiacs and can easily lead to excessive", App.Encyclopedia.link("weight gain", "Weight"), "as slaves are driven to gorge themselves on it.",
+		"Since the food is essentially compacted liquid slave food, it is highly addictive thanks to the, typically, low presence of aphrodisiacs and can easily lead to excessive",
+		App.Encyclopedia.link("weight gain", "Weight"), "as slaves are driven to gorge themselves on it.",
 		"They'll be happy, at least, as they steadily outgrow their clothes.",
-		"Alterations to the recipe exist to prevent", App.Encyclopedia.link("weight gain", "Weight"), "for Slimness Enthusiast societies and to cause gastric distress in Degradationist societies."
-	], "div");
+		"Alterations to the recipe exist to prevent", App.Encyclopedia.link("weight gain", "Weight"),
+		"for Slimness Enthusiast societies and to cause gastric distress in Degradationist societies."], "div");
 	return t;
 }, "FutureSocities");
 
diff --git a/src/gui/Encyclopedia/encyclopediaParaphilias.js b/src/gui/Encyclopedia/encyclopediaParaphilias.js
index 71a17ef38161ce4f0fdc67af4075058954115cca..5a4a1f2ed0802b9d9b65dad7c5338ce583d5eb1d 100644
--- a/src/gui/Encyclopedia/encyclopediaParaphilias.js
+++ b/src/gui/Encyclopedia/encyclopediaParaphilias.js
@@ -95,7 +95,7 @@ App.Encyclopedia.addArticle("Maliciousness", function() {
 App.Encyclopedia.addArticle("Self Hatred", function() {
 	const f = new DocumentFragment();
 	const r = new SpacedTextAccumulator(f);
-	r.push(App.UI.DOM.makeElement("span","self hatred", ["bold"]), "is a paraphilia, an intense form of sexual", App.Encyclopedia.link("flaws"), "that cannot be softened.");
+	r.push(App.UI.DOM.makeElement("span", "self hatred", ["bold"]), "is a paraphilia, an intense form of sexual", App.Encyclopedia.link("flaws"), "that cannot be softened.");
 	r.toParagraph();
 
 	r.push("Self hating slaves can be satisfied by work in an industrialized dairy, in an arcade, or in a glory hole, and will not suffer negative mental effects for doing so.");
diff --git a/src/gui/options/options.js b/src/gui/options/options.js
index ca41733314be7bb548750bfb45369f58a95c9b18..a6c6d6ffa9d0f025c7f5afe5fbf8a278d314e35f 100644
--- a/src/gui/options/options.js
+++ b/src/gui/options/options.js
@@ -856,7 +856,7 @@ App.Intro.display = function(isIntro) {
 	options.addOption("Help tooltips are", "tooltipsEnabled")
 		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
 		.addComment(`This is mostly for new players. <span class='exampleTooltip noteworthy'>Colored text</span> can have tooltips.`)
-		.addCallbackToEach(App.UI.GlobalTooltips.update);
+		.addGlobalCallback(App.UI.GlobalTooltips.update);
 
 	options.addOption("Main menu slave tabs are", "useSlaveSummaryTabs")
 		.addValue("Enabled", 1).on().addValue("CardStyle", 2).on().addValue("Disabled", 0).off();
diff --git a/src/gui/options/optionsGroup.js b/src/gui/options/optionsGroup.js
index d51a9902e19397a6605f46e1d3a14c040bc32ce9..b1220f9b164e04542afb34704cbcf662775a3ff1 100644
--- a/src/gui/options/optionsGroup.js
+++ b/src/gui/options/optionsGroup.js
@@ -35,6 +35,11 @@ App.UI.OptionsGroup = (function() {
 			 * @type {Array<value>}
 			 */
 			this.valuePairs = [];
+			/**
+			 * @type {function(any):void}
+			 * @private
+			 */
+			this._globalCallback = undefined;
 		}
 
 		/**
@@ -157,12 +162,11 @@ App.UI.OptionsGroup = (function() {
 		}
 
 		/**
-		 * TODO: Replace with a global callback
-		 *
+		 * Only executed if no specific callback for this option exists.
 		 * @param {function(any):void} callback gets executed on every button click. Selected value is given as argument.
 		 */
-		addCallbackToEach(callback) {
-			this.valuePairs.forEach(pair => pair.callback = callback);
+		addGlobalCallback(callback) {
+			this._globalCallback = callback;
 			return this;
 		}
 
@@ -261,6 +265,8 @@ App.UI.OptionsGroup = (function() {
 							this.object[this.property] = value.value;
 							if (value.callback) {
 								value.callback(value.value);
+							} else if (this._globalCallback) {
+								this._globalCallback(value.value);
 							}
 							refresh();
 						};
@@ -280,6 +286,8 @@ App.UI.OptionsGroup = (function() {
 					const originalObj = this.valuePairs.find(obj => obj.value === value);
 					if (originalObj && typeof originalObj.callback === "function") {
 						originalObj.callback(originalObj.value);
+					} else if (this._globalCallback) {
+						this._globalCallback(originalObj.value);
 					}
 					refresh();
 				}));
@@ -529,8 +537,7 @@ App.UI.OptionsGroup = (function() {
 		 * @returns {Comment}
 		 */
 		addComment(comment) {
-			const c = new Comment(comment);
-			return this._addRow(c);
+			return this._addRow(new Comment(comment));
 		}
 
 		/**
diff --git a/src/interaction/prostheticLabPassage.js b/src/interaction/prostheticLabPassage.js
index c8d3aa27e4abb8c9162903261a34c25fef2deba5..3c1a67b18d2b07e351a64649b5c185f313222c8b 100644
--- a/src/interaction/prostheticLabPassage.js
+++ b/src/interaction/prostheticLabPassage.js
@@ -28,19 +28,20 @@ App.UI.prostheticLab = function() {
 		App.UI.DOM.appendNewElement("h3", node, "Personnel");
 
 		if (V.researchLab.aiModule === 1) {
-			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
-				"Buy and install research module",
-				() => {
-					cashX(forceNeg(35000 * V.upgradeMultiplierArcology), "capEx");
-					V.researchLab.aiModule = 2;
-					App.UI.reload();
-				},
-				[], '',
-				`This module enables your personal assistant to assist staff and direct menials assigned to your research facility, increasing efficiency. It costs ${cashFormat(35000 * V.upgradeMultiplierArcology)}`
-			));
+			const div = document.createElement("div");
+			div.append(App.UI.DOM.link("Buy and install research module", () => {
+				cashX(forceNeg(35000 * V.upgradeMultiplierArcology), "capEx");
+				V.researchLab.aiModule = 2;
+				App.UI.reload();
+			}));
+			App.Events.addNode(div, [` Costs ${cashFormatColor(35000 * V.upgradeMultiplierArcology)}`]);
+			node.append(div);
+			App.UI.DOM.appendNewElement("div", node,
+				`This module enables your personal assistant to assist staff and direct menials assigned to your research facility, increasing efficiency.`,
+				["note", "indent"]);
 		}
 		if ((staff) === 0) {
-			App.UI.DOM.appendNewElement("div", node, "Facility is currently unstaffed.", "note");
+			App.UI.DOM.appendNewElement("div", node, "Facility is currently unstaffed.");
 		} else {
 			r.push(`You have`);
 			if (V.researchLab.hired === 1) {
@@ -63,27 +64,24 @@ App.UI.prostheticLab = function() {
 			if (V.researchLab.aiModule > 1) {
 				r.push(`Occasionally you hear the voice of your assistant as ${heA} helps direct and organize work.`);
 			}
-			App.Events.addNode(node, r, "div", "note");
+			App.Events.addNode(node, r, "div");
 			r = [];
 		}
 
-		let div = App.UI.DOM.appendNewElement("div", node, null, "indent");
-		div.append(`Currently, this facility can employ ${V.researchLab.maxSpace} people.`);
+		App.UI.DOM.appendNewElement("div", node, `Currently, this facility can employ ${V.researchLab.maxSpace} people.`, ["indent",
+			"note"]);
 		if (V.researchLab.maxSpace >= 5) { // Exists
 			if (V.researchLab.maxSpace < 50) { // Can upgrade
 				const maxSpace = [5, 10, 20, 30, 40, 50];
 				const upgrade = maxSpace[maxSpace.indexOf(V.researchLab.maxSpace) + 1];
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(
+				App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
 					"Expand facility",
 					() => {
 						cashX(forceNeg(Math.trunc(500 * upgrade * V.upgradeMultiplierArcology)), "capEx");
 						V.researchLab.maxSpace = upgrade;
 						App.UI.reload();
-					}
-				));
-			} else {
-				App.Events.addNode(div, r, "div", "note");
-				r = [];
+					}), ["indent"]
+				);
 			}
 		}
 
@@ -106,7 +104,8 @@ App.UI.prostheticLab = function() {
 				}
 			}
 			App.Events.addNode(node, ["Hire", App.UI.DOM.generateLinksStrip(linkArray), "scientists."]);
-			App.UI.DOM.appendNewElement("div", node, `Each scientist will require an initial fee of ${cashFormat(2000)} and incur ${cashFormat(300)} weekly.`, ["indent", "note"]);
+			App.Events.addNode(node, [`Each scientist will require an initial fee of ${cashFormatColor(2000)} and incur ${cashFormatColor(300)} weekly.`], "div", ["indent",
+				"note"]);
 
 			if (V.menials > 0) {
 				const space = (V.researchLab.maxSpace - (staff));
@@ -129,7 +128,8 @@ App.UI.prostheticLab = function() {
 			} else {
 				App.UI.DOM.appendNewElement("div", node, `You do not own any unassigned menial slaves.`);
 			}
-			App.UI.DOM.appendNewElement("div", node, `Using menial slaves is much cheaper than hiring scientists, but they are less effective. ${cashFormat(100)} per slave each week.`, ["indent", "note"]);
+			App.Events.addNode(node, [`Using menial slaves is much cheaper than hiring scientists, but they are less effective. Costs ${cashFormatColor(100)} per slave each week.`],
+				"div", ["indent", "note"]);
 		} else {
 			App.UI.DOM.appendNewElement("div", node, "Facility is fully staffed.", ["indent", "note"]);
 		}
@@ -180,8 +180,11 @@ App.UI.prostheticLab = function() {
 				App.UI.DOM.appendNewElement("div", node, `You have projects planned but without researchers you won't be able to work on them:`);
 			}
 
+			const taskDiv = document.createElement("div");
+			taskDiv.classList.add("grid-3columns-auto");
+
 			for (let i = 0; i < V.researchLab.tasks.length; i++) {
-				const r = [];
+				let r = [];
 				switch (V.researchLab.tasks[i].type) {
 					case "research":
 						r.push(`You`);
@@ -212,9 +215,13 @@ App.UI.prostheticLab = function() {
 				}
 				j += V.researchLab.tasks[i].workLeft;
 				r.push(`<span class="noteworthy">${capFirstChar(App.Data.prosthetics[V.researchLab.tasks[i].id].name)}.</span>`);
+				App.Events.addNode(taskDiv, r, "div", "indent");
+				r = [];
 				if (V.researchLab.speed > 0) {
 					r.push(`Finished in approximately ${(Math.floor(j / V.researchLab.speed) + 1)} week(s).`);
 				}
+				App.Events.addNode(taskDiv, r, "div");
+				r = [];
 
 				r.push(App.UI.DOM.link(
 					(V.researchLab.tasks[i].type === "research") ? "Cancel: Will not return investments." : "Cancel",
@@ -226,8 +233,10 @@ App.UI.prostheticLab = function() {
 						App.UI.reload();
 					}
 				));
-				App.Events.addNode(node, r, "div", "indent");
+				App.Events.addNode(taskDiv, r, "div");
 			}
+
+			node.append(taskDiv);
 		} else {
 			App.UI.DOM.appendNewElement("div", node, `Currently the research lab has no tasks planned.`, "note");
 		}
@@ -235,25 +244,31 @@ App.UI.prostheticLab = function() {
 		App.UI.DOM.appendNewElement("h3", node, "Research");
 
 		App.UI.DOM.appendNewElement("div", node, `Available research projects:`);
+		const researchDiv = document.createElement("div");
+		researchDiv.classList.add("grid-2columns-auto");
 		for (let p of App.Data.prostheticIDs) {
 			if (V.prosthetics[p].research === 0) {
-				// <div class="indent">
 				if (App.Data.prosthetics[p].level <= V.prostheticsUpgrade) {
-					App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
-						`Reverse engineer ${addA(App.Data.prosthetics[p].name)}`,
+					App.UI.DOM.appendNewElement("div", researchDiv, App.UI.DOM.link(`Reverse engineer ${addA(App.Data.prosthetics[p].name)}`,
 						() => {
 							cashX(forceNeg(App.Data.prosthetics[p].costs), "labResearch");
 							V.prosthetics[p].research = -1;
-							V.researchLab.tasks.push({type: "research", id: p, workLeft: App.Data.prosthetics[p].research});
+							V.researchLab.tasks.push({
+								type: "research",
+								id: p,
+								workLeft: App.Data.prosthetics[p].research
+							});
 							App.UI.reload();
-						}, [], "",
-						`Costs ${cashFormat(App.Data.prosthetics[p].costs)} of initial investment.`
-					), "indent");
+						}
+					), ["indent"]);
+					App.Events.addNode(researchDiv, [` Costs ${cashFormatColor(App.Data.prosthetics[p].costs)} of initial investment.`], "div");
 				} else {
-					App.UI.DOM.appendNewElement("div", node, `You need better contracts to get the required research material for reverse engineering ${addA(App.Data.prosthetics[p].name)}.`, "note");
+					App.UI.DOM.appendNewElement("div", researchDiv, `You need better contracts to get the required research material for reverse engineering ${addA(App.Data.prosthetics[p].name)}.`, ["note",
+						"grid-all-columns"]);
 				}
 			}
 		}
+		node.append(researchDiv);
 
 		App.UI.DOM.appendNewElement("h3", node, "Manufacture");
 
diff --git a/src/interaction/siCustom.js b/src/interaction/siCustom.js
index 71418245b010b8bf09fbaea3c431c9c2a7e1e8ad..1afa30bea50fd602432d1e18c9abcf301a67edab 100644
--- a/src/interaction/siCustom.js
+++ b/src/interaction/siCustom.js
@@ -16,7 +16,8 @@ App.UI.SlaveInteract.custom = function(slave, refresh) {
 	App.UI.DOM.appendNewElement("h3", el, `Art`);
 	el.append(
 		customSlaveImage(),
-		customHairImage()
+		customHairImage(),
+		artSeed()
 	);
 
 	App.UI.DOM.appendNewElement("h3", el, `Names`);
@@ -674,6 +675,30 @@ App.UI.SlaveInteract.custom = function(slave, refresh) {
 		return el;
 	}
 
+	function artSeed() {
+		const frag = new DocumentFragment();
+		if (V.imageChoice === 4) { // webGL only right now
+			App.UI.DOM.appendNewElement("p", frag, `WebGL rendering uses a "seed value" to make small changes to the appearance of your slaves. If you're dissatisfied with this slave's appearance and correcting ${his} physical parameters doesn't seem to help, you can try replacing the seed value. Slaves with identical seeds will look identical; the game carefully preserves this value for clones and identical twins, but if you change it here it becomes your responsibility.`);
+
+			const setArtSeed = (/** @type {number} */ num) => {
+				slave.natural.artSeed = num;
+				refresh();
+				App.Events.refreshEventArt(slave);
+			};
+			const button = App.UI.DOM.makeElement("button", "Randomize");
+			button.onclick = () => setArtSeed(jsRandom(0, 10 ** 14));
+			const textbox = App.UI.DOM.makeTextBox(slave.natural.artSeed, (num) => setArtSeed(num), true);
+			textbox.style.maxWidth = "12em";
+			textbox.style.minWidth = "12em";
+			App.UI.DOM.appendNewElement("p", frag, App.UI.DOM.combineNodes(
+				"Art seed: ",
+				textbox,
+				button
+			));
+		}
+		return frag;
+	}
+
 	function customSlaveImage() {
 		let el = document.createElement('p');
 		el.append(`Assign ${him} a custom image: `);
diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js
index 5224aead3fbdf748b80116a71209de4b6709e2c3..65f660557e4a406a180bdd7bf0147d16c040667c 100644
--- a/src/js/SlaveState.js
+++ b/src/js/SlaveState.js
@@ -601,6 +601,16 @@ App.Entity.EyeState = class EyeState {
 	}
 };
 
+/** Genetic "natural targets" for this individual when full grown, without influence from drugs, surgery, etc */
+App.Entity.GeneticState = class GeneticState {
+	constructor() {
+		// TODO: move origHColor, origSkin, origRace here, as hColor, skin, race?
+		this.height = 170; // new - almost done.  need to rewrite physical development for both player and slave.
+		// this.boobs = 500; // TODO: for pregmodder
+		this.artSeed = jsRandom(0, 10 ** 14);
+	}
+};
+
 App.Entity.SlaveState = class SlaveState {
 	constructor() {
 		/** Slave's current name */
@@ -618,6 +628,8 @@ App.Entity.SlaveState = class SlaveState {
 		this.genes = "XX";
 		/** @type {number} */
 		this.pronoun = App.Data.Pronouns.Kind.female;
+		/** slave's natural genetic properties */
+		this.natural = new App.Entity.GeneticState();
 		/** game week slave was acquired.
 		 *
 		 * _0: Obtained prior to game start / at game start_ */
diff --git a/src/js/statsChecker/statsChecker.js b/src/js/statsChecker/statsChecker.js
index 00fb514fe546c4c25c495f1d057f7a770ed1018e..45e0681696ce01b6a724d4545ffc957796123928 100644
--- a/src/js/statsChecker/statsChecker.js
+++ b/src/js/statsChecker/statsChecker.js
@@ -479,7 +479,7 @@ globalThis.isPure = function(slave) {
 };
 
 /**
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  * @returns {boolean}
  */
 globalThis.isVirile = function(slave) {
@@ -1117,7 +1117,7 @@ globalThis.isVegetable = function(slave) {
 /**
  * Returns the hair color the slave was (or would be) born with.
  *
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  * @returns {string}
  */
 globalThis.getGeneticHairColor = function(slave) {
@@ -1130,7 +1130,7 @@ globalThis.getGeneticHairColor = function(slave) {
 /**
  * Returns the skin color the slave was (or would be) born with.
  *
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  * @returns {string}
  */
 globalThis.getGeneticSkinColor = function(slave) {
@@ -1141,7 +1141,6 @@ globalThis.getGeneticSkinColor = function(slave) {
 };
 
 /**
- *
  * @param {App.Entity.SlaveState} slave
  * @returns {boolean}
  */
@@ -1172,13 +1171,17 @@ globalThis.milkFlavor = function(slave) {
 	return `${slave.milkFlavor}-flavored `;
 };
 
+/**
+ * @param {FC.HumanState} slave
+ * @returns {boolean}
+ */
 globalThis.canBeDeflowered = function(slave) {
 	return (slave.vagina === 0 && canDoVaginal(slave)) || (slave.anus === 0 && canDoAnal(slave));
 };
 
 /**
  * A consolidated function for checking if an actor is currently aroused.
- * @param {App.Entity.HumanState} actor
+ * @param {FC.HumanState} actor
  * @returns {boolean}
  */
 globalThis.isHorny = function(actor) {
diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js
index 9c0c46f67e867a423c5075296437431aeb5f795a..200b1f3d13f84a55ab074b297f69fb5c4dd2acdf 100644
--- a/src/js/utilsSlave.js
+++ b/src/js/utilsSlave.js
@@ -637,6 +637,27 @@ globalThis.Height = (function() {
 		return applyAge(result, age, genes);
 	}
 
+	/**
+	 * @param {{nationality: string, race: FC.Race, genes: string, physicalAge: number, birthWeek: number}} slave
+	 * @param {Partial<heightConfig>} [conf]
+	 * @returns {number}
+	 */
+	function _randomAdultHeight(slave, conf) {
+		const mean = _meanHeight({
+			nationality: slave.nationality,
+			race: slave.race,
+			genes: slave.genes,
+			physicalAge: 20,
+			birthWeek: 0
+		});
+		if (conf) {
+			const localConfig = Object.assign({}, defaultConfig);
+			Object.assign(localConfig, conf);
+			return heightGenerator(localConfig, mean);
+		}
+		return heightGenerator(defaultConfig, mean);
+	}
+
 	/**
 	 * @param {{nationality: string, race: FC.Race, genes: string, physicalAge: number, birthWeek: number}} slave
 	 * @param {Partial<heightConfig>} [conf]
@@ -670,6 +691,7 @@ globalThis.Height = (function() {
 	return {
 		mean: _meanHeight,
 		random: _randomHeight,
+		randomAdult: _randomAdultHeight,
 		forAge: _forAge,
 		config: _config,
 	};
@@ -959,7 +981,8 @@ globalThis.randomCareer = function(slave) {
  * @param {FC.HumanState} slave
  */
 globalThis.resyncSlaveHeight = function(slave) {
-	slave.height = Height.random(slave);
+	slave.natural.height = Height.randomAdult(slave);
+	slave.height = Height.forAge(slave.natural.height, slave);
 };
 
 /**
@@ -2843,7 +2866,7 @@ globalThis.ageSlave = function(slave, forceDevelopment = false) {
 	if (slave.broodmother === 1) {
 		slave.ovaryAge += 0.2;
 	}
-	if (slave.physicalAge <= 18 && (forceDevelopment || V.loliGrow > 0)) {
+	if (slave.physicalAge <= 20 && (forceDevelopment || V.loliGrow > 0)) {
 		App.EndWeek.Shared.physicalDevelopment(slave);
 	}
 };
diff --git a/src/js/wombJS.js b/src/js/wombJS.js
index 00b724f1be45b9a491221b746190508743bfe8eb..b73dbee7883f63c9b65f608ba032b154b296d996 100644
--- a/src/js/wombJS.js
+++ b/src/js/wombJS.js
@@ -101,6 +101,13 @@ globalThis.WombInit = function(actor) {
 				{ID: null, mother: f.genetics.mother, father: f.genetics.father}
 			);
 		}
+		if (!jsDef(f.genetics.artSeed)) {
+			// probably could detect and fix clones/twins here too, but I'm not bothering
+			f.genetics.artSeed = jsRandom(0, 10 ** 14);
+		}
+		if (!jsDef(f.genetics.adultHeight)) {
+			f.genetics.adultHeight = Height.randomAdult({nationality: f.genetics.nationality, race: f.genetics.race, genes: f.genetics.gender, physicalAge: 20, birthWeek: 0});
+		}
 	});
 };
 
@@ -197,6 +204,7 @@ globalThis.WombImpregnateClone = function(actor, fCount, mother, age) {
 		tf.genetics.faceShape = motherOriginal.faceShape;
 		tf.genetics.geneticQuirks = clone(mother.geneticQuirks);
 		tf.genetics.skin = motherOriginal.skin;
+		tf.genetics.artSeed = mother.natural.artSeed;
 
 		try {
 			if (actor.womb.length === 0) {
diff --git a/src/markets/specificMarkets/eliteSlave.js b/src/markets/specificMarkets/eliteSlave.js
index 6aa670ec4e332abd00629a579a06f49410bfb0ce..8e5a2e99f015c4e5cbd8431ad69071cf9c676012 100644
--- a/src/markets/specificMarkets/eliteSlave.js
+++ b/src/markets/specificMarkets/eliteSlave.js
@@ -37,10 +37,11 @@ App.Markets["Elite Slave"] = function() {
 		slave.devotion = random(60, 100);
 		if (!heightPass(slave)) {
 			if (V.arcologies[0].FSPetiteAdmiration > 20) {
-				slave.height = Height.random(slave, {limitMult: [-4, -2]});
+				slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -2]});
 			} else if (V.arcologies[0].FSStatuesqueGlorification > 20) {
-				slave.height = Height.random(slave, {limitMult: [3, 5]});
+				slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 5]});
 			}
+			slave.height = Height.forAge(slave.natural.height, slave);
 		}
 		if (V.arcologies[0].FSPaternalist > 20) {
 			setHealth(slave, 100, 0, 0, 0, 0);
diff --git a/src/markets/specificMarkets/prestigiousSlave.js b/src/markets/specificMarkets/prestigiousSlave.js
index a14e42781f7810397d086df809c5ef616ba9f524..550f2ffc5854c1f2c8d579865dd10c26783e692a 100644
--- a/src/markets/specificMarkets/prestigiousSlave.js
+++ b/src/markets/specificMarkets/prestigiousSlave.js
@@ -823,7 +823,8 @@ App.Markets["Prestigious Slave"] = function() {
 				slave.prestigeDesc = "$He was once a rising old world politician, but was forced to flee from the increasingly dangerous politics common in a stressed world, and was subsequently enslaved.";
 				slave.career = "a politician";
 				slave.muscles = random(10, 50);
-				slave.height = random(160, 200);
+				slave.natural.height = random(160, 200);
+				slave.height = slave.natural.height;
 				slave.face = Math.clamp(slave.face + 20, -100, 100);
 				slave.faceImplant += 20;
 				slave.faceShape = "masculine";
diff --git a/src/npc/children/ChildState.js b/src/npc/children/ChildState.js
index 67143dd75b9c2b2d8cf92c1a158e5a48068cc606..27388ac6e51c66ecf6dae71c516f1f358999d83a 100644
--- a/src/npc/children/ChildState.js
+++ b/src/npc/children/ChildState.js
@@ -19,6 +19,8 @@ App.Facilities.Nursery.ChildState = class ChildState {
 		this.genes = "XX";
 		/** @type {number} */
 		this.pronoun = App.Data.Pronouns.Kind.female;
+		/** slave's natural genetic properties */
+		this.natural = new App.Entity.GeneticState();
 		/** Game week slave was acquired.
 		 *
 		 * _0: Obtained prior to game start / at game start_ */
diff --git a/src/npc/databases/cheatmodeDatabase.js b/src/npc/databases/cheatmodeDatabase.js
index 919e7945e8a89d1bed3f022b79ac50c43de58777..60baa3766077f2b116ee705b27c84e124dc35c69 100644
--- a/src/npc/databases/cheatmodeDatabase.js
+++ b/src/npc/databases/cheatmodeDatabase.js
@@ -23,6 +23,7 @@ App.Intro.cheatModeSlaves = function() {
 	setHealth(cheatSlave, 50);
 	cheatSlave.devotion = 100;
 	cheatSlave.nationality = "Stateless";
+	cheatSlave.natural.height = 175;
 	cheatSlave.height = 175;
 	cheatSlave.race = "white";
 	cheatSlave.eye.origColor = "green";
@@ -92,6 +93,7 @@ App.Intro.cheatModeSlaves = function() {
 	cheatSlave.devotion = 100;
 	cheatSlave.nationality = "Stateless";
 	cheatSlave.muscles = 20;
+	cheatSlave.natural.height = 190;
 	cheatSlave.height = 190;
 	cheatSlave.race = "black";
 	cheatSlave.origHColor = "black";
@@ -161,6 +163,7 @@ App.Intro.cheatModeSlaves = function() {
 	setHealth(cheatSlave, 10);
 	cheatSlave.devotion = 60;
 	cheatSlave.nationality = "Stateless";
+	cheatSlave.natural.height = 175;
 	cheatSlave.height = 175;
 	cheatSlave.race = "black";
 	cheatSlave.pubicHColor = "black";
@@ -227,6 +230,7 @@ App.Intro.cheatModeSlaves = function() {
 	cheatSlave.devotion = 60;
 	cheatSlave.nationality = "Stateless";
 	cheatSlave.muscles = 50;
+	cheatSlave.natural.height = 190;
 	cheatSlave.height = 190;
 	cheatSlave.race = "black";
 	cheatSlave.origHColor = "black";
@@ -299,6 +303,7 @@ App.Intro.cheatModeSlaves = function() {
 	cheatSlave.devotion = 30;
 	cheatSlave.nationality = "Stateless";
 	cheatSlave.muscles = 50;
+	cheatSlave.natural.height = 175;
 	cheatSlave.height = 175;
 	cheatSlave.race = "white";
 	cheatSlave.eye.origColor = "green";
@@ -359,6 +364,7 @@ App.Intro.cheatModeSlaves = function() {
 	cheatSlave.devotion = 60;
 	cheatSlave.nationality = "Stateless";
 	cheatSlave.muscles = 50;
+	cheatSlave.natural.height = 190;
 	cheatSlave.height = 190;
 	cheatSlave.race = "black";
 	cheatSlave.origHColor = "black";
diff --git a/src/npc/generate/generateGenetics.js b/src/npc/generate/generateGenetics.js
index 23cfcc48ee84e04852ca241c906600af580bfbbe..1a0a13c3deb543042bb233d49b9529b204adc229 100644
--- a/src/npc/generate/generateGenetics.js
+++ b/src/npc/generate/generateGenetics.js
@@ -49,7 +49,9 @@ globalThis.generateGenetics = (function() {
 			cloneID: 0,
 			geneticQuirks: {},
 			fetish: "none",
-			spermY: 50
+			spermY: 50,
+			adultHeight: 170,
+			artSeed: jsRandom(0, 10 ** 14)
 		};
 		if (actor1.ID > 0) {
 			mother = V.genePool.find(s => s.ID === actor1.ID);
@@ -109,10 +111,40 @@ globalThis.generateGenetics = (function() {
 		genes.behavioralFlaw = setBehavioralFlaw(father, mother);
 		genes.fetish = setFetish(father, mother);
 		genes.spermY = setSpermY(father, mother);
+		genes.adultHeight = setAdultHeight(father, mother, genes.gender, genes.race, genes.nationality, genes.geneticQuirks);
 
 		return genes;
 	}
 
+	/** set expected adult height for the fetus
+	 * @param {FC.Zeroable<FC.HumanState>} father
+	 * @param {FC.HumanState} mother
+	 * @param {string} gender
+	 * @param {FC.Race} race
+	 * @param {string} nationality
+	 * @param {Partial<FC.GeneticQuirks>} quirks
+	 * @returns {number}
+	 */
+	function setAdultHeight(father, mother, gender, race, nationality, quirks) {
+		const randomPart = Height.random({nationality, race, genes: gender, physicalAge: 20, birthWeek: 0});
+		if ((quirks.dwarfism === 2) !== (mother.geneticQuirks.dwarfism === 2) ||
+			(quirks.gigantism === 2) !== (mother.geneticQuirks.gigantism === 2) ||
+			father && ((quirks.dwarfism === 2) !== (father.geneticQuirks.dwarfism === 2)) ||
+			father && ((quirks.gigantism === 2) !== (father.geneticQuirks.gigantism === 2))) {
+			// we have a height quirk change compared to one of our parents.  better to just start over with a completely random target height.
+			return randomPart;
+		}
+		// global average: men are 7% taller than women. natural heights contain this bias.
+		const genderScalingFactor = 1.07;
+		// heritance ratio for height in humans is currently estimated at 79% (Yengo, L., Vedantam, S., Marouli, E., et al. "A saturated map of common genetic variants associated with human height." Nature 610, 704–712 (2022))
+		const heritanceRatio = 0.79;
+		// assemble!
+		const motherPart = mother.natural.height * (gender === "XX" ? 1.0 : genderScalingFactor);
+		const fatherPart = father ? father.natural.height * (gender === "XY" ? 1.0 : (1 / genderScalingFactor)) : motherPart;
+		const inheritedPart = (motherPart + fatherPart) * 0.5;
+		return Math.round((heritanceRatio * inheritedPart) + ((1 - heritanceRatio) * randomPart));
+	}
+
 	// get spermY value of the parent that's donating the Y chromosome
 	function getSpermY(father, mother) {
 		let sourceSpermY = 50; // default if no inherited Y chromosome (should be impossible, but the Adam Principle is optional, so it can happen)
@@ -1088,6 +1120,7 @@ globalThis.generateGenetics = (function() {
  * @returns {App.Entity.SlaveState|App.Facilities.Nursery.InfantState}
  */
 globalThis.generateChild = function(mother, ovum, incubator = false) {
+	/** @type {FC.FetusGenetics} */
 	let genes = ovum.genetics; // TODO: maybe just argument this? We'll see.
 	let child;
 
@@ -1129,6 +1162,7 @@ globalThis.generateChild = function(mother, ovum, incubator = false) {
 		child.skin = getGeneticSkinColor(child);
 		child.hColor = getGeneticHairColor(child);
 		child.spermY = genes.spermY;
+		child.natural.height = genes.adultHeight;
 		child.pubicHColor = child.hColor;
 		child.underArmHColor = child.hColor;
 		child.eyebrowHColor = child.hColor;
@@ -1219,6 +1253,7 @@ globalThis.generateChild = function(mother, ovum, incubator = false) {
 			child.tailColor = child.hColor;
 		}
 		child.spermY = genes.spermY;
+		child.natural.height = genes.adultHeight;
 		resetEyeColor(child, "both");
 		child.pubicHColor = child.hColor;
 		child.underArmHColor = child.hColor;
diff --git a/src/npc/generate/generateLeadershipSlave.js b/src/npc/generate/generateLeadershipSlave.js
index 4862b4c8e606e6cac00c10e7cd500c840fcaa3f5..0f395edb91ab4d2af8cba9d71e6bea106e2b267f 100644
--- a/src/npc/generate/generateLeadershipSlave.js
+++ b/src/npc/generate/generateLeadershipSlave.js
@@ -66,7 +66,8 @@ globalThis.generateLeadershipSlave = function(input, location) {
 			slave.devotion = jsRandom(51, 85);
 			slave.trust = jsRandom(51, 85);
 			slave.muscles = jsRandom(30, 70);
-			slave.height = Height.random(slave, {skew: 3, spread: .2, limitMult: [1, 4]});
+			slave.natural.height = Height.randomAdult(slave, {skew: 3, spread: .2, limitMult: [1, 4]});
+			slave.height = Height.forAge(slave.natural.height, slave);
 			slave.weight = jsRandom(-10, 10);
 			slave.teeth = either("normal", "pointy");
 			slave.skill.combat = 70;
@@ -164,7 +165,8 @@ globalThis.generateLeadershipSlave = function(input, location) {
 			slave.muscles = jsRandom(41, 70);
 			slave.sexualQuirk = "caring";
 			slave.weight = jsRandom(0, 30);
-			slave.height = Height.random(slave, {skew: 3, spread: .2, limitMult: [1, 4]});
+			slave.natural.height = Height.randomAdult(slave, {skew: 3, spread: .2, limitMult: [1, 4]});
+			slave.height = Height.forAge(slave.natural.height, slave);
 			applyMaleGenitalia({dick: jsRandom(3, 5), balls: jsRandom(4, 9), prostate: either(1, 1, 1, 2)});
 			slave.career = either(App.Data.Careers.Leader.farmer);
 			break;
diff --git a/src/npc/generate/generateMarketSlave.js b/src/npc/generate/generateMarketSlave.js
index 22843621dcdc6816f9a3d9b8d657607f998f8f56..84f4c115e5ea52c54588a46a8cd3f53bef0abc5f 100644
--- a/src/npc/generate/generateMarketSlave.js
+++ b/src/npc/generate/generateMarketSlave.js
@@ -112,7 +112,8 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 					r += `The corporation specifically targets incredibly tall slaves. `;
 					maxMult = 5; // do not limit tallness
 				}
-				slave.height = Height.random(slave, {skew: V.corp.SpecHeight - 3, limitMult: [minMult, maxMult]});
+				slave.natural.height = Height.randomAdult(slave, {skew: V.corp.SpecHeight - 3, limitMult: [minMult, maxMult]});
+				slave.height = Height.forAge(slave.natural.height, slave);
 			}
 			if (V.corp.SpecVirgin === 1) {
 				r += `The corporation ensures its slaves are virgins. `;
@@ -865,27 +866,29 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 			}
 			if (neighbor.FSPetiteAdmiration > 20) {
 				r += `They tend to be short, some far more than others. `;
-				if (slave.height >= Height.forAge(160, slave)) {
-					slave.height = Height.random(slave, {limitMult: [-2, 0]});
-					if (slave.height >= Height.forAge(160, slave)) {
-						slave.height = Height.random(slave, {limitMult: [-3, -1]});
-						if (slave.height >= Height.forAge(160, slave)) {
-							slave.height = Height.forAge(jsRandom(90, 130), slave);
+				if (slave.natural.height >= 160) {
+					slave.natural.height = Height.random(slave, {limitMult: [-2, 0]});
+					if (slave.natural.height >= 160) {
+						slave.natural.height = Height.random(slave, {limitMult: [-3, -1]});
+						if (slave.natural.height >= 160) {
+							slave.natural.height = jsRandom(90, 130);
 							slave.geneticQuirks.dwarfism = 2;
 						}
 					}
+					slave.height = Height.forAge(slave.natural.height, slave);
 				}
 			} else if (neighbor.FSStatuesqueGlorification > 20) {
 				r += `They tend to be tall, if not unbelievably so. `;
-				if (slave.height < Height.forAge(170, slave)) {
-					slave.height = Height.random(slave, {limitMult: [0, 2]});
-					if (slave.height < Height.forAge(170, slave)) {
-						slave.height = Height.random(slave, {limitMult: [1, 3]});
-						if (slave.height < Height.forAge(170, slave)) {
-							slave.height = Height.forAge(jsRandom(200, 264), slave);
+				if (slave.natural.height < 170) {
+					slave.natural.height = Height.random(slave, {limitMult: [0, 2]});
+					if (slave.natural.height < 170) {
+						slave.natural.height = Height.random(slave, {limitMult: [1, 3]});
+						if (slave.natural.height < 170) {
+							slave.natural.height = jsRandom(200, 264);
 							slave.geneticQuirks.gigantism = 2;
 						}
 					}
+					slave.height = Height.forAge(slave.natural.height, slave);
 				}
 			}
 			if (neighbor.FSSlimnessEnthusiast > 20) {
@@ -1599,7 +1602,7 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 			} else {
 				setHealth(slave, jsRandom(-50, 100), Math.max(normalRandInt(0, 4), 0), Math.max(normalRandInt(10, 4), 0), Math.max(normalRandInt(0, 0.5), 0), jsRandom(10, 20));
 			}
-			slave.height = jsRandom(160, 210);
+			slave.height = Math.max(jsRandom(160, 210), slave.natural.height);
 			slave.butt = jsRandom(4, 10);
 			if (V.GRI.schoolUpgrade === 2) {
 				slave.boobs = 200 * jsRandom(15, 30);
@@ -2227,15 +2230,16 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 			setHealth(slave, jsRandom(60, 80), 0, Math.max(normalRandInt(0, 2), 0), 0, jsRandom(5, 20));
 			const minHeight = jsRandom(170, 180);
 			if (V.HA.schoolUpgrade === 2) {
-				slave.height = Math.clamp(Height.random(slave, {
+				slave.natural.height = Math.clamp(Height.random(slave, {
 					limitMult: [2, 15],
 					spread: 0.1
 				}), minHeight, 274);
 				slave.muscles = jsRandom(40, 80);
 			} else {
-				slave.height = Math.clamp(Height.random(slave, {limitMult: [1, 4]}), minHeight, 274);
+				slave.natural.height = Math.clamp(Height.random(slave, {limitMult: [1, 4]}), minHeight, 274);
 				slave.muscles = jsRandom(20, 40);
 			}
+			slave.height = slave.natural.height;
 			if (V.HA.schoolUpgrade === 3) {
 				slave.weight = jsEither([10, 20, 20, 30, 30, 40, 40, 50]);
 				slave.waist = jsRandom(-10, 40);
diff --git a/src/npc/generate/generateNewSlaveJS.js b/src/npc/generate/generateNewSlaveJS.js
index 771360302c3b98d907ea80a006f9073c03eb3f18..da75bca2f209edc8d3f0c424f8025d3f229bef62 100644
--- a/src/npc/generate/generateNewSlaveJS.js
+++ b/src/npc/generate/generateNewSlaveJS.js
@@ -167,12 +167,13 @@ globalThis.GenerateNewSlave = (function() {
 
 	function generateXXBodyProportions() {
 		if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
-			slave.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15});
+			slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -1], spread: 0.15});
 		} else if (slave.geneticQuirks.gigantism === 2) {
-			slave.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15});
+			slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 10], spread: 0.15});
 		} else {
-			slave.height = Height.random(slave);
+			slave.natural.height = Height.randomAdult(slave);
 		}
+		slave.height = Height.forAge(slave.natural.height, slave);
 		if (slave.height >= Height.mean(slave) * 170 / 162.5) {
 			slave.hips = jsEither([-1, 0, 0, 1, 1, 2, 2]);
 			slave.shoulders = jsEither([-1, -1, 0, 0, 0, 1]);
@@ -200,12 +201,13 @@ globalThis.GenerateNewSlave = (function() {
 
 	function generateXYBodyProportions() {
 		if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
-			slave.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15});
+			slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -1], spread: 0.15});
 		} else if (slave.geneticQuirks.gigantism === 2) {
-			slave.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15});
+			slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 10], spread: 0.15});
 		} else {
-			slave.height = Height.random(slave);
+			slave.natural.height = Height.randomAdult(slave);
 		}
+		slave.height = Height.forAge(slave.natural.height, slave);
 		if (slave.physicalAge <= 13) {
 			if (slave.height > Height.mean(slave) * 170 / 172.5) {
 				slave.hips = jsEither([-2, -1, -1, 0, 1]);
diff --git a/src/npc/generate/generateRelatedSlave.js b/src/npc/generate/generateRelatedSlave.js
index 9d9dd98adf8b36bd1322f6c37f06b1c293c1989b..95fc244f2afdb0b548cfc2c6518feb610c8724c9 100644
--- a/src/npc/generate/generateRelatedSlave.js
+++ b/src/npc/generate/generateRelatedSlave.js
@@ -260,6 +260,12 @@ globalThis.generateRelatedSlave = (function() {
 		if (slave.butt > 1) {
 			slave.butt += random(-1, 1);
 		}
+		// fuzz height
+		const heightAdjust = random(-5, Math.min(maxHeight(slave) - slave.height, 5));
+		slave.natural.height += heightAdjust;
+		slave.height += heightAdjust;
+		// reset art seed
+		slave.natural.artSeed = jsRandom(0, 10 ** 14);
 	}
 
 	/**
@@ -290,7 +296,7 @@ globalThis.generateRelatedSlave = (function() {
 		}
 
 		// reset height
-		slave.height = Height.random(slave);
+		slave.height = Height.forAge(slave.natural.height, slave);
 
 		// reset puberty status
 		generatePuberty(slave);
diff --git a/src/npc/generate/heroCreator.js b/src/npc/generate/heroCreator.js
index 8ebe65004b82ad359a02823b5714ce7a977c845b..b742630504754e62afd042dd5095b81cadc6539b 100644
--- a/src/npc/generate/heroCreator.js
+++ b/src/npc/generate/heroCreator.js
@@ -100,10 +100,10 @@ App.Utils.getHeroSlave = function(heroSlave) {
 	repairLimbs(newSlave);
 	generatePuberty(newSlave);
 	newSlave.weekAcquired = V.week;
-	if (!newSlave.pubicHColor) {
+	if (!heroSlave.pubicHColor) {
 		newSlave.pubicHColor = newSlave.hColor;
 	}
-	if (!newSlave.underArmHColor) {
+	if (!heroSlave.underArmHColor) {
 		newSlave.underArmHColor = newSlave.hColor;
 	}
 	if (newSlave.override_Race !== 1) {
@@ -127,6 +127,13 @@ App.Utils.getHeroSlave = function(heroSlave) {
 	if (newSlave.override_Skin !== 1) {
 		newSlave.skin = getGeneticSkinColor(newSlave);
 	}
+	if (!heroSlave.natural?.height) {
+		// assumes adult - child hero slaves MUST specify natural height separately!
+		newSlave.natural.height = newSlave.height - newSlave.heightImplant * 10;
+	}
+	if (!heroSlave.natural?.artSeed) {
+		newSlave.natural.artSeed = jsRandom(0, 10 ** 14);
+	}
 	setHealth(newSlave, newSlave.health.condition, 0, 0, 0, newSlave.health.tired);
 
 	SetBellySize(newSlave);
diff --git a/src/npc/generate/lawCompliance.js b/src/npc/generate/lawCompliance.js
index d67ff08d971afaff42bc95806a0fd2ab942f9863..050138c0eab13b9324cbafdd6e0d582f3bc4272a 100644
--- a/src/npc/generate/lawCompliance.js
+++ b/src/npc/generate/lawCompliance.js
@@ -320,14 +320,16 @@ App.Desc.lawCompliance = function(slave, market = 0) {
 
 	function FSPetiteAdmirationSMR() {
 		if (!heightPass(slave)) {
-			slave.height = Height.random(slave, {skew: -1, limitMult: [-5, -2]});
+			slave.natural.height = Height.randomAdult(slave, {skew: -1, limitMult: [-5, -2]});
+			slave.height = Height.forAge(slave.natural.height, slave);
 		}
 		return `${His} height was meticulously taken before being allowed into the markets.`;
 	}
 
 	function FSStatuesqueGlorificationSMR() {
 		if (!heightPass(slave)) {
-			slave.height = Height.random(slave, {skew: 1, limitMult: [2, 5]});
+			slave.natural.height = Height.randomAdult(slave, {skew: 1, limitMult: [2, 5]});
+			slave.height = Height.forAge(slave.natural.height, slave);
 		}
 		return `${His} height, as well as ${his} potential for growth, were meticulously taken before being allowed into the markets.`;
 	}
@@ -672,10 +674,11 @@ App.Desc.lawCompliance = function(slave, market = 0) {
 	}
 
 	function heightAdvancedSMRup() {
-		slave.height = Height.random(slave, {
+		slave.natural.height = Height.randomAdult(slave, {
 			skew: V.policies.SMR.height.advancedSMR,
 			limitMult: [0, 5 * V.policies.SMR.height.advancedSMR]
 		});
+		slave.height = Height.forAge(slave.natural.height, slave);
 		let t = [`While ${he} was in the slave pens, ${he} saw that slaves on the shorter end of the height curve were immediately designated as menials and Fuckdolls.`];
 		if (slave.physicalAge < 16) {
 			t.push(`${He} is <span class="gold">terrified</span> that if ${he} doesn't keep growing, ${he}'ll be reassigned on the spot without a second thought.`);
@@ -688,10 +691,11 @@ App.Desc.lawCompliance = function(slave, market = 0) {
 	}
 
 	function heightAdvancedSMRdown() {
-		slave.height = Height.random(slave, {
+		slave.natural.height = Height.randomAdult(slave, {
 			skew: V.policies.SMR.height.advancedSMR,
 			limitMult: [0, 5 * V.policies.SMR.height.advancedSMR]
 		});
+		slave.height = Height.forAge(slave.natural.height, slave);
 		let t = [`While ${he} was in the slave pens, ${he} saw that slaves on the taller end of the height curve were immediately designated as menials and Fuckdolls.`];
 		if (slave.physicalAge < 16) {
 			t.push(`${He} is <span class="gold">terrified</span> that if ${he} goes through a growth spurt, ${he}'ll be reassigned on the spot without a second thought.`);
diff --git a/src/npc/infants/InfantState.js b/src/npc/infants/InfantState.js
index 1d74fcd36deeed36191af52fb613bd3c6de9f8a3..b0c36f76a85116b76606a57b4ffa1c64435708c5 100644
--- a/src/npc/infants/InfantState.js
+++ b/src/npc/infants/InfantState.js
@@ -13,6 +13,8 @@ App.Facilities.Nursery.InfantState = class InfantState {
 		/** @type {FC.GenderGenes} */
 		this.genes = "XX";
 		this.pronoun = App.Data.Pronouns.Kind.female;
+		/** slave's natural genetic properties */
+		this.natural = new App.Entity.GeneticState();
 		/** game week child was acquired.
 		 *
 		 * _0: Obtained prior to game start / at game start_ */
diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js
index 00d1aa92736a01108b049182270906d8249987a5..42021b2aa1b38967a555faab80c98bb226a43792 100644
--- a/src/npc/startingGirls/startingGirls.js
+++ b/src/npc/startingGirls/startingGirls.js
@@ -66,6 +66,7 @@ App.StartingGirls.cleanup = function(slave) {
 		slave.indenture = Math.clamp(slave.indenture, 26, 208) || 26;
 	}
 
+	slave.natural.height = Math.clamp(slave.natural.height, 85, 274) || 140;
 	slave.height = Math.clamp(slave.height, 85, 274) || 140;
 	slave.boobs = Math.clamp(Math.trunc(slave.boobs / 50) * 50, 0, 50000) || 200;
 	slave.hLength = Math.clamp(slave.hLength, 0, 500) || 40;
@@ -714,13 +715,13 @@ App.StartingGirls.physical = function(slave, cheat = false) {
 			.showTextBox().pulldown();
 	}
 
-	options.addOption(`Height: ${heightToEitherUnit(slave.height)}`, "height", slave).showTextBox({unit: "cm"})
+	options.addOption(`Natural Adult Height: ${heightToEitherUnit(slave.natural.height)}`, "height", slave.natural).showTextBox({unit: "cm"})
 		.addRange(145, 150, "<", "Petite")
 		.addRange(155, 160, "<", "Short")
 		.addRange(165, 170, "<", "Average")
 		.addRange(180, 185, "<", "Tall")
 		.addRange(190, 185, ">=", "Very tall");
-	option = options.addCustomOption(`Average height for a ${slave.physicalAge} year old is ${heightToEitherUnit(Height.mean(slave))}`)
+	option = options.addCustomOption(`Average natural adult height is ${heightToEitherUnit(Height.mean(slave.nationality, slave.race, slave.genes, 20))}`)
 		.addButton(
 			"Make average",
 			() => resyncSlaveHeight(slave),
@@ -729,17 +730,29 @@ App.StartingGirls.physical = function(slave, cheat = false) {
 	if (cheat || slave.geneticQuirks.dwarfism === 2) {
 		option.addButton(
 			"Make dwarf",
-			() => slave.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15}),
+			() => slave.natural.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15}),
 			""
 		);
 	}
 	if (cheat || slave.geneticQuirks.gigantism === 2) {
 		option.addButton(
 			"Make giant",
-			() => slave.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15}),
+			() => slave.natural.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15}),
 			""
 		);
 	}
+	options.addOption(`Current Height: ${heightToEitherUnit(slave.height)}`, "height", slave).showTextBox({unit: "cm"})
+		.addRange(Height.forAge(145, slave), Height.forAge(150, slave), "<", `Petite for age`)
+		.addRange(Height.forAge(155, slave), Height.forAge(160, slave), "<", "Short for age")
+		.addRange(Height.forAge(165, slave), Height.forAge(170, slave), "<", "Average for age")
+		.addRange(Height.forAge(180, slave), Height.forAge(185, slave), "<", "Tall for age")
+		.addRange(Height.forAge(190, slave), Height.forAge(185, slave), ">=", "Very tall for age");
+	options.addCustomOption(`Average height for a ${slave.physicalAge} year old is ${heightToEitherUnit(Height.mean(slave))}`)
+		.addButton(
+			"Scale for age from adult height",
+			() => slave.height = Height.forAge(slave.natural.height, slave),
+			""
+		);
 
 	if (cheat) {
 		options.addOption("Height implant", "heightImplant", slave)
@@ -1714,7 +1727,7 @@ App.StartingGirls.profile = function(slave, cheat = false) {
 
 	options.addOption("Age", "actualAge", slave).showTextBox()
 		.customButton("Resync characteristics to age", () => resyncSlaveToAge(slave), "")
-		.customButton("Resync only height to age", () => slave.height = Height.random(slave), "")
+		.customButton("Resync only height to age", () => resyncSlaveHeight(slave), "")
 		.addComment("It is recommended to resync if you change age significantly");
 	if (cheat) {
 		options.addOption("Physical age", "physicalAge", slave).showTextBox();
@@ -1821,6 +1834,11 @@ App.StartingGirls.profile = function(slave, cheat = false) {
 	options.addOption("Description", "desc", slave.custom).showTextBox({large: true})
 		.addComment("Use complete, capitalized and punctuated sentences.");
 	options.addOption("Label", "label", slave.custom).showTextBox().addComment("Use a short phrase");
+	if (V.imageChoice === 4) {
+		options.addOption("Art Seed", "artSeed", slave.natural).showTextBox({large: true})
+			.customButton("Randomize", () => slave.natural.artSeed = jsRandom(0, 10 ** 14), "")
+			.addComment(`The WebGL Art Renderer uses the art seed to set minor face and body parameters. You can change it if you don't like this slave's appearance.`);
+	}
 
 	el.append(options.render());
 	return el;
diff --git a/src/npc/startingGirls/startingGirlsPassage.js b/src/npc/startingGirls/startingGirlsPassage.js
index 91e4def4d8c6904fa16ff483c875f26090b81da9..dbdacc91f568f7bc8a957fb3f03962f3c7838cf6 100644
--- a/src/npc/startingGirls/startingGirlsPassage.js
+++ b/src/npc/startingGirls/startingGirlsPassage.js
@@ -120,7 +120,8 @@ App.StartingGirls.passage = function() {
 						V.activeSlave.face = 55;
 						V.activeSlave.muscles = 20;
 						V.activeSlave.weight = -20;
-						V.activeSlave.height = Height.forAge(190, V.activeSlave);
+						V.activeSlave.natural.height = 190;
+						V.activeSlave.height = Height.forAge(V.activeSlave.natural.height, V.activeSlave);
 					},
 					[],
 					"Starting Girls"
diff --git a/src/npc/surgery/bodySwap/bodySwap.js b/src/npc/surgery/bodySwap/bodySwap.js
index 5c6cdb2c71a87055bf9fdd14ed79048dfbb30469..a14253a4510200b1abd031c42a917888560f8df1 100644
--- a/src/npc/surgery/bodySwap/bodySwap.js
+++ b/src/npc/surgery/bodySwap/bodySwap.js
@@ -7,6 +7,7 @@
 globalThis.bodySwap = function(soul, body, fromGenepool) {
 	WombInit(body); // Just to be sure.
 	soul.genes = body.genes;
+	soul.natural = body.natural;
 	soul.physicalAge = body.physicalAge;
 	soul.visualAge = body.visualAge;
 	soul.ageImplant = body.ageImplant;
diff --git a/src/npc/surgery/surgery.js b/src/npc/surgery/surgery.js
index eb04fa79269118ef3ab0cbd960714b8f6044d0ab..1a80f90a23ad3daf5402cce3cb81c1b0c034d5bb 100644
--- a/src/npc/surgery/surgery.js
+++ b/src/npc/surgery/surgery.js
@@ -726,7 +726,7 @@ globalThis.resetEyeColor = function(slave, side = "both") {
 };
 
 /**
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  * @param {FC.GeneticQuirk} level
  */
 globalThis.induceAlbinism = function(slave, level) {
diff --git a/src/player/desc/pLongBelly.js b/src/player/desc/pLongBelly.js
index d286a0e638ef361af165bdd4a55bc94470537f95..2abd50c54d75eeb020b280dcbc97baad7aa7432a 100644
--- a/src/player/desc/pLongBelly.js
+++ b/src/player/desc/pLongBelly.js
@@ -1614,7 +1614,7 @@ App.Desc.Player.belly = function(PC = V.PC) {
 				r.push(`You're far enough along at this point that it's in your best interest to stay in the nest and wait things out instead of risking going to labor at an inopportune time.`);
 			}
 			if (PC.geneMods.rapidCellGrowth !== 1 && PC.bellyPreg >= 100000 && PC.belly > (PC.pregAdaptation * 3200) && (PC.bellyPreg >= 500000 || PC.wombImplant !== "restraint")) {
-				r.push(`You are undergoing a <span class="red">very high risk pregnancy,</span> so to decrease the likelyhood of ${V.seeExtreme === 1 && V.dangerousPregnancy === 1 ? "abdominal rupture" : "your water breaking early"}, you have been placed on medical bed rest.`);
+				r.push(`You are undergoing a <span class="red">very high risk pregnancy,</span> so to decrease the probability of ${V.seeExtreme === 1 && V.dangerousPregnancy === 1 ? "abdominal rupture" : "your water breaking early"}, you have been placed on medical bed rest.`);
 			} else if (PC.bellyPreg > PC.pregAdaptation * 1000 && PC.bellyPreg < PC.pregAdaptation * 2200 && PC.geneMods.progenitor !== 1) {
 				r.push(`You are undergoing a <span class="red">high risk pregnancy,</span> so taking things easy is probably a good idea.`);
 			}
diff --git a/src/player/js/PlayerState.js b/src/player/js/PlayerState.js
index 54e5149ca8e6ce07d6523bcab73c489d7dfb9afe..01dbb6fea5ca80b496375e75a92eeb1666dce4b7 100644
--- a/src/player/js/PlayerState.js
+++ b/src/player/js/PlayerState.js
@@ -258,6 +258,8 @@ App.Entity.PlayerState = class PlayerState {
 		this.refreshmentType = 0;
 		/** @type {number} */
 		this.pronoun = App.Data.Pronouns.Kind.male;
+		/** player's natural genetic properties */
+		this.natural = new App.Entity.GeneticState();
 		/**
 		 * * career prior to becoming owner
 		 * * (22+)			(14+)					(10+)
@@ -2039,6 +2041,10 @@ App.Entity.PlayerState = class PlayerState {
 		 *
 		 * 0: stable; 1: gaining; -1: losing */
 		this.weightDirection = 0;
+		/** Stores the exact colors of the albinism quirk
+		 * @type {{skin:string, eyeColor:string, hColor:string}}
+		 */
+		this.albinismOverride = null;
 		// exclusive minor player variables (probably) here
 		/** have you been drugged with fertility drugs
 		 *
diff --git a/src/player/pcSalon.js b/src/player/pcSalon.js
index 1c99c140dc96b4a359ed9a4ddecc06347e973811..e63c46a24df84ca385114bd8e347e3169d12823b 100644
--- a/src/player/pcSalon.js
+++ b/src/player/pcSalon.js
@@ -35,9 +35,11 @@ App.UI.playerSalon = function(PC) {
 			if (PC.tail !== "none") {
 				el.append(tail());
 			}
+			/*
 			if (PC.appendages !== "none") {
 				el.append(appendages());
 			}
+			*/
 			el.append(skin());
 		}
 		return el;
@@ -615,7 +617,7 @@ App.UI.playerSalon = function(PC) {
 			if (PC.markings === "birthmark") {
 				option = options.addOption(`You have a large visible birthmark`, "markings", PC)
 					.addValue("Bleach it", "none", billMod);
-				if (PC.prestige > 0 || PC.porn.prestige > 1) {
+				if (PC.prestige > 0) {
 					option.addComment(`It makes you look unique among your peers.`);
 				}
 			}