diff --git a/src/js/descriptionWidgets.js b/src/js/descriptionWidgets.js
index a702976f1ac0da6c303a775b34d3bb6c668cdc6c..f445f1802f6615922bc78565455f48bdd2def49c 100644
--- a/src/js/descriptionWidgets.js
+++ b/src/js/descriptionWidgets.js
@@ -576,7 +576,62 @@ App.Desc.brand = function(slave, surface) {
 	} = getPronouns(slave);
 	/* eslint-enable */
 	if (State.variables.showBodyMods === 1) {
-		if (surface) { /* describes a single branded body part */
+		if (surface === "extra") { // Make a sentence that describes all body parts that aren't explicitly described elsewhere in longSlave.  If you brand a slave on her thumb, for instance.  But why.
+			let extraMarks = App.Desc.extraMarks(slave, "brand");
+			extraMarks = Object.keys(extraMarks);
+			let length = extraMarks.length;
+			if (length === 0) {
+				return r;
+			} else if (length === 1) {
+				r += `${He} also has a single unusual brand: `;
+			} else {
+				r += `${He} also has several unusual brands: `;
+			}
+
+			// If L/R parts of this object match, they will be described in the same phrase.  Length is used only to calculate punctuation, so we prepare to skip.
+			for (const bodyPart of extraMarks) {
+				if (bodyPart.startsWith("left ")) {
+					let right = "right " + bodyPart.replace("left ", "");
+					if (slave.brand[bodyPart] && slave.brand[right]) {
+						length--;
+					}
+				}
+			}
+			let counter = 0;
+			for (const bodyPart of extraMarks) {
+				counter++;
+				surface = App.Desc.oppositeSides(bodyPart);
+				if (slave.brand[surface.center]) { // center defined, body part has no mirror.
+					r += `${slave.brand[surface.center]} branded into the flesh of ${his} ${surface.center}`;
+				} else { // Center not defined, body part has a mirror.
+					if (!slave.brand[surface.left] && !slave.brand[surface.right]) {
+						// no marks
+					} else if (bodyPart.startsWith("right ") && slave.brand[surface.left]) {
+						// we already described it on the left
+					} else if (slave.brand[surface.left] === slave.brand[surface.right]) {
+						// matching places and marks
+						// note that the slave.brand object won't have slave.brand["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match.
+						r += `${slave.brand[surface.left]} branded into the flesh of both ${his} ${surface.both}`;
+					}  else if (slave.brand[surface.left] && slave.brand[surface.right]) {
+						// matching places but different marks
+						r += `both ${slave.brand[surface.left]} branded into the flesh of ${his} ${surface.left}, and ${slave.brand[surface.right]} branded into ${his} ${surface.right}`;
+					} else if (slave.brand[surface.left]) {
+						// left
+						r += `${slave.brand[surface.left]} branded into the flesh of ${his} ${surface.left}`;
+					} else if (slave.brand[surface.right]) {
+						// right
+						r += `${slave.brand[surface.right]} branded into the flesh of ${his} ${surface.right}`;
+					}
+				}
+				if (counter === length) {
+					r += `. `;
+				} else if (counter === length - 1) {
+					r += `, and `;
+				} else if (counter < length) {
+					r += `, `;
+				}
+			}
+		} else if (surface) { /* describes a single branded body part */
 			if (surface === "belly" && setup.fakeBellies.includes(bellyAccessory) && slave.brand.belly) {
 				r += `${His} fake belly has the same brand, ${slave.brand.belly}, as ${his} real one. `;
 			} else {
@@ -700,11 +755,16 @@ App.Desc.inscrip = function(slave) {
  */
 App.Desc.oppositeSides = function(surface) {
 	let parts = {};
-	if (["neck", "chest", "back", "lower back", "belly", "pubic mound"].includes(surface) || surface.startsWith("left") || surface.startsWith("right")) {
-		parts.center = surface;
-	} else {
+	if (["ear", "cheek", "shoulder", "breast", "upper arm", "lower arm", "hand", "wrist", "testicle", "buttock", "thigh", "calf", "ankle", "foot"].includes(surface) || surface.startsWith("left ") || surface.startsWith("right ")) {
 		// set up a left part and a right to check for a mirror brand or marking
-		if (surface === "feet") {
+		if (surface.startsWith("left ") || surface.startsWith("right ")) {
+			// find root word
+			if (surface.startsWith("left ")) {
+				surface = surface.replace("left ", "");
+			} else if (surface.startsWith("right ")) {
+				surface = surface.replace("right ", "");
+			}
+		} else if (surface === "feet") {
 			parts.both = surface;
 			surface = "foot";
 		} else if (surface === "calves") {
@@ -716,6 +776,49 @@ App.Desc.oppositeSides = function(surface) {
 		if (!parts.both) {
 			parts.both = surface + "s";
 		}
+	} else {
+		parts.center = surface;
 	}
 	return parts;
 };
+
+/**
+ * @param {string} slave
+ * @param {string} markType
+ * @returns {object} Returns an object containing marks that are not explicitly described elsewhere, so they can be placed in a single sentence.
+ */
+App.Desc.extraMarks = function(slave, markType) {
+	let extras = {};
+	let slaveMarks = Object.keys(slave[markType]);
+	if (markType === "brand") {
+		for (const bodyPart of slaveMarks) {
+			if ([
+				"left ear", "right ear",
+				"left cheek", "right cheek",
+				"lips", "neck",
+				"left shoulder", "right shoulder",
+				"left breast", "right breast",
+				"left upper arm", "right upper arm",
+				"left lower arm", "right lower arm",
+				"left hand", "right hand",
+				"left wrist", "right wrist",
+				"back", "lower back",
+				"penis",
+				"left testicle", "right testicle",
+				"pubic mound",
+				"belly",
+				"left buttock", "right buttock",
+				"anus", "asshole",
+				"left thigh", "right thigh",
+				"left calf", "right calf",
+				"left ankle", "right ankle",
+				"left foot", "right foot"
+			].includes(bodyPart)) {
+				continue;
+			} else {
+				extras[bodyPart] = slave[markType][bodyPart];
+			}
+		}
+	}
+	return extras;
+};
diff --git a/src/js/generateNewSlaveJS.js b/src/js/generateNewSlaveJS.js
index c781796185f1950722cdd2a2e4dba4c6dca0511f..68e8099de605f02863284984b4e4800fe9b535e3 100644
--- a/src/js/generateNewSlaveJS.js
+++ b/src/js/generateNewSlaveJS.js
@@ -65,6 +65,7 @@ window.GenerateNewSlave = (function() {
 		generateSkills();
 		generateDisabilities();
 		generateGeneticQuirkTweaks();
+		generateHormones();
 		generatePronouns(slave);
 		slave.origRace = slave.race;
 		slave.origEye = slave.eyeColor;
@@ -1708,6 +1709,39 @@ window.GenerateNewSlave = (function() {
 			}
 		}
 	}
+	
+	function generateHormones() {
+		// PubertyXX and PubertyXY == 1 at this point should guarantee functioning sex organs of the appropriate type
+		if (slave.genes === "XX") {
+			if (slave.pubertyXX === 1) {
+				if (slave.pubertyXY === 1) {
+					slave.hormoneBalance = 20;
+				} else {
+					slave.hormoneBalance = 60;
+				}
+			} else {
+				if (slave.pubertyXY === 1) {
+					slave.hormoneBalance = -20;
+				} else {
+					slave.hormoneBalance = 20;
+				}
+			}
+		} else if (slave.genes === "XY") {
+			if (slave.pubertyXX === 1) {
+				if (slave.pubertyXY === 1) {
+					slave.hormoneBalance = 20;
+				} else {
+					slave.hormoneBalance = 40;
+				}
+			} else {
+				if (slave.pubertyXY === 1) {
+					slave.hormoneBalance = -40;
+				} else {
+					slave.hormoneBalance = 20;
+				}
+			}
+		}
+	}
 
 	return GenerateNewSlave;
 })();
diff --git a/src/uncategorized/longSlaveDescription.tw b/src/uncategorized/longSlaveDescription.tw
index 8d377773f31064bb21990984805d1c276661855d..9ca4d6b520a06c3f9ddf131743bc4367709dbe98 100644
--- a/src/uncategorized/longSlaveDescription.tw
+++ b/src/uncategorized/longSlaveDescription.tw
@@ -2051,6 +2051,11 @@ $He is
 	<</if>>
 <</if>>
 
+<<if $activeSlave.fuckdoll == 0>>
+	/* Describe any brands that are not directly addressed elsewhere in longSlave */
+	<<= App.Desc.brand($activeSlave, "extra")>>
+<</if>>
+
 <<if ($showClothing == 1) && ($saleDescription == 0)>>
 
 	<<earDescription>>