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/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/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/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 56448a7cdaff6b1903353af712062a70682d37b8..862d8e041712ea59dac07705fdf4f22ab720c037 100644
--- a/src/data/backwardsCompatibility/updateSlaveObject.js
+++ b/src/data/backwardsCompatibility/updateSlaveObject.js
@@ -1437,4 +1437,21 @@ App.Update.Slave = function(slave, genepool = false) {
 			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/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/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/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/intro/acquisition.js b/src/events/intro/acquisition.js
index e20aa203f71b6c69157b56b34907ed404a2a001a..f8718ee8367229eec565273633a4e38b2d5eddc4 100644
--- a/src/events/intro/acquisition.js
+++ b/src/events/intro/acquisition.js
@@ -1001,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);
@@ -1033,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 0c6f83bed7ad2ac10079dee0cbdff70de3918998..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));
@@ -299,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/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/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/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/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/player/js/PlayerState.js b/src/player/js/PlayerState.js
index ef4f1d8c425ce80ddde5fa79ca3b525179e04f02..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+)