diff --git a/src/markets/bulkSlave/bulkSlaveIntro.js b/src/markets/bulkSlave/bulkSlaveIntro.js
index 18ca0d1bcd652376e6c555eaf4d182138a5b9c6a..04f2b0b8beee2fb95d4755e1d45f3ecc2c41ad9c 100644
--- a/src/markets/bulkSlave/bulkSlaveIntro.js
+++ b/src/markets/bulkSlave/bulkSlaveIntro.js
@@ -1,14 +1,21 @@
-App.Markets.bulkSlaveIntro = function() {
+/**
+ * 
+ * @param {boolean} [generateNeeded=false]
+ */
+App.Markets.bulkSlaveIntro = function(generateNeeded = false) {
 	const el = new DocumentFragment();
 	const r = [];
-	const discount = App.Markets.getDiscount();
+	const discount = getDiscount();
 	let seed;
 	let p;
-	if (!V.market.introType || V.market.newSlaves.length === 0) {
-		V.market.introType = "";
+	let spent;
+
+	if (generateNeeded) {
+		bulkSlaveGenerate();
 	}
-	if (isNaN(V.market.newSlaveIndex)) {
-		V.market.newSlaveIndex = 0;
+
+	if (V.market.newSlaves.length === 0) {
+		V.market.introType = "";
 	}
 
 	switch (V.market.introType) {
@@ -40,7 +47,7 @@ App.Markets.bulkSlaveIntro = function() {
 			} else {
 				r.push(`With all your discounts factored in you got a <span class="yellowgreen">${(500 - discount) / 5}%</span> discount;`);
 			}
-			r.push(`You spent <span class="yellowgreen">${cashFormat(V.spent)}</span> on your new slaves.`);
+			r.push(`You spent <span class="yellowgreen">${cashFormat(spent)}</span> on your new slaves.`);
 			break;
 		case "inStock":
 			r.push(`You clear out ${App.Markets.marketName(V.market.slaveMarket, V.market.numArcology)} of its stock of ${V.market.newSlaves.length} slaves.`);
@@ -51,7 +58,7 @@ App.Markets.bulkSlaveIntro = function() {
 			} else {
 				r.push(`With all your discounts factored in you got a <span class="yellowgreen">${(500 - discount) / 5}%</span> discount`);
 			}
-			r.push(`You spent <span class="yellowgreen">${cashFormat(V.spent)}</span> on your new slaves.`);
+			r.push(`You spent <span class="yellowgreen">${cashFormat(spent)}</span> on your new slaves.`);
 			break;
 		case "liquidator":
 			r.push(`Your new pair of slaves look frightened and uncertain, but seem encouraged by each other's presence.`);
@@ -119,78 +126,163 @@ App.Markets.bulkSlaveIntro = function() {
 
 	V.market.newSlaveIndex++;
 	return el;
-};
 
-App.Markets.getDiscount = function() {
-	/* Discount calculation. Gives 5% on top of slave school discount */
-	let discount = 475;
-	let opinion;
-	switch (V.market.slaveMarket) {
-		case "TSS":
-			if (V.TSS.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "TUO":
-			if (V.TUO.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "GRI":
-			if (V.GRI.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "SCP":
-			if (V.SCP.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "LDE":
-			if (V.LDE.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "TGA":
-			if (V.TGA.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "HA":
-			if (V.HA.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "NUL":
-			if (V.NUL.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "TCR":
-			if (V.TCR.schoolUpgrade !== 0) {
-				discount = 375;
-			}
-			break;
-		case "TFS":
-			if (V.TFS.schoolUpgrade !== 0) {
-				discount = 300;
+	function bulkSlaveGenerate() {
+		V.market.newSlaves = [];
+		V.market.newSlavesDone = 0;
+		V.market.newSlaveIndex = 0;
+		V.market.introType = "bulk";
+		let _slaveCost;
+		if (!V.market.numSlaves) {
+			V.market.numSlaves = 5;
+		}
+
+		for (let _i = 0; _i < V.market.numSlaves; _i++) {
+			let slave = (generateMarketSlave(V.market.slaveMarket, V.market.numArcology)).slave;
+			V.slavesSeen++;
+			if (App.Data.misc.lawlessMarkets.includes(V.market.slaveMarket)) {
+				_slaveCost = slaveCost(slave);
 			} else {
-				discount = 380;
+				const _backup = slave; /* backup newly generated slave */
+				App.Desc.lawCompliance(slave, V.market.slaveMarket); /* includes CheckForGingering — slave stats may change, affecting price */
+				_slaveCost = slaveCost(slave);
+				removeGingering(); /* remove gingered state, if applied, so we can apply it again later */
+				slave = _backup; /* restore backup so we can apply Law Compliance again later */
 			}
-			break;
-		case "corporate":
-			if (V.corp.Market === 1) {
-				discount = 350;
+
+			/* Adjust _slaveCost according to V.slavesSeen */
+			if (V.slavesSeen > V.slaveMarketLimit) {
+				_slaveCost += _slaveCost*((V.slavesSeen-V.slaveMarketLimit)*0.1);
+				if (V.market.introType === "inStock") {
+					break;
+				}
 			}
-			break;
-		case "neighbor":
-			if (V.market.numArcology >= V.arcologies.length) {
-				V.market.numArcology = 1;
+
+			/* Apply discount modifier */
+			_slaveCost = discount*Math.trunc(_slaveCost/500);
+
+			/* Charge the Player for the slave, or break out if cannot afford */
+			if (V.cash < _slaveCost) {
+				_i = V.market.numSlaves;
+				break;
+			} else {
+				cashX(forceNeg(_slaveCost), "slaveTransfer", slave);
+				V.market.newSlaves.push(slave);
+				spent += _slaveCost;
 			}
-			opinion = App.Neighbor.opinion(0, V.market.numArcology);
-			opinion = Math.clamp(Math.trunc(opinion/20), -10, 10);
-			discount -= (opinion * 25);
-			break;
+		}
+
+		/* Max Buy clean-up */
+		if (V.market.numSlaves === 9999) {
+			V.market.numSlaves = V.market.newSlaves.length;
+		}
+
+		/* increment Slave school purchase counts if needed */
+		switch (V.market.slaveMarket) {
+			case "TSS":
+				V.TSS.studentsBought += V.market.newSlaves.length;
+				break;
+			case "TUO":
+				V.TUO.studentsBought += V.market.newSlaves.length;
+				break;
+			case "GRI":
+				V.GRI.studentsBought += V.market.newSlaves.length;
+				break;
+			case "SCP":
+				V.SCP.studentsBought += V.market.newSlaves.length;
+				break;
+			case "LDE":
+				V.LDE.studentsBought += V.market.newSlaves.length;
+				break;
+			case "TGA":
+				V.TGA.studentsBought += V.market.newSlaves.length;
+				break;
+			case "HA":
+				V.HA.studentsBought += V.market.newSlaves.length;
+				break;
+			case "TCR":
+				V.TCR.studentsBought += V.market.newSlaves.length;
+				break;
+			case "TFS":
+				V.TFS.studentsBought += V.market.newSlaves.length;
+				break;
+			case "NUL":
+				V.NUL.studentsBought += V.market.newSlaves.length;
+				break;
+		}
+	}
+
+	function getDiscount() {
+		/* Discount calculation. Gives 5% on top of slave school discount */
+		let discount = 475;
+		let opinion;
+		switch (V.market.slaveMarket) {
+			case "TSS":
+				if (V.TSS.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "TUO":
+				if (V.TUO.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "GRI":
+				if (V.GRI.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "SCP":
+				if (V.SCP.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "LDE":
+				if (V.LDE.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "TGA":
+				if (V.TGA.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "HA":
+				if (V.HA.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "NUL":
+				if (V.NUL.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "TCR":
+				if (V.TCR.schoolUpgrade !== 0) {
+					discount = 375;
+				}
+				break;
+			case "TFS":
+				if (V.TFS.schoolUpgrade !== 0) {
+					discount = 300;
+				} else {
+					discount = 380;
+				}
+				break;
+			case "corporate":
+				if (V.corp.Market === 1) {
+					discount = 350;
+				}
+				break;
+			case "neighbor":
+				if (V.market.numArcology >= V.arcologies.length) {
+					V.market.numArcology = 1;
+				}
+				opinion = App.Neighbor.opinion(0, V.market.numArcology);
+				opinion = Math.clamp(Math.trunc(opinion/20), -10, 10);
+				discount -= (opinion * 25);
+				break;
+		}
+		return discount;
 	}
-	return discount;
 };
diff --git a/src/pregmod/theBlackMarket.tw b/src/pregmod/theBlackMarket.tw
index 9ea2771d5d384abacb409334012b8d5bb9237ff3..19d24e97cc8d0150e12df67a2cd6134916783c29 100644
--- a/src/pregmod/theBlackMarket.tw
+++ b/src/pregmod/theBlackMarket.tw
@@ -34,10 +34,10 @@ There is quite the selection of refreshments available, you could always shift y
 	A convoy of scientists from the banned wetware CPU project are present and selling their leftover wares.
 	[[Browse CPUs|Slave Markets][$market.slaveMarket = "wetware", $slavesSeen += 1]] |
 	<<if $cash > _minimumFive>>
-		[[(x5)|Bulk Slave Generate][$market.slaveMarket = "wetware", $market.introType = "bulk", $market.numSlaves = 5]] |
+		[[(x5)|Bulk Slave Intro][$market.slaveMarket = "wetware", $market.introType = "bulk", $market.numSlaves = 5]] |
 	<</if>>
 	<<if $cash > _minimumTen>>
-		[[(x10)|Bulk Slave Generate][$market.slaveMarket = "wetware", $market.introType = "bulk", $market.numSlaves = 10]] |
+		[[(x10)|Bulk Slave Intro][$market.slaveMarket = "wetware", $market.introType = "bulk", $market.numSlaves = 10]] |
 	<</if>>
 <</if>>
 */
diff --git a/src/uncategorized/bulkSlaveGenerate.tw b/src/uncategorized/bulkSlaveGenerate.tw
index 82b3a8e14c94080adea4e6127e175c79389fab75..1c8448aa5140d1b94c57b1c79c15d36b2365ceab 100644
--- a/src/uncategorized/bulkSlaveGenerate.tw
+++ b/src/uncategorized/bulkSlaveGenerate.tw
@@ -1,75 +1,3 @@
 :: Bulk Slave Generate [nobr]
 
-<<set $returnTo = "Main", $market.newSlaves = [], $market.newSlavesDone = 0, $market.newSlaveIndex = 0, $market.introType = "bulk", $spent = 0>>
-
-<<if ndef $market.numSlaves>>
-	<<set $market.numSlaves = 5>>
-<</if>>
-
-<<set _discount = App.Markets.getDiscount()>>
-
-<<for _i = 0; _i < $market.numSlaves; _i++>>
-	<<set $activeSlave = (generateMarketSlave($market.slaveMarket, $market.numArcology)).slave>>
-	<<set $slavesSeen++>>
-	<<if App.Data.misc.lawlessMarkets.includes($market.slaveMarket)>>
-		<<set _slaveCost = slaveCost($activeSlave)>>
-	<<else>>
-		<<set _backup = $activeSlave>> /* backup newly generated slave */
-		<<run App.Desc.lawCompliance($activeSlave, $market.slaveMarket)>> /* includes CheckForGingering — slave stats may change, affecting price */
-		<<set _slaveCost = slaveCost($activeSlave)>>
-		<<run removeGingering()>> /* remove gingered state, if applied, so we can apply it again later */
-		<<set $activeSlave = _backup>> /* restore backup so we can apply Law Compliance again later */
-	<</if>>
-
-	/* Adjust _slaveCost according to $slavesSeen */
-	<<if $slavesSeen > $slaveMarketLimit>>
-		<<set _slaveCost += _slaveCost*(($slavesSeen-$slaveMarketLimit)*0.1)>>
-		<<if $market.introType == "inStock">>
-			<<break>>
-		<</if>>
-	<</if>>
-
-	/* Apply discount modifier */
-	<<set _slaveCost = _discount*Math.trunc(_slaveCost/500)>>
-
-	/* Charge the Player for the slave, or break out if cannot afford */
-	<<if $cash < _slaveCost>>
-		<<set _i = $market.numSlaves>>
-		<<break>>
-	<<else>>
-		<<run cashX(forceNeg(_slaveCost), "slaveTransfer", $activeSlave)>>
-		<<set $market.newSlaves.push($activeSlave)>>
-		<<set $spent += _slaveCost>>
-	<</if>>
-<</for>>
-
-/* Max Buy clean-up */
-<<if $market.numSlaves == 9999>>
-	<<set $market.numSlaves = $market.newSlaves.length>>
-<</if>>
-
-/* increment Slave school purchase counts if needed */
-<<switch $market.slaveMarket>>
-<<case "TSS">>
-	<<set $TSS.studentsBought += $market.newSlaves.length>>
-<<case "TUO">>
-	<<set $TUO.studentsBought += $market.newSlaves.length>>
-<<case "GRI">>
-	<<set $GRI.studentsBought += $market.newSlaves.length>>
-<<case "SCP">>
-	<<set $SCP.studentsBought += $market.newSlaves.length>>
-<<case "LDE">>
-	<<set $LDE.studentsBought += $market.newSlaves.length>>
-<<case "TGA">>
-	<<set $TGA.studentsBought += $market.newSlaves.length>>
-<<case "HA">>
-	<<set $HA.studentsBought += $market.newSlaves.length>>
-<<case "TCR">>
-	<<set $TCR.studentsBought += $market.newSlaves.length>>
-<<case "TFS">>
-	<<set $TFS.studentsBought += $market.newSlaves.length>>
-<<case "NUL">>
-	<<set $NUL.studentsBought += $market.newSlaves.length>>
-<</switch>>
-
-<<goto "Bulk Slave Intro">>
+<<includeDOM App.Markets.bulkSlaveIntro(true)>>