diff --git a/src/Mods/SecExp/buildings/weaponsManufacturing.tw b/src/Mods/SecExp/buildings/weaponsManufacturing.tw
index d5814aa04453baf417bb1cab4952a172879a1f44..94bac86edd151ed077c3c4d23d644b6ed343591f 100644
--- a/src/Mods/SecExp/buildings/weaponsManufacturing.tw
+++ b/src/Mods/SecExp/buildings/weaponsManufacturing.tw
@@ -164,7 +164,7 @@ You own <<print num($menials)>> free menial slaves. This manufacturing complex c
 				<<set _reasons.push('drug lab needs more advanced equipement')>>
 			<</if>>
 			<<if $SecExp.edicts.SFSupportLevel < 2 || $SecExp.edicts.SFSupportLevel < 4 || $SecExp.edicts.SFSupportLevel < 5>>
-				<<set _reasons.push('support contract needs more clauses')>>
+				<<set _reasons.push('pass higher SF support edicts')>>
 			<</if>>
 			<<if $SF.Squad.Firebase < 7>>
 				<<set _reasons.push('Firebase would likely require additional expansion(s)')>>
diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js
index 9e0232e3971d6588a96fc65a6f6967951022c514..3b553724ee80d8668ae86a128255bfc16cb788f5 100644
--- a/src/data/backwardsCompatibility/backwardsCompatibility.js
+++ b/src/data/backwardsCompatibility/backwardsCompatibility.js
@@ -360,6 +360,10 @@ App.Update.globalVariables = function(node) {
 		delete V.killChoice;
 	}
 
+	if (V.foodCrisis) {
+		delete V.foodCrisis;
+	}
+
 	App.SecExp.generalBC();
 	App.SF.BC();
 
diff --git a/src/endWeek/nextWeek/resetGlobals.js b/src/endWeek/nextWeek/resetGlobals.js
index ac5fc9999b4f472eb7c62f90843ae58147dc4109..183ec6d4a276d3683134c081fe34191162536b14 100644
--- a/src/endWeek/nextWeek/resetGlobals.js
+++ b/src/endWeek/nextWeek/resetGlobals.js
@@ -5,12 +5,6 @@ App.EndWeek.resetGlobals = function() {
 	// Integer and float variables. No real need to zero them out but doesn't hurt to have them in a known state, though this might mask variables NaN'ing out. Takes up the least amount of Memory besides a "" string.
 	V.i = 0;
 	V.j = 0;
-	V.motherSlave = -1;
-	V.daughterSlave = -1;
-	V.devMother = -1;
-	V.devDaughter = -1;
-	V.youngerSister = -1;
-	V.olderSister = -1;
 
 	// Other arrays
 	V.events = [];
@@ -25,7 +19,6 @@ App.EndWeek.resetGlobals = function() {
 	V.PETSevent = [];
 	V.FSNonconformistEvents = [];
 	V.REButtholeCheckinIDs = [];
-	V.rebelSlaves = [];
 	V.eligibleSlaves = [];
 
 	// Slave Objects using 0 instead of null. Second most memory eaten up.
diff --git a/src/events/RE/reLegendaryFormerAbolitionist.js b/src/events/RE/reLegendaryFormerAbolitionist.js
index a8f5a11e26a97c95d659db11a50f027762e09cab..4435717401c49594864c7a4688f7cae994045279 100644
--- a/src/events/RE/reLegendaryFormerAbolitionist.js
+++ b/src/events/RE/reLegendaryFormerAbolitionist.js
@@ -15,7 +15,7 @@ App.Events.RELegendaryFormerAbolitionist = class RELegendaryFormerAbolitionist e
 				"$He is an enslaved member of an anti-slavery extremist group.",
 			].includes(s.origin) ||
 			s.career === "an antislavery activist",
-			s.newGamePlus === 0,
+			(s) => s.newGamePlus === 0,
 			(s) => [Job.MASTERSUITE, Job.CONCUBINE, Job.FUCKTOY].includes(s.assignment)
 		]];
 	}
diff --git a/src/events/eventUtils.js b/src/events/eventUtils.js
index e1a495ba95abbe263fbb61de1086b85374b3ba92..1108ba9f7a3d8d511749fe210c1edf0bd8c12cda 100644
--- a/src/events/eventUtils.js
+++ b/src/events/eventUtils.js
@@ -165,7 +165,7 @@ App.Events.Result = class {
 	/**
 	 * @param {string} [text] - the link text for the response
 	 * @param {resultHandler} [handler] - the function to call to generate the result when the link is clicked
-	 * @param {string|Node} [note] - a note to provide alongside the link (for example, a cost or virginity loss warning)
+	 * @param {string} [note] - a note to provide alongside the link (for example, a cost or virginity loss warning)
 	 * To mark an option as disabled, construct the result with only the note.
 	 */
 	constructor(text, handler, note) {
@@ -194,14 +194,7 @@ App.Events.Result = class {
 	makeResponse(node) {
 		let wrote = false;
 		if (this.text && this.handler) {
-			node.appendChild(App.UI.DOM.link(this.text, () => this.handle(node)));
-			wrote = true;
-		}
-		if (wrote && this.note) {
-			node.append(" ");
-		}
-		if (this.note) {
-			node.appendChild(App.UI.DOM.makeElement("span", this.note, "detail"));
+			node.appendChild(App.UI.DOM.link(this.text, () => this.handle(node), [], '', this.note));
 			wrote = true;
 		}
 		return wrote;
diff --git a/src/events/nonRandom/daughters/pCoupAftermath.js b/src/events/nonRandom/daughters/pCoupAftermath.js
new file mode 100644
index 0000000000000000000000000000000000000000..1cb22feecace1fd6b202b876015ec6e5f20d75d6
--- /dev/null
+++ b/src/events/nonRandom/daughters/pCoupAftermath.js
@@ -0,0 +1,143 @@
+App.Events.PCoupAftermath = class REShippingContainer extends App.Events.BaseEvent {
+	execute(node) {
+		let r = [];
+
+		V.nextButton = " "; // hide button until user makes a selection
+		V.rivalOwner = 0;
+		V.rivalryPower = 0;
+		if (random(0, 99) <= V.seeDicks) {
+			V.rivalGender = 2;
+		} else {
+			V.rivalGender = 1;
+		}
+		const {
+			HeR,
+			heR, himR,
+		} = getPronouns({pronoun: (V.rivalGender === 2) ? App.Data.Pronouns.Kind.male : App.Data.Pronouns.Kind.female}).appendSuffix("R");
+		const {heA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
+
+		const rivalArc = (V.rivalSet !== 0) ? V.arcologies.find(arc => arc.rival === 1) : null;
+		V.fcnn.push("...evidence also suggests that the Daughters of Liberty had also planned a terrorist attack on...");
+
+		if (V.mercenaries > 3) {
+			r.push(`Your ${V.mercenariesTitle}`);
+		} else if (V.mercenaries > 0) {
+			r.push(`Your mercenaries`);
+		} else if (V.arcologyUpgrade.drones > 0) {
+			r.push(`Your security drones`);
+		} else {
+			r.push(`Private security teams`);
+		}
+		r.push(`perform the grisly task of disposing of the bodies of the Daughters killed in the assault. They strip them of anything that might be of use in cleaning up after the attempted coup — communication devices, PDAs, computers, even handwritten notes. The raw intel is scanned and passed to ${V.assistant.name}. Most of it is rubbish.`);
+		App.Events.addParagraph(node, r);
+		r = [];
+		r.push(`Some of it is not. There is evidence of payments from a ${V.rivalSet === 0 ? "nearby Free City" : "neighboring arcology"} to the leadership of the Daughters. ${capFirstChar(V.assistant.name)} is silent for a long time, crosschecking records to assemble a complete picture despite your enemies' attempts to disguise the transactions. Finally, ${V.assistant.name} finishes and displays a picture, using nearly the entire surface of your desk for effect.`);
+		if (V.assistant.personality > 0) {
+			r.push(`"This," ${heA} says in a tone of satisfaction, "is the`);
+			if (V.rivalGender === 2) {
+				r.push(`bastard`);
+			} else if (V.rivalGender === 1) {
+				r.push(`bitch`);
+			} else {
+				r.push(`cunt`);
+			}
+			r.push(`you want, ${properTitle()}."`);
+		} else {
+			r.push(`"This," ${heA} says neutrally, "is the culprit, ${properTitle()}."`);
+		}
+
+		r.push(`The face is vigorous, determined, and`);
+		if (V.rivalGender === 2) {
+			r.push(`masculine. The very stereotype of the male arcology owner.`);
+		} else if (V.rivalGender === 1) {
+			r.push(`feminine. The very stereotype of the female arcology owner.`);
+		} else {
+			r.push(`androgynous. The very stereotype of the dissolute arcology owner.`);
+		}
+		if (rivalArc) {
+			r.push(
+				`And, as you suspected, it's one of your neighbors. It's the individual who owns`,
+				App.UI.DOM.makeElement("span", `${rivalArc.name}.`, "bold")
+			);
+			App.Events.addParagraph(node, r);
+			r = [];
+		}
+
+		r.push(`Your assistant continues, "${HeR} came into an arcology about when you did, ${properTitle()}. It seems the Daughters originally planned to attack ${himR}, but ${heR} bought them off and sent them after you, instead."`);
+		if (V.assistant.personality > 0) {
+			r.push(`"I wonder," ${heA} teases, "if ${heR} thinks you're cute, or what?"`);
+		}
+		App.Events.addParagraph(node, r);
+		r = [];
+		r.push(`You inquire as to whether there's any identifiable cause for the evident dislike.`);
+		if (V.rivalryFS !== 0) {
+			r.push(`"Definitely," says your assistant. "The most cursory review of the recent history of this Free City shows that divergence began with your selection of ${V.rivalryFS} as a society model for the future. They immediately went the opposite direction."`);
+		} else {
+			r.push(`"No," says your assistant. "It may be that giving the Daughters an alternative target was necessary and you were simply unlucky. Alternatively, this may be envy of your success; of rising arcology owners, you have come farthest, fastest."`);
+		}
+
+		App.Events.addParagraph(node, r);
+
+		const cashTrace = 20000;
+		App.Events.addResponses(node, [
+			new App.Events.Result(`Contact the culprit privately and discuss the matter`, privately),
+			new App.Events.Result(`Reveal the evidence publicly`, publicly),
+			new App.Events.Result(`Devote funds to tracing the evidence`, trace, `This will cost ${cashFormat(cashTrace)}`)
+		]);
+
+		function privately() {
+			const frag = new DocumentFragment();
+			let r = [];
+			unlock();
+			r.push(`Your fellow arcology owner proves very receptive to your missive, as well they might. Your defeat of the Daughters has made a major impact on the willingness of slaveowners to discuss slave revolts in public, and any arcology owner who was proved to be funding anti-slaver violence, even under duress, would be shunned. With very little prompting, ${heR} forwards a <span class="cash inc">huge indemnity payment.</span> It's nowhere near enough to cause bankruptcy, but it's enough to give you a massive advantage should you find yourselves at odds again.`);
+			cashX(100000, "war");
+			App.Events.addParagraph(frag, r);
+			return frag;
+		}
+
+		function publicly() {
+			const frag = new DocumentFragment();
+			let r = [];
+			unlock();
+			r.push(`Free Cities society is understandably reluctant to condemn, never mind depose, arcology owners. The precedent of removing one would be bad, even if the public brought enough strength together to accomplish it. Your evidence looks quite bad, but isn't so incontrovertible as to cause your fellow aristocrats to take such a drastic measure. Nonetheless, the public is aghast at the spectacle of an arcology owner funding an attack on another. Opinion <span class="rep inc">rallies</span> around you, and you even receive some discreet <span class="cash inc">donations,</span> delivered with the intimation that they are to be used against your enemy. There is stony silence from the Daughters' backer; today, you began a real inter-arcology war.`);
+			repX(1000, "war");
+			cashX(10000, "war");
+			V.rivalryPower = 1;
+			if (rivalArc) {
+				rivalArc.embargo = 2;
+				rivalArc.embargoTarget = 0;
+				rivalArc.influenceTarget = 0;
+				V.rivalOwner = rivalArc.prosperity;
+			} else {
+				V.rivalOwner = V.arcologies[0].prosperity;
+			}
+			App.Events.addParagraph(frag, r);
+			return frag;
+		}
+
+		function trace() {
+			const frag = new DocumentFragment();
+			let r = [];
+			unlock();
+			r.push(`The money flows out, and the information flows in. You are rewarded with a reasonably complete picture of your rival's operations. The intelligence will be extremely useful going forward, since by gathering it, you sent an unmistakable signal that you do not consider the matter closed. There is stony silence from the Daughters' backer; today, you began a real inter-arcology war. But, with this information, you can maintain it from a position of advantage.`);
+			cashX(-cashTrace, "war");
+			V.rivalryPower = 5;
+			if (rivalArc) {
+				rivalArc.embargo = 3;
+				rivalArc.embargoTarget = 0;
+				rivalArc.influenceTarget = 0;
+				V.rivalOwner = rivalArc.prosperity;
+			} else {
+				V.rivalOwner = V.arcologies[0].prosperity;
+			}
+			App.Events.addParagraph(frag, r);
+			return frag;
+		}
+
+		/** unlock Continue button */
+		function unlock() {
+			V.nextButton = "Continue";
+			App.Utils.updateUserButton();
+		}
+	}
+};
diff --git a/src/events/nonRandom/daughters/pCoupAftermath.tw b/src/events/nonRandom/daughters/pCoupAftermath.tw
deleted file mode 100644
index 9e3f8c86d2248d0955867f82b3f55fb0450bb8dc..0000000000000000000000000000000000000000
--- a/src/events/nonRandom/daughters/pCoupAftermath.tw
+++ /dev/null
@@ -1,98 +0,0 @@
-:: P coup aftermath [nobr]
-
-<<set $nextButton = " ", $rivalOwner = 0, $rivalryPower = 0, _num = random(0,99)>> /* hide button until user makes a selection */
-<<if _num <= $seeDicks>>
-	<<set $rivalGender = 2>>
-<<else>>
-	<<set $rivalGender = 1>>
-<</if>>
-<<if $rivalGender == 2>>
-	<<set _heR = "he">>
-	<<set _himR = "him">>
-	<<set _HeR = capFirstChar(_heR)>>
-<<else>>
-	<<set _heR = "she">>
-	<<set _himR = "her">>
-	<<set _HeR = capFirstChar(_heR)>>
-<</if>>
-<<setAssistantPronouns>>
-<<set $fcnn.push("...evidence also suggests that the Daughters of Liberty had also planned a terrorist attack on...")>>
-
-<<if $mercenaries > 3>>Your $mercenariesTitle<<elseif $mercenaries > 0>>Your mercenaries<<elseif $arcologyUpgrade.drones > 0>>Your security drones<<else>>Private security teams<</if>> perform the grisly task of disposing of the bodies of the Daughters killed in the assault. They strip them of anything that might be of use in cleaning up after the attempted coup — communication devices, PDAs, computers, even handwritten notes. The raw intel is scanned and passed to $assistant.name. Most of it is rubbish.
-<br><br>
-Some of it is not. There is evidence of payments from a <<if $rivalSet == 0>>nearby Free City<<else>>neighboring arcology<</if>> to the leadership of the Daughters. <<= capFirstChar($assistant.name)>> is silent for a long time, crosschecking records to assemble a complete picture despite your enemies' attempts to disguise the transactions. Finally, $assistant.name finishes and displays a picture, using nearly the entire surface of your desk for effect. <<if $assistant.personality > 0>>"This," _heA says in a tone of satisfaction, "is the <<if $rivalGender == 2>>bastard<<elseif $rivalGender == 1>>bitch<<else>>cunt<</if>> you want, <<= properTitle()>>."<<else>>"This," _heA says neutrally, "is the culprit, <<= properTitle()>>."<</if>>
-
-The face is vigorous, determined, and <<if $rivalGender == 2>>masculine. The very stereotype of the male arcology owner<<elseif ($rivalGender == 1)>>feminine. The very stereotype of the female arcology owner<<else>>androgynous. The very stereotype of the dissolute arcology owner<</if>>.
-<<if $rivalSet != 0>>
-	And, as you suspected, it's one of your neighbors. It's the individual who owns
-	<<for $i = 0; $i < $arcologies.length; $i++>>
-		<<if $arcologies[$i].rival == 1>>
-			''$arcologies[$i].name.''
-			<<break>>
-		<</if>>
-	<</for>>
-	<br><br>
-<</if>>
-Your assistant continues, "_HeR came into an arcology about when you did, <<= properTitle()>>. It seems the Daughters originally planned to attack _himR, but _heR bought them off and sent them after you, instead."<<if $assistant.personality > 0>> "I wonder," _heA teases, "if _heR thinks you're cute, or what?"<</if>>
-<br><br>
-You inquire as to whether there's any identifiable cause for the evident dislike.
-<<if $rivalryFS != 0>>
-	"Definitely," says your assistant. "The most cursory review of the recent history of this Free City shows that divergence began with your selection of $rivalryFS as a society model for the future. They immediately went the opposite direction."
-<<else>>
-	"No," says your assistant. "It may be that giving the Daughters an alternative target was necessary and you were simply unlucky. Alternatively, this may be envy of your success; of rising arcology owners, you have come farthest, fastest."
-<</if>>
-
-<br><br>
-
-<span id="result">
-<<link "Contact the culprit privately and discuss the matter">>
-	<<set $nextButton = "Continue">><<run App.Utils.updateUserButton()>> /* unlock Continue button */
-	<<replace "#result">>
-	Your fellow arcology owner proves very receptive to your missive, as well they might. Your defeat of the Daughters has made a major impact on the willingness of slaveowners to discuss slave revolts in public, and any arcology owner who was proved to be funding anti-slaver violence, even under duress, would be shunned. With very little prompting, _heR forwards a @@.yellowgreen;huge indemnity payment.@@ It's nowhere near enough to cause bankruptcy, but it's enough to give you a massive advantage should you find yourselves at odds again.
-	<<run cashX(100000, "war")>>
-	<</replace>>
-<</link>>
-<br><<link "Reveal the evidence publicly">>
-	<<set $nextButton = "Continue">><<run App.Utils.updateUserButton()>> /* unlock Continue button */
-	<<replace "#result">>
-	Free Cities society is understandably reluctant to condemn, never mind depose, arcology owners. The precedent of removing one would be bad, even if the public brought enough strength together to accomplish it. Your evidence looks quite bad, but isn't so incontrovertible as to cause your fellow aristocrats to take such a drastic measure. Nonetheless, the public is aghast at the spectacle of an arcology owner funding an attack on another. Opinion @@.green;rallies@@ around you, and you even receive some discreet @@.yellowgreen;donations,@@ delivered with the intimation that they are to be used against your enemy. There is stony silence from the Daughters' backer; today, you began a real inter-arcology war.
-	<<run repX(1000, "war")>>
-	<<run cashX(10000, "war")>>
-	<<set $rivalryPower = 1>>
-	<<if $rivalSet != 0>>
-		<<for $i = 0; $i < $arcologies.length; $i++>>
-			<<if $arcologies[$i].rival == 1>>
-				<<set $arcologies[$i].embargo = 2>>
-				<<set $arcologies[$i].embargoTarget = 0>>
-				<<set $arcologies[$i].influenceTarget = 0>>
-				<<set $rivalOwner = $arcologies[$i].prosperity>>
-				<<break>>
-			<</if>>
-		<</for>>
-	<<else>>
-		<<set $rivalOwner = $arcologies[0].prosperity>>
-	<</if>>
-	<</replace>>
-<</link>>
-<br><<link "Devote funds to tracing the evidence">>
-	<<set $nextButton = "Continue">><<run App.Utils.updateUserButton()>> /* unlock Continue button */
-	<<replace "#result">>
-	The money flows out, and the information flows in. You are rewarded with a reasonably complete picture of your rival's operations. The intelligence will be extremely useful going forward, since by gathering it, you sent an unmistakable signal that you do not consider the matter closed. There is stony silence from the Daughters' backer; today, you began a real inter-arcology war. But, with this information, you can maintain it from a position of advantage.
-	<<run cashX(-20000, "war")>>
-	<<set $rivalryPower = 5>>
-	<<if $rivalSet != 0>>
-		<<for $i = 0; $i < $arcologies.length; $i++>>
-			<<if $arcologies[$i].rival == 1>>
-				<<set $arcologies[$i].embargo = 3>>
-				<<set $arcologies[$i].embargoTarget = 0>>
-				<<set $arcologies[$i].influenceTarget = 0>>
-				<<set $rivalOwner = $arcologies[$i].prosperity>>
-				<<break>>
-			<</if>>
-		<</for>>
-	<<else>>
-		<<set $rivalOwner = $arcologies[0].prosperity>>
-	<</if>>
-	<</replace>>
-<</link>> //This will cost <<print cashFormat(20000)>>//
-</span>
diff --git a/src/events/nonRandom/foodCrisis/pFoodCrisisLowerClass.js b/src/events/nonRandom/foodCrisis/pFoodCrisisLowerClass.js
new file mode 100644
index 0000000000000000000000000000000000000000..ab37feced510deccf2e0f8211981238916aa8bcf
--- /dev/null
+++ b/src/events/nonRandom/foodCrisis/pFoodCrisisLowerClass.js
@@ -0,0 +1,85 @@
+App.Events.pFoodCrisisLowerClass = class PFoodCrisis extends App.Events.BaseEvent {
+	constructor(actors, params) {
+		super(actors, params);
+	}
+
+	actorPrerequisites() {
+		return [];
+	}
+
+	eventPrerequisites() {
+		return [
+			() => App.Events.effectiveWeek() >= 48,
+			() => !!V.experimental.food,
+			() => !V.eventResults.foodCrisis,
+		];
+	}
+
+	execute(node) {
+		let r = [];
+
+		const discount = V.PC.skill.trading >= 50 && ["capitalist", "entrepreneur", "business kid"].includes(V.PC.career) || V.PC.skill.trading >= 100;
+		const price = discount ? 7500 : 10000;
+
+		r.push(`The region supplying much of the Free City's food had been battling a famine for quite some time now — between the deteriorating weather and the war raging on — but it had always seemed the situation was improving, and your arcology's citizens never really had to worry about going to bed hungry. Unfortunately, that all changed this week. A firefight had broken out near one of the region's largest farms, and one of the main reserves of food was caught in the crossfire.`);
+
+		App.Events.addParagraph(node, r);
+		r = [];
+
+		r.push(`Supplies steadily began to dwindle, and it wasn't long before the prices of food began to rise as a result. ${V.arcologyUpgrade.hydro ? `Even the hydroponics system you had installed earlier could barely put a dent in the needs of your citizens.` : ``} Now, the poorest in your arcology are facing starvation. Seeing no other choice, they turned to you to provide them with sustenance. <span class="bold">This is a unique opportunity.</span> It's unlikely your citizens would ask for your help again, should you choose not to help them.`);
+
+		App.Events.addResponses(node, [
+			new App.Events.Result(`Provide them with ample rations`, ample, `This will cost ${cashFormat(price * 2.5)} and ${discount ? `some upkeep, reduced by your knowledge of trading` : `will incur significant upkeep costs`}.`),
+			new App.Events.Result(`Give them enough to survive on`, enough, `This will cost ${cashFormat(price * 1.5)} and ${discount ? `some upkeep, reduced by your knowledge of trading` : `will incur significant upkeep costs`}.`),
+			new App.Events.Result(`They can figure their problem out on their own`, refuse)
+		]);
+
+		V.eventResults.foodCrisis = 1;	// don't repeat this event
+
+		function ample() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`You have enough to go around, so you decide to help the desperate citizens. You have a number of rationing stations set up throughout ${V.arcologies[0].name} and announce that each citizen is entitled to four full meals a day, more than enough to sate the hunger of even the most famished of men. Your citizens are <span class="reputation inc">thrilled</span> to hear that their leader is looking out for them.`);
+
+			V.rations = 2;
+			cashX(forceNeg(price * 2.5), "farmyard");
+			repX(3500, "event");
+
+			App.Events.queueEvent(2, new App.Events.pFoodCrisisMiddleClass());
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+
+		function enough() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`You have your own problems to deal with, but that doesn't mean you don't look out for your own. You have a number of rationing stations set up throughout ${V.arcologies[0].name} and announce that each citizen is entitled to two full meals a day, just enough for your citizens not to starve. Your citizens are <span class="reputation inc">happy</span> to hear that their leader is looking out for them.`);
+
+			V.rations = 1;
+			cashX(forceNeg(price * 1.5), "farmyard");
+			repX(2000, "event");
+
+			App.Events.queueEvent(2, new App.Events.pFoodCrisisMiddleClass());
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+
+		function refuse() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`You have your own problems to deal with, and you simply can't afford to drop everything and solve theirs at the moment. That you can't take care of your arcology's citizen <span class="reputation dec">reflects poorly on you.</span>`);
+
+			V.rations = 0;
+			repX(-1500, "event");
+
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+	}
+};
diff --git a/src/events/nonRandom/foodCrisis/pFoodCrisisMiddleClass.js b/src/events/nonRandom/foodCrisis/pFoodCrisisMiddleClass.js
new file mode 100644
index 0000000000000000000000000000000000000000..ea38c57ddd178d23755ee06e65e9bc640eee50cc
--- /dev/null
+++ b/src/events/nonRandom/foodCrisis/pFoodCrisisMiddleClass.js
@@ -0,0 +1,78 @@
+App.Events.pFoodCrisisMiddleClass = class PFoodCrisis extends App.Events.BaseEvent {
+	constructor(actors, params) {
+		super(actors, params);
+	}
+
+	actorPrerequisites() {
+		return [];
+	}
+
+	eventPrerequisites() {
+		return [
+			() => !!V.experimental.food,
+		];
+	}
+
+	execute(node) {
+		const r = [];
+
+		const discount = V.PC.skill.trading >= 50 && ["capitalist", "entrepreneur", "business kid"].includes(V.PC.career) || V.PC.skill.trading >= 100;
+		const price = discount ? 7500 : 10000;
+
+		r.push(`It's been a few weeks since your citizens had approached you asking for aid, and since then, the situation hasn't improved. In fact, it had gotten worse, and food prices have reached a record high. The tension in ${V.arcologies[0].name} is palpable, and small riots have broken out more than once over disputes about food. You are not surprised, then, when you receive a visit from some more of your citizens – not the poor, but not wealthy either. They state that they noticed that you have been giving out rations to the poorer citizens, and, now that the situation has become dire, were wondering if you would be willing to do the same for them.`);
+
+		App.Events.addParagraph(node, r);
+
+		App.Events.addResponses(node, [
+			new App.Events.Result(`Give them generous rations as well`, ample, `This will cost ${cashFormat(price * 2)} and ${discount ? `some upkeep, reduced by your knowledge of trading` : `will incur significant upkeep costs`}.`),
+			new App.Events.Result(`Give them enough to survive on`, enough, `This will cost ${cashFormat(price)} and ${discount ? `some upkeep, reduced by your knowledge of trading` : `will incur significant upkeep costs`}.`),
+			new App.Events.Result(`Change your mind about giving out any rations at all`, refuse)
+		]);
+
+		function ample() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`You still have more than enough to go around, so you inform the leaders that you have decided you will give them large rations, enough to feed even the hungriest citizen. The leaders are <span class="reputation inc">very pleased</span> to hear that you are taking care of them as well.`);
+
+			V.rations = 4;
+			cashX(forceNeg(price * 2), "farmyard");
+			repX(3000, "event");
+
+			App.Events.queueEvent(2, new App.Events.pFoodCrisisUpperClass());
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+
+		function enough() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`As much as you'd like to provide them with all of the food in the world, it simply is not feasible in your current situation. Therefore, you announce to the leaders that you will provide them only enough rations to live off of. The leaders understand, and are <span class="reputation inc">pleased</span> to hear that you would provide for them at all.`);
+
+			V.rations = 3;
+			cashX(forceNeg(price), "farmyard");
+			repX(1500, "event");
+
+			App.Events.queueEvent(2, new App.Events.pFoodCrisisUpperClass());
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+
+		function refuse() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`Having given the people rations at all was a mistake, you think to yourself. You have a great number of your own problems to deal with, and providing rations to everyone that can't afford food is putting an unnecessary strain on your own situation. With this is mind, you tell the leaders that you simply can't help them at this time, and have decided that you can't help anyone with food at all. The citizens are understandably <span class="reputation dec">angry</span> that you would go back on your word.`);
+
+			V.rations = 0;
+			repX(-1500, "event");
+
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+	}
+};
diff --git a/src/events/nonRandom/foodCrisis/pFoodCrisisUpperClass.js b/src/events/nonRandom/foodCrisis/pFoodCrisisUpperClass.js
new file mode 100644
index 0000000000000000000000000000000000000000..64ef82e2379b410177fbb444f2c0ff28aaeed17d
--- /dev/null
+++ b/src/events/nonRandom/foodCrisis/pFoodCrisisUpperClass.js
@@ -0,0 +1,82 @@
+App.Events.pFoodCrisisUpperClass = class PFoodCrisis extends App.Events.BaseEvent {
+	constructor(actors, params) {
+		super(actors, params);
+	}
+
+	actorPrerequisites() {
+		return [];
+	}
+
+	eventPrerequisites() {
+		return [
+			() => !!V.experimental.food,
+		];
+	}
+
+	execute(node) {
+		let r = [];
+
+		const discount = V.PC.skill.trading >= 50 && ["capitalist", "entrepreneur", "business kid"].includes(V.PC.career) || V.PC.skill.trading >= 100;
+		const price = discount ? 7500 : 10000;
+
+		r.push(`Another few weeks has passed since your last meeting with your citizens regarding rationing, and things have only deteriorated further since then. It was only a matter of time, then, before the wealthier citizens of ${V.arcologies[0].name} paid you a visit one afternoon. While being able to afford food wasn't exactly difficult for them as of yet, they could read the writing on the wall, and knew it would only be a matter of time before the prices of food were so high that even they would be forced to beg for handouts.`);
+
+		App.Events.addParagraph(node, r);
+		r = [];
+
+		r.push(`Seeing the progress you had made since taking control of the arcology, they decided their best course of action was to come to you with a proposition. They would allow you to take full control of the food supply in ${V.arcologies[0].name}, and in return you would keep them well-fed. <span class="bold">This is a unique opportunity.</span> If you turn their offer down, the citizens of your arcology will find another way of surviving.`);
+
+		App.Events.addParagraph(node, r);
+
+		App.Events.addResponses(node, [
+			new App.Events.Result(`Set up a food market`, foodMarket, `This will cost an initial investment of ${cashFormat(price * 15)}${discount ? `, reduced by your knowledge of trading` : ``}.`),
+			new App.Events.Result(`Politely decline their offer, but continue giving them rations`, enough, `This will cost ${cashFormat(price)} and ${discount ? `some upkeep, reduced by your knowledge of trading` : `will incur significant upkeep costs`}.`),
+			new App.Events.Result(`Turn down their offer and end rationing completely`, refuse),
+		]);
+
+		function foodMarket() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`You know that a proposition like this wouldn't have been easy for your citizens to make, and you also know that there is no one better suited to a task like this than you. You announce that you will be setting up a market to buy, sell, and store food in, and that you'll make sure that the citizens will continue to be well-fed. Your citizens are <span class="reputation inc">glad</span> to hear that you are looking out for their best interests.`);
+
+			V.foodMarket = 1;
+			V.rations = 0;
+			cashX(forceNeg(price * 15), "farmyard");
+			repX(5000, "event");
+
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+
+		function enough() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`Things have been going fairly well for you, but not <em>that</em> well — setting up an entirely new place to buy, sell, and store food would no doubt be an expensive undertaking. You tell the citizens that while you can't spare the resources to create a new market at the moment, you will honor your past agreement and continue giving them free rations. The people initially seem a bit disappointed that you don't seem to want to expand ${V.arcologies[0].name}, but are ultimately <span class="reputation inc">glad</span> to hear that you'll continue taking care of them.`);
+
+			V.rations = 5;
+			cashX(forceNeg(price), "farmyard");
+			repX(1500, "event");
+
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+
+		function refuse() {
+			const el = new DocumentFragment();
+			const r = [];
+
+			r.push(`While a new place to buy, sell, and store food in ${V.arcologies[0].name} would most likely come in quite handy in the future, you ultimately decide that you simply cannot spare the resources required. In fact, giving rations at all was a costly venture, and after not having seen any sort of return-on-investment, you decide that you are unable to continue giving out rations anymore. Your citizens are <span class="reputation dec">angry</span> at the fact that you seem not to care about them at all, but that's their problem.`);
+
+			V.rations = 0;
+			repX(-1500, "event");
+
+			App.Events.addParagraph(el, r);
+
+			return el;
+		}
+	}
+};
diff --git a/src/events/nonRandomEvent.js b/src/events/nonRandomEvent.js
index aa82783f01c12d7611c6392c447944bcc9f3644d..1d3fe25284ecdbbeb5f12a7c0ffb091404e8b300 100644
--- a/src/events/nonRandomEvent.js
+++ b/src/events/nonRandomEvent.js
@@ -92,6 +92,7 @@ App.Events.getNonrandomEvents = function() {
 		new App.Events.MurderAttemptFollowup(),
 		new App.Events.pRaped(),
 		new App.Events.pAbducted(),
+		new App.Events.pFoodCrisisLowerClass(),
 
 		// secExp
 		new App.Events.secExpSmilingMan0(),
@@ -260,17 +261,8 @@ globalThis.nonRandomEvent = function() {
 			} else {
 				setTimeout(() => Engine.play("Nonrandom Event"), Engine.minDomActionDelay);
 			}
-		} else if (effectiveWeek === 48 && V.experimental.food === 1) {
-			V.foodCrisis = 1;
-			setTimeout(() => Engine.play("P food crisis"), Engine.minDomActionDelay);
-		} else if (effectiveWeek === 50 && V.rations > 0) {
-			V.foodCrisis = 2;
-			setTimeout(() => Engine.play("P food crisis"), Engine.minDomActionDelay);
 		} else if (effectiveWeek === 54 && (V.peacekeepers) && V.peacekeepers.attitude >= 0) {
 			setTimeout(() => Engine.play("P peacekeepers deficit"), Engine.minDomActionDelay);
-		} else if (effectiveWeek === 60 && V.rations > 0) {
-			V.foodCrisis = 3;
-			setTimeout(() => Engine.play("P food crisis"), Engine.minDomActionDelay);
 		} else if (V.SF.Toggle && V.SF.Active === -1 && effectiveWeek >= 72) {
 			setTimeout(() => Engine.play("Security Force Proposal"), Engine.minDomActionDelay);
 		} else if (V.arcologies[0].FSRestart !== "unset" && V.failedElite > 300 && V.eugenicsFullControl !== 1) {
diff --git a/src/events/recFS/recfsIntellectualDependency.js b/src/events/recFS/recfsIntellectualDependency.js
index 6e15206dd8f082e3e80ee9ef4eb7991fa1cf1c89..eb78f70ec19b6b0403f8cc53e307658f691eda65 100644
--- a/src/events/recFS/recfsIntellectualDependency.js
+++ b/src/events/recFS/recfsIntellectualDependency.js
@@ -60,7 +60,7 @@ App.Events.recFSIntellectualDependency = class recFSIntellectualDependency exten
 			const frag = new DocumentFragment();
 			r = [];
 			r.push(`You receive so many messages, as a noted titan of the new Free Cities world, that ${V.assistant.name} has to be quite draconian in culling them. ${HeA} lets only the most important through to you. One category of message that always gets through regardless of content, though, is requests for voluntary enslavement. As the new world takes shape, they've become less rare than they once were.`);
-			App.Events.addParagraph(node, r);
+			App.Events.addParagraph(frag, r);
 			r = [];
 			r.push(`The call comes in from a middle-class area. It appears that the tired looking woman placing the call has a special needs child and can no longer continue to provide the care ${he} requires. Having ${him} disappear discreetly into ${V.arcologies[0].name} would be a convenient way of resolving the situation. Your society's tastes for the mentally slow gives them a plausible way to salve their own consciences on abandoning their child, while, at the same time, giving ${him} a home where ${he} can thrive.`);
 
diff --git a/src/events/timeGatedPlotEvent.js b/src/events/timeGatedPlotEvent.js
index d6ccb46266fc47aff674dce4780ddb72532c6367..e8cc1358f0952e3fe526916d58c4501aa01a844e 100644
--- a/src/events/timeGatedPlotEvent.js
+++ b/src/events/timeGatedPlotEvent.js
@@ -51,7 +51,7 @@ App.Events.TimeGatedPlotEvent = class TimeGatedPlotEvent extends App.Events.Base
 		} else {
 			this.events[71] = new App.Events.TwineEvent().wrapPassage([], "P coup attempt");
 		}
-		this.events[72] = new App.Events.TwineEvent().wrapPassage([], "P coup aftermath");
+		this.events[72] = new App.Events.PCoupAftermath();
 
 		// events with complex prerequisites don't belong here...they're just normal scheduled events and need their own chain controller or result flags
 		for (let week = 0; week < this.events.length; ++week) {
diff --git a/src/facilities/farmyard/food/pFoodCrisis.tw b/src/facilities/farmyard/food/pFoodCrisis.tw
deleted file mode 100644
index 1e34af8d9ea6758b107226b09844e9c63a8186f7..0000000000000000000000000000000000000000
--- a/src/facilities/farmyard/food/pFoodCrisis.tw
+++ /dev/null
@@ -1,125 +0,0 @@
-:: P food crisis [nobr]
-
-/* feel free to move this into a different folder */
-
-<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event">>
-
-<<if ($PC.skill.trading >= 100) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>
-	<<set _price = 2500>>
-<<elseif ($PC.skill.trading >= 50) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>
-	<<set _price = 5000>>
-<<else>>
-	<<set _price = 10000>>
-<</if>>
-
-<<switch $foodCrisis>>
-<<case 1>>
-
-	The region supplying much of the Free City's food had been battling a famine for quite some time now — between the deteriorating weather and the war raging on — but it had always seemed the situation was improving, and your arcology's citizens never really had to worry about going to bed hungry. Unfortunately, that all changed this week. A firefight had broken out near one of the region's largest farms, and one of the main reserves of food was caught in the crossfire.
-
-	<br><br>
-
-	Supplies steadily began to dwindle, and it wasn't long before the prices of food began to rise as a result. <<if $arcologyUpgrade.hydro == 1>>Even the hydroponics system you had installed earlier could barely put a dent in the needs of your citizens.<</if>> Now, the poorest in your arcology are facing starvation. Seeing no other choice, they turned to you to provide them with sustenance. ''This is a unique opportunity.'' It's unlikely your citizens would ask for your help again, should you choose not to help them.
-
-	<br><br>
-
-	<span id="result">
-	<<link "Provide them with ample rations">>
-		<<replace "#result">>
-		You have enough to go around, so you decide to help the desperate citizens. You have a number of rationing stations set up throughout $arcologies[0].name and announce that each citizen is entitled to four full meals a day, more than enough to sate the hunger of even the most famished of men. Your citizens are @@.green;thrilled@@ to hear that their leader is looking out for them.
-		<<run repX(5000, "event")>>
-		<<set cashX(forceNeg(_price*2), "farmyard")>>
-		<<set $rations = 2>>
-		<</replace>>
-	<</link>>
-	<<if ($PC.skill.trading >= 50) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>//This will cost <<print cashFormat(_price*2)>> and some upkeep, @@.springgreen;reduced by your knowledge of trading@@//<<else>>//This will cost <<print cashFormat(_price*2)>> and incur significant upkeep costs//<</if>>
-	<br><<link "Give them enough to survive on">>
-		<<replace "#result">>
-		You have your own problems to deal with, but that doesn't mean you don't look out for your own. You have a number of rationing stations set up throughout $arcologies[0].name and announce that each citizen is entitled to two full meals a day, just enough for your citizens not to starve. Your citizens are @@.green;happy@@ to hear that their leader is looking out for them.
-		<<run repX(2500, "event")>>
-		<<set cashX(forceNeg(_price), "farmyard")>>
-		<<set $rations = 1>>
-		<</replace>>
-	<</link>>
-	<<if ($PC.skill.trading >= 50) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>//This will cost <<print cashFormat(_price)>> and some upkeep, @@.springgreen;reduced by your knowledge of trading@@//<<else>>//This will cost <<print cashFormat(_price)>> and incur significant upkeep costs//<</if>>
-	<br><<link "They can figure their problem out on their own">>
-		<<replace "#result">>
-		You have your own problems to deal with, and you simply can't afford to drop everything and solve theirs at the moment. That you can't take care of your arcology's citizen @@.red;reflects poorly on you.@@
-		<<run repX(-500, "event")>>
-		<</replace>>
-	<</link>>
-	</span>
-
-<<case 2>>
-
-	It's been a few weeks since your citizens had approached you asking for aid, and since then, the situation hasn't improved. In fact, it had gotten worse, and food prices have reached a record high. The tension in $arcologies[0].name is palpable, and small riots have broken out more than once over disputes about food. You are not surprised, then, when you receive a visit from some of the "middle class" /* TODO: still not really happy with this */ citizens. They state that they noticed that you have been giving out rations to the poorer citizens, and, now that the situation has become dire, were wondering if you would be willing to do the same for them.
-
-	<br><br>
-
-	<span id="result">
-	<<link "Give them generous rations as well">>
-		<<replace "#result">>
-		You still have more than enough to go around, so you inform the leaders that you have decided you will give them large rations, enough to feed even the hungriest citizen. The leaders are @@.green;very pleased@@ to hear that you are taking care of them as well.
-		<<run repX(5000, "event")>>
-		<<set cashX(forceNeg(_price*2), "farmyard")>>
-		<<set $rations = 4>>
-		<</replace>>
-	<</link>>
-	<<if ($PC.skill.trading >= 50) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>//This will cost <<print cashFormat(_price*2)>> and some upkeep, @@.springgreen;reduced by your knowledge of trading@@//<<else>>//This will cost <<print cashFormat(_price*2)>> and incur significant upkeep costs//<</if>>
-	<br><<link "Provide them with enough sustenance to survive on too">>
-		<<replace "#result">>
-		As much as you'd like to provide them with all of the food in the world, it simply is not feasible in your current situation. Therefore, you announce to the leaders that you will provide them only enough rations to live off of. The leaders understand, and are @@.green;pleased@@ to hear that you would provide for them at all.
-		<<run repX(2500, "event")>>
-		<<set cashX(forceNeg(_price), "farmyard")>>
-		<<set $rations = 3>>
-		<</replace>>
-	<</link>>
-	<<if ($PC.skill.trading >= 50) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>//This will cost <<print cashFormat(_price)>> and some upkeep, @@.springgreen;reduced by your knowledge of trading@@//<<else>>//This will cost <<print cashFormat(_price)>> and incur significant upkeep costs//<</if>>
-	<br><<link "Change your mind about giving out any rations at all">>
-		<<replace "#result">>
-		Having given the people rations at all was a mistake, you think to yourself. You have a great number of your own problems to deal with, and providing rations to everyone that can't afford food is putting an unnecessary strain on your own situation. With this is mind, you tell the leaders that you simply can't help them at this time, and have decided that you can't help anyone with food at all. The citizens are understandably @@.red;angry@@ that you would go back on your word.
-		<<run repX(-1000, "event")>>
-		<<set $rations = 0>>
-		<</replace>>
-	<</link>>
-	</span>
-
-<<case 3>>
-
-	Another few weeks has passed since your last meeting with your citizens regarding rationing, and things have only deteriorated further since then. It was only a matter of time, then, before the wealthier citizens of $arcologies[0].name paid you a visit one afternoon. While being able to afford food wasn't exactly difficult for them as of yet, they could read the writing on the wall, and knew it would only be a matter of time before the prices of food were so high that even they would be forced to beg for handouts.
-
-	<br><br>
-
-	Seeing the progress you had made since taking control of the arcology, they decided their best course of action was to come to you with a proposition. They would allow you to take full control of the food supply in $arcologies[0].name, and in return you would keep them well-fed. ''This is a unique opportunity.'' If you turn their offer down, the citizens of your arcology will find another way of surviving.
-
-	<span id="result">
-	<br>
-	<br><<link "Set up a food market">>
-		<<replace "#result">>
-		You know that a proposition like this wouldn't have been easy for your citizens to make, and you also know that there is no one better suited to a task like this than you. You announce that you will be setting up a market to buy, sell, and store food in, and that you'll make sure that the citizens will continue to be well-fed. Your citizens are @@.green;glad@@ to hear that you are looking out for their best interests.
-		<<run repX(5000, "event")>>
-		<<set cashX(forceNeg(_price*5), "farmyard")>>
-		<<set $foodMarket = 1>>
-		<<unset $rations>>
-		<</replace>>
-	<</link>>
-	<<if ($PC.skill.trading >= 50) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>//This will cost an initial investment of <<print cashFormat(_price*5)>>, @@.springgreen;reduced by your knowledge of trading@@//<<else>>//This will cost an initial investment of <<print cashFormat(_price*5)>>//<</if>>
-	<br><<link "Politely decline their offer, but continue giving them rations">>
-		<<replace "#result">>
-		Things have been going fairly well for you, but not //that// well — setting up an entirely new place to buy, sell, and store food would no doubt be an expensive undertaking. You tell the citizens that while you can't spare the resources to create a new market at the moment, you will honor your past agreement and continue giving them free rations. The people initially seem a bit disappointed that you don't seem to want to expand $arcologies[0].name, but are ultimately @@.green;glad@@ to hear that you'll continue taking care of them.
-		<<run repX(2500, "event")>>
-		<<set cashX(forceNeg(_price), "farmyard")>>
-		<<set $rations = 5>>
-		<</replace>>
-	<</link>>
-	<<if ($PC.skill.trading >= 50) || ($PC.career == "capitalist" || $PC.career == "entrepreneur" || $PC.career == "business kid")>>//This will cost <<print cashFormat(_price)>> and some upkeep, @@.springgreen;reduced by your knowledge of trading@@//<<else>>//This will cost <<print cashFormat(_price)>> and incur significant upkeep costs//<</if>>
-	<br><<link "Turn down their offer and end rationing completely">>
-		<<replace "#result">>
-		While a new place to buy, sell, and store food in $arcologies[0].name would most likely come in quite handy in the future, you ultimately decide that you simply cannot spare the resources required. In fact, giving rations at all was a costly venture, and after not having seen any sort of return-on-investment, you decide that you are unable to continue giving out rations anymore. Your citizens are @@.red;angry@@ at the fact that you seem not to care about them at all, but that's their problem.
-		<<run repX(-1000, "event")>>
-		<<unset $rations>>
-		<</replace>>
-	<</link>>
-	</span>
-
-<</switch>>
\ No newline at end of file
diff --git a/src/facilities/penthouse/penthousePassage.js b/src/facilities/penthouse/penthousePassage.js
index ac96c78561fb2e767ff894647ba96046446ee3d3..281b29509d94abda5dc41ed114ec6af248703284 100644
--- a/src/facilities/penthouse/penthousePassage.js
+++ b/src/facilities/penthouse/penthousePassage.js
@@ -510,33 +510,34 @@ App.UI.managePenthouse = function() {
 		App.UI.DOM.appendNewElement(
 			"div",
 			el,
-			(V.rep >= rep) ?
-				App.UI.DOM.passageLink("Visit the market", "The Black Market") :
-				`You lack the ${num(rep)} reputation to be invited to the underground Black Market.`
+			(V.rep >= rep)
+				? App.UI.DOM.passageLink("Visit the market", "The Black Market")
+				: `You lack the ${num(rep)} reputation to be invited to the underground Black Market.`
 		);
 		return el;
 	}
 
 	/**
+	 * Creates a new link to purchase a facility.
 	 *
 	 * @param {string} title
-	 * @param {function(void):void} func
-	 * @param {number} [cost=5000]
+	 * @param {function(void):void} handler
+	 * @param {number} [cost]
 	 * @returns {DocumentFragment}
 	 */
-	function makeLink(title, func, cost = 5000) {
+	function makeLink(title, handler, cost = 5000) {
 		const el = new DocumentFragment();
 		cost = Math.trunc(cost * V.upgradeMultiplierArcology);
 		el.append(App.UI.DOM.link(
 			title,
 			() => {
-				func();
+				handler();
+
 				cashX(forceNeg(cost), "capEx");
 				V.PC.skill.engineering += .1;
 				jQuery(container).empty().append(createPage());
-			},
+			}, [], '', `Costs ${cashFormat(cost)}.`
 		));
-		App.UI.DOM.appendNewElement("span", el, ` Costs ${cashFormat(cost)}`, "detail");
 		return el;
 	}
 };
diff --git a/src/gui/storyCaption.js b/src/gui/storyCaption.js
index 0b39cf7d009f107f336726dfef7a1b409b05d02f..34a34abf4505bee3f03bb10e7c728a2f6a04ece7 100644
--- a/src/gui/storyCaption.js
+++ b/src/gui/storyCaption.js
@@ -410,7 +410,7 @@ App.UI.storyCaption = function() {
 	}
 
 	function crime() {
-		V.SecExp.core.crimeLow = Math.clamp(Math.trunc(crime), 0, 100);
+		V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow, 0, 100);
 		const div = document.createElement("div");
 		App.UI.DOM.appendNewElement("span", div, "Crime", "orangered");
 		div.append(" | ");
@@ -418,6 +418,7 @@ App.UI.storyCaption = function() {
 
 		if (showCheats()) {
 			div.append(App.UI.DOM.makeTextBox(V.SecExp.core.crimeLow, crime => {
+				V.SecExp.core.crimeLow = Math.clamp(Math.trunc(crime), 0, 100);
 				V.cheater = 1;
 				App.Utils.scheduleSidebarRefresh();
 			}, true));
diff --git a/src/uncategorized/randomNonindividualEvent.tw b/src/uncategorized/randomNonindividualEvent.tw
index eb531a13b0fd99b5d9105625045132a796f54399..c932445f6a6ec1ecfa8076e475ddb7662175d9d7 100644
--- a/src/uncategorized/randomNonindividualEvent.tw
+++ b/src/uncategorized/randomNonindividualEvent.tw
@@ -10,9 +10,9 @@
 
 		''Any one of your slaves would have been selected for a random non-individual event:''
 		<br>
-		<<for $i = 0; $i < $slaves.length; $i++>>
-			<<set _slaveName = SlaveFullName($slaves[$i])>>
-			<br><<print "[[_slaveName|Random Nonindividual Event][$eventSlave = $slaves[" + $i + "]]]">>
+		<<for _slave range $slaves>>
+			<<set _slaveName = SlaveFullName(_slave)>>
+			<br><<print "[[_slaveName|Random Nonindividual Event][$eventSlave = _slave]]">>
 		<</for>>
 		<br><br>[[Switch to RIE Eligibility Check|RIE Eligibility Check][$activeSlave = 0, $eventSlave = 0]]
 	<<else>>