diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js
index 2f4285e3dc4b9a598246d1d8d3db5628974b77fb..4954d4c97a55ef55b1a23726ccef77dcc8e7d06e 100644
--- a/src/js/SlaveState.js
+++ b/src/js/SlaveState.js
@@ -2611,9 +2611,9 @@ App.Entity.SlaveState = class SlaveState {
 		 *
 		 * 0: yes; 1+: number of swaps (increases upkeep each time) */
 		this.bodySwap = 0;
-		/** Who, if relevant, the body belonged to. */
+		/** Who, if relevant, this slave's current body belonged to originally. */
 		this.origBodyOwner = "";
-		/** Who, if relevant, the body belonged to. */
+		/** Who, if relevant, this slave's original body currently belongs to (i.e. the exact opposite of the variable above). */
 		this.origBodyOwnerID = 0;
 		/**
 		 * Slave's current hormonal balance, directs saHormones changes
diff --git a/src/npc/surgery/bodySwap/bodySwap.js b/src/npc/surgery/bodySwap/bodySwap.js
index b532dae1485c0e8cc3918711863375bb596e012e..5c6cdb2c71a87055bf9fdd14ed79048dfbb30469 100644
--- a/src/npc/surgery/bodySwap/bodySwap.js
+++ b/src/npc/surgery/bodySwap/bodySwap.js
@@ -261,7 +261,7 @@ globalThis.bodySwapSelection = function(soul) {
 			App.UI.DOM.link(
 				body.slaveName,
 				() => {
-					V.swappingSlave = body;
+					V.swappingSlave = body.ID;
 					cashX(forceNeg(cost), "slaveSurgery", body);
 				},
 				[],
@@ -335,7 +335,7 @@ globalThis.huskSwapSelection = function(body) {
 										App.UI.DOM.link(
 											soul.slaveName,
 											() => {
-												V.swappingSlave = soul;
+												V.swappingSlave = soul.ID;
 												cashX(forceNeg(cost), "slaveSurgery", soul);
 											},
 											[],
diff --git a/src/npc/surgery/bodySwap/bodySwapReaction.js b/src/npc/surgery/bodySwap/bodySwapReaction.js
index b18c2db8460914255f4ca049760d31ecf3a1c6a4..a95555ac5a3700df722b0ede0a4756916b121cac 100644
--- a/src/npc/surgery/bodySwap/bodySwapReaction.js
+++ b/src/npc/surgery/bodySwap/bodySwapReaction.js
@@ -2028,25 +2028,32 @@ globalThis.bodySwapReaction = function(body, soul) {
 				}
 			}
 
+			App.Events.addParagraph(el, r);
+			r = [];
 			if (body.fetish !== Fetish.MINDBROKEN) {
+				let recognizesBody = false;
 				if (body.origBodyOwnerID === body.ID) {
 					r.push(`This is ${his} body alright.`);
+					recognizesBody = true;
 				} else if (body.ID === body.cloneID) {
 					r.push(`This feels like ${his} body, in a sense.`);
+					recognizesBody = true;
 				}
-				r.push(`Some things might have changed,`);
-				if (body.devotion > 50) {
-					r.push(`but ${he} enjoyed the time they spent apart.`);
-				} else if (body.devotion >= -20) {
-					r.push(`but <span class="mediumaquamarine">it's good to be home.</span>`);
-					body.trust += 15;
-				} else {
-					r.push(`but <span class="mediumaquamarine">${he}'s where ${he} belongs.</span> Now to get it back the way <span class="mediumorchid">${he} likes it.</span>`);
-					body.trust += 30;
-					body.devotion -= 15;
-				}
-				if (body.ID === body.cloneID) {
-					r.push(`Whether or not ${he}'ll figure out it is a clone of ${his} original body remains to be seen.`);
+				if (recognizesBody) {
+					r.push(`Some things might have changed,`);
+					if (body.devotion > 50) {
+						r.push(`but ${he} enjoyed the time they spent apart.`);
+					} else if (body.devotion >= -20) {
+						r.push(`but <span class="mediumaquamarine">it's good to be home.</span>`);
+						body.trust += 15;
+					} else {
+						r.push(`but <span class="mediumaquamarine">${he}'s where ${he} belongs.</span> Now to get it back the way <span class="mediumorchid">${he} likes it.</span>`);
+						body.trust += 30;
+						body.devotion -= 15;
+					}
+					if (body.ID === body.cloneID) {
+						r.push(`Whether or not ${he}'ll figure out it is a clone of ${his} original body remains to be seen.`);
+					}
 				}
 			}
 		}
@@ -3782,6 +3789,8 @@ globalThis.bodySwapReaction = function(body, soul) {
 				}
 			}
 
+			App.Events.addParagraph(el, r);
+			r = [];
 			if (body.fetish !== Fetish.MINDBROKEN) {
 				if (body.origBodyOwnerID === body.ID) {
 					r.push(`This is ${his} body alright. Some things might have changed,`);
diff --git a/src/npc/surgery/bodySwap/huskSlaveSwap.js b/src/npc/surgery/bodySwap/huskSlaveSwap.js
index 599ceb4acfdf26c8084c55bd4a93179352157194..56a0b484bfeaf005c723dc8d3351b10604001135 100644
--- a/src/npc/surgery/bodySwap/huskSlaveSwap.js
+++ b/src/npc/surgery/bodySwap/huskSlaveSwap.js
@@ -1,61 +1,61 @@
 App.UI.SlaveInteract.huskSlaveSwap = function() {
 	const node = new DocumentFragment();
 
-	const oldSlave = clone(V.swappingSlave);
-	const m = V.slaveIndices[V.swappingSlave.ID];
+	const target = getSlave(V.swappingSlave);
+	const oldSlave = clone(target);
 	const {
 		he
-	} = getPronouns(V.swappingSlave);
+	} = getPronouns(target);
 
-	App.UI.DOM.appendNewElement("p", node, `You strap ${V.slaves[m].slaveName}, and the body to which ${he} will be transferred, into the remote surgery and stand back as it goes to work.`);
-	bodySwap(V.slaves[m], V.activeSlave, false);
-	const gps = V.genePool.findIndex(function(s) { return s.ID === V.slaves[m].ID; });
-	// special exception to swap genePool since the temporary body lacks an entry. Otherwise we could just call the widget using the genePool entries
-	V.genePool[gps].race = V.slaves[m].race;
-	V.genePool[gps].origRace = V.slaves[m].origRace;
-	V.genePool[gps].skin = V.slaves[m].skin;
-	V.genePool[gps].markings = V.slaves[m].markings;
-	V.genePool[gps].eye.origColor = V.slaves[m].eye.origColor;
-	V.genePool[gps].origHColor = V.slaves[m].origHColor;
-	V.genePool[gps].origSkin = V.slaves[m].origSkin;
-	V.genePool[gps].face = V.slaves[m].face;
-	V.genePool[gps].pubicHStyle = V.slaves[m].pubicHStyle;
-	V.genePool[gps].underArmHStyle = V.slaves[m].underArmHStyle;
-	V.genePool[gps].eyebrowHStyle = V.slaves[m].eyebrowHStyle;
+	App.UI.DOM.appendNewElement("p", node, `You strap ${target.slaveName}, and the body to which ${he} will be transferred, into the remote surgery and stand back as it goes to work.`);
+	bodySwap(target, V.activeSlave, false);
+	const gps = V.genePool.find(s => s.ID === target.ID);
+	// special exception to swap genePool since the temporary body lacks an entry. Otherwise we could just call bodySwap using the genePool entries
+	gps.race = target.race;
+	gps.origRace = target.origRace;
+	gps.skin = target.skin;
+	gps.markings = target.markings;
+	gps.eye.origColor = target.eye.origColor;
+	gps.origHColor = target.origHColor;
+	gps.origSkin = target.origSkin;
+	gps.face = target.face;
+	gps.pubicHStyle = target.pubicHStyle;
+	gps.underArmHStyle = target.underArmHStyle;
+	gps.eyebrowHStyle = target.eyebrowHStyle;
 
 	App.Events.addParagraph(node, [
-		`After an honestly impressive procedure, ${V.slaves[m].slaveName} is recovering nicely.`,
-		bodySwapReaction(V.slaves[m], oldSlave)
+		`After an honestly impressive procedure, ${target.slaveName} is recovering nicely.`,
+		bodySwapReaction(target, oldSlave)
 	]);
 
 	const cost = slaveCost(oldSlave);
 	const payout = Math.trunc(cost/3);
 	let r = [];
-	r.push(`${V.slaves[m].slaveName}'s old body was bought by the Flesh Heap for ${cashFormat(payout)}.`);
-	if (V.slaves[m].bodySwap > 0) {
-		const myBody = V.slaves.findIndex(function(s) { return s.origBodyOwnerID === V.slaves[m].ID; });
-		if (myBody !== -1) {
-			V.slaves[myBody].origBodyOwnerID = 0;
+	r.push(`${target.slaveName}'s old body was bought by the Flesh Heap for ${cashFormat(payout)}.`);
+	if (target.bodySwap > 0) {
+		const origBodyOwner = V.slaves.find(s => s.origBodyOwnerID === target.ID);
+		if (origBodyOwner) {
+			origBodyOwner.origBodyOwnerID = 0;
 			const {
 				he2, him2, his2
-			} = getPronouns(V.slaves[myBody]).appendSuffix("2");
-			if (V.slaves[myBody].fetish !== Fetish.MINDBROKEN && V.slaves[myBody].fuckdoll === 0) {
-				if (V.slaves[myBody].devotion > 20) {
-					r.push(`${V.slaves[myBody].slaveName} is somewhat saddened to see ${his2} body leave forever.`);
-				} else if (V.slaves[myBody].devotion >= -50) {
-					r.push(`${V.slaves[myBody].slaveName} is <span class="mediumorchid">disturbed</span> to find ${his2} body is gone for good, damaging ${his2} <span class="gold">ability to trust you.</span>`);
-					V.slaves[myBody].devotion -= 30;
-					V.slaves[myBody].trust -= 30;
+			} = getPronouns(origBodyOwner).appendSuffix("2");
+			if (origBodyOwner.fetish !== Fetish.MINDBROKEN && origBodyOwner.fuckdoll === 0) {
+				if (origBodyOwner.devotion > 20) {
+					r.push(`${origBodyOwner.slaveName} is somewhat saddened to see ${his2} body leave forever.`);
+				} else if (origBodyOwner.devotion >= -50) {
+					r.push(`${origBodyOwner.slaveName} is <span class="mediumorchid">disturbed</span> to find ${his2} body is gone for good, damaging ${his2} <span class="gold">ability to trust you.</span>`);
+					origBodyOwner.devotion -= 30;
+					origBodyOwner.trust -= 30;
 				} else {
-					r.push(`${V.slaves[myBody].slaveName} is <span class="mediumorchid">deeply upset</span> that ${he2}'ll never see ${his2} body again. With so little left, ${he2} finds it easy to take vengeance by <span class="orangered">completely rejecting your ownership of ${him2}.</span>`);
-					V.slaves[myBody].devotion -= 50;
-					V.slaves[myBody].trust = 100;
+					r.push(`${origBodyOwner.slaveName} is <span class="mediumorchid">deeply upset</span> that ${he2}'ll never see ${his2} body again. With so little left, ${he2} finds it easy to take vengeance by <span class="orangered">completely rejecting your ownership of ${him2}.</span>`);
+					origBodyOwner.devotion -= 50;
+					origBodyOwner.trust = 100;
 				}
 			}
 		}
 	}
 	App.Events.addParagraph(node, r);
-	V.slaves[m].bodySwap++;
+	target.bodySwap++;
 	cashX(payout, "slaveTransfer");
 	V.activeSlave = 0;
 	V.swappingSlave = 0;
diff --git a/src/npc/surgery/bodySwap/slaveSlaveSwap.js b/src/npc/surgery/bodySwap/slaveSlaveSwap.js
index 285c6cf015f1588f2b2945a44b10e626aa14bc3f..77097c3d15b044a97b25c105cd948fceac11173a 100644
--- a/src/npc/surgery/bodySwap/slaveSlaveSwap.js
+++ b/src/npc/surgery/bodySwap/slaveSlaveSwap.js
@@ -1,57 +1,55 @@
 App.UI.SlaveInteract.slaveSlaveSwap = function() {
 	const node = new DocumentFragment();
 
-	const ss1 = V.slaveIndices[V.AS];
-	const ss1Clone = clone(getSlave(V.AS));
+	const ss1 = getSlave(V.AS);
+	const ss1Clone = clone(ss1);
 
-	const ss2 = V.slaveIndices[V.swappingSlave.ID];
-	const ss2Clone = clone(V.swappingSlave);
+	const ss2 = getSlave(V.swappingSlave);
+	const ss2Clone = clone(ss2);
 
-	const gps1 = V.genePool.findIndex(s => s.ID === V.slaves[ss1].ID);
-	const gps1Clone = clone(V.genePool[gps1]);
+	const gps1 = V.genePool.find(s => s.ID === ss1.ID);
+	const gps1Clone = clone(gps1);
 
-	const gps2 = V.genePool.findIndex(s => s.ID === V.slaves[ss2].ID);
-	const gps2Clone = clone(V.genePool[gps2]);
+	const gps2 = V.genePool.find(s => s.ID === ss2.ID);
+	const gps2Clone = clone(gps2);
 
-	App.UI.DOM.appendNewElement("p", node, `You strap ${getSlave(V.AS).slaveName} and ${V.swappingSlave.slaveName} into the remote surgery and stand back as it goes to work.`);
+	App.UI.DOM.appendNewElement("p", node, `You strap ${ss1.slaveName} and ${ss2.slaveName} into the remote surgery and stand back as it goes to work.`);
 
-	bodySwap(V.slaves[ss1], ss2Clone, false);
-	bodySwap(V.genePool[gps1], gps2Clone, true);
+	bodySwap(ss1, ss2Clone, false);
+	bodySwap(gps1, gps2Clone, true);
 
-	bodySwap(V.slaves[ss2], ss1Clone, false);
-	bodySwap(V.genePool[gps2], gps1Clone, true);
+	bodySwap(ss2, ss1Clone, false);
+	bodySwap(gps2, gps1Clone, true);
+
+	// figuring out who has whose body now
+	whoHasWho(ss1, ss2, ss2Clone);
+	whoHasWho(ss2, ss1, ss1Clone);
+
+	// now to handle whose body it is, name-wise
+	bodySwapName(ss1, ss2Clone);
+	bodySwapName(ss2, ss1Clone);
 
 	App.Events.addParagraph(node, [
-		`After an honestly impressive procedure, ${V.slaves[ss1].slaveName} is recovering nicely.`,
-		bodySwapReaction(V.slaves[ss1], ss1Clone)
+		`After an honestly impressive procedure, ${ss1.slaveName} is recovering nicely.`,
+		bodySwapReaction(ss1, ss1Clone)
 	]);
 
 	App.UI.DOM.appendNewElement("hr", node);
 
 	App.Events.addParagraph(node, [
-		`In the neighboring bed, ${V.slaves[ss2].slaveName} rests peacefully.`,
-		bodySwapReaction(V.slaves[ss2], ss2Clone)
+		`In the neighboring bed, ${ss2.slaveName} rests peacefully.`,
+		bodySwapReaction(ss2, ss2Clone)
 	]);
 
-	// figuring out whom has whose body now
-	whoHasWho(ss1, ss2Clone);
-	whoHasWho(ss2, ss1Clone);
-
-	// now to handle whose body it is, name-wise
-	bodySwapName(V.slaves[ss1], V.slaves[ss2]);
-	bodySwapName(V.slaves[ss2], V.slaves[ss1]);
-
 	for (const ss of [ss1, ss2]) {
-		if (ss1Clone.bodySwap > 0) {
-			if (V.slaves[ss].origBodyOwnerID === V.slaves[ss].ID) {
-				V.slaves[ss].bodySwap = 0;
-				V.slaves[ss].origBodyOwnerID = 0;
-				V.slaves[ss].origBodyOwner = "";
-			} else {
-				V.slaves[ss].bodySwap++;
-			}
+		if (ss.origBodyOwnerID === ss.ID) {
+			// if we got our own original body back, clear our bodyswap records
+			ss.bodySwap = 0;
+			ss.origBodyOwnerID = 0;
+			ss.origBodyOwner = "";
 		} else {
-			V.slaves[ss].bodySwap++;
+			// otherwise, increment the bodyswap counter
+			ss.bodySwap++;
 		}
 	}
 
@@ -59,13 +57,22 @@ App.UI.SlaveInteract.slaveSlaveSwap = function() {
 	V.swappingSlave = 0;
 	return node;
 
-	function whoHasWho(index, opposingClone) {
-		if (V.slaves[index].bodySwap === 0) {
-			V.slaves[index].origBodyOwnerID = opposingClone.ID;
-		} else if (V.slaves[ss2].origBodyOwner !== "") { // now who's going to be looking for you?
-			const myBody = V.slaves.findIndex(function(s) { return s.origBodyOwnerID === V.slaves[ss2].ID; });
-			if (myBody !== -1) {
-				V.slaves[myBody].origBodyOwnerID = V.slaves[index].ID;
+	/** Update origBodyOwnerID appropriately.
+	 * @param {App.Entity.SlaveState} target
+	 * @param {App.Entity.SlaveState} opposing
+	 * @param {App.Entity.SlaveState} opposingClone
+	 */
+	function whoHasWho(target, opposing, opposingClone) {
+		if (opposingClone.bodySwap === 0) {
+			// if my new body came directly from its original owner, give them a reference to me
+			opposing.origBodyOwnerID = target.ID;
+		} else {
+			// if my new body originally belonged to someone else, update the original owner's reference to point to me
+			// note that the original owner may also be me; we'll take care of that later (after generating the reaction)
+			// but we never want to find a self-reference, since those are always temporary
+			const originalOwner = V.slaves.find(s => s.origBodyOwnerID === opposingClone.ID && s.origBodyOwnerID !== s.ID);
+			if (originalOwner) {
+				originalOwner.origBodyOwnerID = target.ID;
 			}
 		}
 	}