diff --git a/js/003-data/startingGirlsData.js b/js/003-data/startingGirlsData.js
new file mode 100644
index 0000000000000000000000000000000000000000..5af7cb18d04f3431ebb94cebf9417a19a6c6feef
--- /dev/null
+++ b/js/003-data/startingGirlsData.js
@@ -0,0 +1,96 @@
+/**
+ * @typedef startingGirlsOptionsPreset
+ * @property {string} name
+ * @property {number} value
+ * @property {number} max
+ * @property {0|1} [extreme] undefined: ignore settings, 0: only when V.seeExtreme === 0, 1: only when V.seeExtreme === 1
+ * @property {"on"|"off"} [style]
+ */
+
+/**
+ * @type {Object<string, Array<startingGirlsOptionsPreset>>}
+ */
+App.Data.StartingGirls = {
+	weight: [
+		{name: "Emaciated", value: -100, max: -95},
+		{name: "Skinny", value: -50, max: -30},
+		{name: "Thin", value: -20, max: -10},
+		{name: "Average", value: 0, max: 10},
+		{name: "Plush", value: 20, max: 30},
+		{name: "Chubby", value: 50, max: 95},
+		{name: "Fat", value: 100, max: 130},
+		{name: "Obese", value: 140, max: 160},
+		{name: "Super obese", value: 180, max: 190},
+		{name: "Dangerously obese", value: 200, max: 999}
+	],
+	muscles: [
+		{name: "Frail", value: -100, max: -95},
+		{name: "Very weak", value: -66, max: -50},
+		{name: "Weak", value: -41, max: -5},
+		{name: "Normal", value: 0, max: 5},
+		{name: "Toned", value: 20, max: 30},
+		{name: "Well built", value: 40, max: 50},
+		{name: "Quite muscular", value: 65, max: 95},
+		{name: "Ripped", value: 100, max: 999}
+	],
+	waist: [
+		{name: "Absurd", value: -100, max: -95},
+		{name: "Hourglass", value: -55, max: -40},
+		{name: "Feminine", value: -25, max: -15},
+		{name: "Average", value: 0, max: 10},
+		{name: "Unattractive", value: 15, max: 40},
+		{name: "Ugly", value: 55, max: 95},
+		{name: "Masculine", value: 100, max: 999}
+	],
+	face: [
+		{name: "Very Ugly", value: -100, max: -95},
+		{name: "Ugly", value: -55, max: -40},
+		{name: "Unattractive", value: -15, max: -10},
+		{name: "Average", value: 0, max: 10},
+		{name: "Attractive", value: 15, max: 40},
+		{name: "Beautiful", value: 55, max: 95},
+		{name: "Very beautiful", value: 100, max: 999}
+	],
+	lips: [
+		{name: "Thin", value: 5, max: 10},
+		{name: "Normal", value: 15, max: 20},
+		{name: "Pretty", value: 25, max: 40},
+		{name: "Plush", value: 55, max: 70},
+		{name: "Huge", value: 85, max: 95, extreme: 1},
+		{name: "Facepussy", value: 100, max: 999, extreme: 1},
+		{name: "Huge", value: 85, max: 999, extreme: 0}
+	],
+	intelligence: [
+		{name: "Moronic", value: -100, max: -95},
+		{name: "Very stupid", value: -60, max: -50},
+		{name: "Stupid", value: -30, max: -15},
+		{name: "Average", value: 0, max: 15},
+		{name: "Smart", value: 30, max: 50},
+		{name: "Very smart", value: 60, max: 95},
+		{name: "Brilliant", value: 100, max: 999}
+	],
+	fetishStrength: [
+		{name: "Very Low", value: 15, max: 30},
+		{name: "Low", value: 45, max: 60},
+		{name: "Normal", value: 75, max: 85},
+		{name: "High", value: 90, max: 95},
+		{name: "Extremely High", value: 100, max: 999}
+	],
+	attr: [
+		{name: "Disgusted", value: 0, max: 5, style: "off"},
+		{name: "Turned off", value: 10, max: 15, style: "off"},
+		{name: "Not attracted", value: 25, max: 35, style: "off"},
+		{name: "Indifferent", value: 50, max: 65},
+		{name: "Attracted", value: 75, max: 85, style: "on"},
+		{name: "Aroused", value: 90, max: 95, style: "on"},
+		{name: "Passionate", value: 100, max: 999, style: "on"}
+	],
+	energy: [
+		{name: "Frigid", value: 5, max: 10, style: "off"},
+		{name: "Poor", value: 25, max: 40, style: "off"},
+		{name: "Average", value: 45, max: 60},
+		{name: "Powerful", value: 65, max: 80, style: "on"},
+		{name: "Sex addict", value: 85, max: 99, style: "on"},
+		{name: "Nympho", value: 100, max: 999, style: "on"}
+	]
+};
diff --git a/src/npc/generate/generateNewSlaveJS.js b/src/npc/generate/generateNewSlaveJS.js
index 732f28ce54a3405c468b97d7bf88fe4eeb5744c9..a4e5cfb6a8831629c3fbd1009e806faf56f499f4 100644
--- a/src/npc/generate/generateNewSlaveJS.js
+++ b/src/npc/generate/generateNewSlaveJS.js
@@ -71,6 +71,7 @@ globalThis.GenerateNewSlave = (function() {
 		slave.devotion = jsRandom(-90, -60);
 		slave.trust = jsRandom(-45, -25);
 		slave.weight = jsRandom(-100, 180);
+		slave.muscles = jsRandom(-5, 15);
 		setHealth(slave);
 
 		WombInit(slave);
diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js
index 4742905683b367543449ed1a92fe21fe3eea94d6..44c4dcc99b928394d0ee30b97943a425fff78218 100644
--- a/src/npc/startingGirls/startingGirls.js
+++ b/src/npc/startingGirls/startingGirls.js
@@ -12,6 +12,36 @@ App.StartingGirls.generate = function(params) {
 	slave.canRecruit = 0;
 	slave.weekAcquired = 0;
 
+	// map wide range attributes to presets
+	/**
+	 * Maps a generated value to the corresponding preset
+	 *
+	 * @param {number} value
+	 * @param {Array<startingGirlsOptionsPreset>} presets
+	 * @returns {number}
+	 * @throws RangeError
+	 */
+	function mapValue(value, presets) {
+		for (const entry of presets) {
+			if ((entry.extreme === undefined || entry.extreme === V.seeExtreme)
+				&& value < entry.max) {
+				return entry.value;
+			}
+		}
+		throw new RangeError(`${typeof value} ${value} not contained in given set.`);
+	}
+
+	slave.weight = mapValue(slave.weight, App.Data.StartingGirls.weight);
+	slave.muscles = mapValue(slave.muscles, App.Data.StartingGirls.muscles);
+	slave.waist = mapValue(slave.waist, App.Data.StartingGirls.waist);
+	slave.face = mapValue(slave.face, App.Data.StartingGirls.face);
+	slave.lips = mapValue(slave.lips, App.Data.StartingGirls.lips);
+	slave.intelligence = mapValue(slave.intelligence, App.Data.StartingGirls.intelligence);
+	slave.fetishStrength = mapValue(slave.fetishStrength, App.Data.StartingGirls.fetishStrength);
+	slave.attrXY = mapValue(slave.attrXY, App.Data.StartingGirls.attr);
+	slave.attrXX = mapValue(slave.attrXY, App.Data.StartingGirls.attr);
+	slave.energy = mapValue(slave.energy, App.Data.StartingGirls.energy);
+
 	return slave;
 };
 
@@ -619,6 +649,22 @@ App.StartingGirls.applyPlayerOrigin = function(slave) {
 	}
 };
 
+/**
+ * @param {Object} option
+ * @param {Array<startingGirlsOptionsPreset>} set
+ */
+App.StartingGirls.addSet = function(option, set) {
+	set.forEach((preset) => {
+		if (preset.extreme === undefined
+			|| preset.extreme === V.seeExtreme) {
+			option.addValue(preset.name, preset.value);
+			if (preset.style) {
+				option[preset.style]();
+			}
+		}
+	});
+};
+
 App.StartingGirls.physical = function(slave) {
 	const el = new DocumentFragment();
 	const {he} = getPronouns(slave);
@@ -653,36 +699,17 @@ App.StartingGirls.physical = function(slave) {
 			);
 	}
 
-	options.addOption("Weight", "weight", slave)
-		.addRange(-100, -95, "<", "Emaciated")
-		.addRange(-50, -30, "<", "Skinny")
-		.addRange(-20, -10, "<", "Thin")
-		.addRange(0, 10, "<", "Average")
-		.addRange(20, 30, "<", "Plush")
-		.addRange(50, 95, "<", "Chubby")
-		.addRange(100, 130, "<", "Fat")
-		.addRange(140, 160, "<", "Obese")
-		.addRange(180, 190, "<", "Super obese")
-		.addRange(200, 190, ">=", "Dangerously obese");
-
-	options.addOption("Muscles", "muscles", slave)
-		.addRange(-100, -96, "<", "Frail")
-		.addRange(-66, -51, "<", "Very weak")
-		.addRange(-41, -6, "<", "Weak")
-		.addRange(0, 5, "<", "Normal")
-		.addRange(20, 30, "<", "Toned")
-		.addRange(40, 50, "<", "Well built")
-		.addRange(65, 95, "<", "Quite muscular")
-		.addRange(100, 95, ">=", "Ripped");
-
-	options.addOption("Waist", "waist", slave)
-		.addRange(-100, -95, "<", "	Absurd")
-		.addRange(-55, -40, "<", "Hourglass")
-		.addRange(-25, -15, "<", "Feminine")
-		.addRange(0, 10, "<", "Average")
-		.addRange(15, 40, "<", "Unattractive")
-		.addRange(55, 95, "<", "Ugly")
-		.addRange(100, 10, ">=", "Masculine");
+	App.StartingGirls.addSet(
+		options.addOption("Weight", "weight", slave),
+		App.Data.StartingGirls.weight);
+
+	App.StartingGirls.addSet(
+		options.addOption("Muscles", "muscles", slave),
+		App.Data.StartingGirls.muscles);
+
+	App.StartingGirls.addSet(
+		options.addOption("Waist", "waist", slave),
+		App.Data.StartingGirls.waist);
 
 	option = options.addOption("Facial appearance", "faceShape", slave)
 		.addValue("Normal", "normal");
@@ -691,14 +718,9 @@ App.StartingGirls.physical = function(slave) {
 	}
 	option.addValueList([["Androgynous", "androgynous"], ["Cute", "cute"], ["Sensual", "sensual"], ["Exotic", "exotic"]]);
 
-	options.addOption("Facial attractiveness", "face", slave)
-		.addRange(-100, -95, "<", "Very ugly")
-		.addRange(-55, -40, "<", "Ugly")
-		.addRange(-15, -10, "<", "Unattractive")
-		.addRange(0, 10, "<", "Average")
-		.addRange(15, 40, "<", "Attractive")
-		.addRange(55, 95, "<", "Beautiful")
-		.addRange(100, 95, ">=", "Very beautiful");
+	App.StartingGirls.addSet(
+		options.addOption("Facial attractiveness", "face", slave),
+		App.Data.StartingGirls.face);
 
 	const optionLeft = options.addOption("Left eye", "vision", slave.eye.left);
 	const optionRight = options.addOption("Right eye", "vision", slave.eye.right);
@@ -730,17 +752,9 @@ App.StartingGirls.physical = function(slave) {
 		slave.hears = 2;
 	}
 
-	option = options.addOption("Lips", "lips", slave)
-		.addRange(5, 10, "<", "Thin")
-		.addRange(15, 20, "<", "Normal")
-		.addRange(25, 40, "<", "Pretty")
-		.addRange(55, 70, "<", "Plush");
-	if (V.seeExtreme === 1) {
-		option.addRange(85, 95, "<", "Huge")
-			.addRange(100, 95, ">=", "Facepussy");
-	} else {
-		option.addRange(85, 70, ">=", "Huge");
-	}
+	App.StartingGirls.addSet(
+		options.addOption("Lips", "lips", slave),
+		App.Data.StartingGirls.lips);
 
 	options.addOption("Voice", "voice", slave)
 		.addValueList([["Mute", 0], ["Deep", 1], ["Normal", 2], ["High", 3]]);
@@ -1230,8 +1244,9 @@ App.StartingGirls.mental = function(slave) {
 	let option;
 	let r;
 
-	options.addOption("Intelligence", "intelligence", slave)
-		.addValueList([["Moronic", -100], ["Very stupid", -60], ["Stupid", -30], ["Average", 0], ["Smart", 30], ["Very smart", 60], ["Brilliant", 100]]);
+	App.StartingGirls.addSet(
+		options.addOption("Intelligence", "intelligence", slave),
+		App.Data.StartingGirls.intelligence);
 
 	options.addOption("Education", "intelligenceImplant", slave)
 		.addValueList([["Uneducated", 0], ["Educated", 15], ["Well educated", 30]]);
@@ -1297,47 +1312,30 @@ App.StartingGirls.mental = function(slave) {
 		}
 
 		if (slave.fetish !== "none" && slave.fetish !== "mindbroken") {
-			options.addOption("Fetish strength", "fetishStrength", slave)
-				.addRange(15, 30, "<=", "Very Low")
-				.addRange(45, 60, "<=", "Low")
-				.addRange(75, 85, "<=", "Normal")
-				.addRange(90, 95, "<=", "High")
-				.addRange(100, 95, ">", "Extremely High");
+			App.StartingGirls.addSet(
+				options.addOption("Fetish strength", "fetishStrength", slave),
+				App.Data.StartingGirls.fetishStrength);
 		}
 	}
 
 	options.addOption("Sexuality", "attrKnown", slave)
 		.addValue("Known", 1, () => {
-			slave.attrXX = random(0, 100);
-			slave.attrXY = random(0, 100);
-			slave.energy = random(1, 90);
+			slave.attrXX = App.Data.StartingGirls.attr.random().value;
+			slave.attrXY = App.Data.StartingGirls.attr.random().value;
+			slave.energy = App.Data.StartingGirls.energy.random().value;
 		}).on()
 		.addValue("Unknown", 0).off();
 	if (slave.attrKnown === 1) {
-		options.addOption("Attraction to men", "attrXY", slave)
-			.addRange(0, 5, "<=", "Disgusted").off()
-			.addRange(10, 15, "<=", "Turned off").off()
-			.addRange(25, 35, "<=", "Not attracted").off()
-			.addRange(50, 65, "<=", "Indifferent").neutral()
-			.addRange(75, 85, "<=", "Attracted").on()
-			.addRange(90, 95, "<=", "Aroused").on()
-			.addRange(100, 95, ">", "Passionate").on();
-		options.addOption("Attraction to women", "attrXX", slave)
-			.addRange(0, 5, "<=", "Disgusted").off()
-			.addRange(10, 15, "<=", "Turned off").off()
-			.addRange(25, 35, "<=", "Not attracted").off()
-			.addRange(50, 65, "<=", "Indifferent").neutral()
-			.addRange(75, 85, "<=", "Attracted").on()
-			.addRange(90, 95, "<=", "Aroused").on()
-			.addRange(100, 95, ">", "Passionate").on();
-
-		options.addOption("Sex drive", "energy", slave)
-			.addRange(5, 10, "<=", "Frigid").off()
-			.addRange(25, 40, "<=", "Poor").off()
-			.addRange(45, 60, "<=", "Average").neutral()
-			.addRange(65, 80, "<=", "Powerful").on()
-			.addRange(85, 99, "<=", "Sex addict").on()
-			.addRange(100, 99, ">", "Nympho").on();
+		App.StartingGirls.addSet(
+			options.addOption("Attraction to men", "attrXY", slave),
+			App.Data.StartingGirls.attr);
+		App.StartingGirls.addSet(
+			options.addOption("Attraction to women", "attrXX", slave),
+			App.Data.StartingGirls.attr);
+
+		App.StartingGirls.addSet(
+			options.addOption("Sex drive", "energy", slave),
+			App.Data.StartingGirls.energy);
 	}
 
 	if (slave.fetish !== "mindbroken") {