diff --git a/devTools/javaSanityCheck/ignoredVariables b/devTools/javaSanityCheck/ignoredVariables
index cf7011ee74099424c855ed37f7316ec044e7281b..1b839f16bb14a9c20a0deb915d08653c79756e1b 100644
--- a/devTools/javaSanityCheck/ignoredVariables
+++ b/devTools/javaSanityCheck/ignoredVariables
@@ -84,6 +84,8 @@ saRules
 plural
 orig
 bimboMaleNames
+RuleHasError
+DefaultRulesError
 # PC
 vision
 criticalDamage
diff --git a/src/004-base/proxies.js b/src/004-base/proxies.js
index 9ce94c7366f622e34bf28802f616152f3dc35320..03fc68bf390c917ca8c95735fa47a3463e24287a 100644
--- a/src/004-base/proxies.js
+++ b/src/004-base/proxies.js
@@ -1,55 +1,122 @@
-window.createReadonlyProxy = function(target) {
-	if (target.__isReadonlyProxy) { return target; }
-	return new Proxy(target, {
-		get: function(o, prop) {
-			if (prop == '__isReadonlyProxy') { return true; }
-			return createReadonlyProxy(o[prop]);
-		},
-		set: function(o, prop, value) {
-			return false;
-		},
-		deleteProperty: function(o, prop) {
-			return false;
+(function() {
+	const readOnlySymbol = Symbol("readonly proxy");
+	window.createReadonlyProxy = function(target) {
+		if (target == null) return target; //intentionally ==
+		if (target[readOnlySymbol]) { return target; }
+		if (_.isArray(target)) {
+			return new Proxy(target, {
+				get:function(o, prop) {
+					if(prop === readOnlySymbol) { return true; }
+					const val = o[prop];
+					if (typeof val === 'function') {
+						if (['push', 'unshift', 'pop'].includes(prop)) {
+							return function () {
+								throw Error("Cannot modify a readonly array");
+							}
+						}
+						return val.bind(target);
+					}
+					return createReadonlyProxy(val);
+				},
+				set:function(o, prop, value) {
+					return true;
+				},
+				deleteProperty:function(o, prop) {
+					return true;
+				}
+			});
 		}
-	});
-};
-window.createCheatProxy = function(target) {
-	if (target.__isCheatProxy) { return target; }
-	return new Proxy(target, {
-		get: function(o, prop) {
-			if (prop == '__isCheatProxy') { return true; }
-			return createCheatProxy(o[prop]);
-		},
-		set: function(o, prop, value) {
-			o[prop] = value;
-			State.variables.cheater = 1;
-			return true;
-		},
-		deleteProperty: function(o, prop) {
-			delete o[prop];
-			State.variables.cheater = 1;
-			return false;
+		if (_.isObject(target)) {
+			return new Proxy(target, {
+				get:function(o, prop) {
+					if(prop === readOnlySymbol) { return true; }
+					return createReadonlyProxy(o[prop]);
+				},
+				set:function(o, prop, value) {
+					return true;
+				},
+				deleteProperty:function(o, prop) {
+					return true;
+				}
+			});
 		}
-	});
-};
+		return target;
+	};
+	const cheaterSymbol = Symbol("cheating proxy");
+	window.createCheatProxy = function(target) {
+		if (target == null) return target; //intentionally ==
+		if (target[cheaterSymbol]) { return target; }
+		if (_.isArray(target)) {
+			return new Proxy(target, {
+				get:function(o, prop) {
+					if(prop === cheaterSymbol) { return true; }
+					const val = o[prop];
+					if (typeof val === 'function') {
+						if (['push', 'unshift', 'pop'].includes(prop)) {
+							return function (el) {
+								const retval = Array.prototype[prop].apply(o, arguments);
+								//Make sure we set cheater after calling the function
+								State.variables.cheater = 1;//Can't use `V` because it probably points to a proxy.
+								return retval;
+							}
+						}
+						return val.bind(target);
+					}
+					return createCheatProxy(val);
+				},
+				set:function(o, prop, value) {
+					o[prop] = value;
+					State.variables.cheater = 1;//Can't use `V` because it probably points to a proxy.
+					return true;
+				},
+				deleteProperty:function(o, prop) {
+					delete o[prop];
+					State.variables.cheater = 1;//Can't use `V` because it probably points to a proxy.
+					return true;
+				}
+			});
+		}
+		if (_.isObject(target)) {
+			return new Proxy(target, {
+				get:function(o, prop) {
+					if(prop === cheaterSymbol) { return true; }
+					return createCheatProxy(o[prop]);
+				},
+				set:function(o, prop, value) {
+					o[prop] = value;
+					State.variables.cheater = 1;
+					return true;
+				},
+				deleteProperty:function(o, prop) {
+					delete o[prop];
+					State.variables.cheater = 1;
+					return true;
+				}
+			});
+		}
+		return target;
+	};
+})();
 Object.defineProperty(window, "V", {
 	get: function() {
 		if (window.storyProxy != null) { return window.storyProxy; }
 		return State.variables;
 	}
 });
+//This should be used if the user might use V under normal, non-cheating circumstances but shouldn't be punished for accidentally setting the value. The attempt to make the change will simply be disregarded.
 window.runWithReadonlyProxy = function(callback) {
 	window.storyProxy = createReadonlyProxy(State.variables);
 	try {
-		callback();
+		return callback();
 	} finally {
 		window.storyProxy = null;
 	}
 };
+// This should be used if setting values would constitute cheating. For example, a debug view that shows all variables in an editable form; showing isn't cheating, but making a change would be.
 window.runWithCheatProxy = function(callback) {
 	window.storyProxy = createCheatProxy(State.variables);
 	try {
-		callback();
+		return callback();
 	} finally {
 		window.storyProxy = null;
 	}
diff --git a/src/SecExp/js/secExp.js b/src/SecExp/js/secExp.js
index ba09c63b768a7855443382aab7da976ce1184ed2..e656e4f042c08cdedfcdabe9ce7ded14e7f1fa46 100644
--- a/src/SecExp/js/secExp.js
+++ b/src/SecExp/js/secExp.js
@@ -456,11 +456,6 @@ App.SecExp.Check = (function() {
 				delete V.difficulty;
 			}
 
-			if (V.PCWounded === 1 && V.PCWoundCooldown > 0) {
-				V.SecExp.pcWounded = V.PCWoundCooldown;
-				delete V.PCWoundCooldown;
-			}
-
 			V.SecExp.settings.battle = V.SecExp.settings.battle || {};
 			V.SecExp.settings.battle.enabled = V.SecExp.settings.battle.enabled || 1;
 			if (jsDef(V.battlesEnabled)) {
diff --git a/src/gui/css/mainStyleSheet.css b/src/gui/css/mainStyleSheet.css
index 269a6c106604d81e519f9a3aedfeb5fdac7922e2..0855e9cf5e27d57a28b441d279a7f0d1e0ae6d3c 100644
--- a/src/gui/css/mainStyleSheet.css
+++ b/src/gui/css/mainStyleSheet.css
@@ -284,11 +284,19 @@ white-space: normal;
 	color: #68D;
 	margin-right: 1em;
 }
+.rajs-listitem.selected {
+	color: gray;
+	text-decoration: none;
+}
 .rajs-listitem:last-of-type { margin-right: 0; }
 .rajs-listitem:hover {
 	cursor: pointer;
 	text-decoration: underline;
 }
+.rajs-listitem.selected:hover {
+	cursor: default;
+	text-decoration: none;
+}
 .rajs-list strong:first-of-type, .rajs-list input {
 	margin-right: 2em;
 }
diff --git a/src/init/storyInit.tw b/src/init/storyInit.tw
index 9d372873dea58f2389c0d6de5a61814743df1ef5..dd729bd8ab4313a0b4a310bf0197f18099c1ae03 100644
--- a/src/init/storyInit.tw
+++ b/src/init/storyInit.tw
@@ -1492,7 +1492,7 @@ You should have received a copy of the GNU General Public License along with thi
 
 /* Security Expansion */
 <<set $wasToggledBefore = 0>>
-<<set $PCWounded = 0>>
+<<set $PC.majorInjury = 0>>
 /* moved first build to post toggle */
 <<set $secExpEnabled = $secExpEnabled || 0>>
 
diff --git a/src/interaction/main/mainLinks.js b/src/interaction/main/mainLinks.js
index ba03d63c83c30c13e7a52778f37fe8cdfc0c46eb..c375f7ab6605d3831d8c0decea516e59361e127e 100644
--- a/src/interaction/main/mainLinks.js
+++ b/src/interaction/main/mainLinks.js
@@ -4,7 +4,7 @@ App.UI.View.MainLinks = function() {
 	const PA = Array.isArray(V.personalAttention) ? V.personalAttention.map(x => getSlave(x.ID)) : [];
 	let r = '';
 
-	if (V.PCWounded === 1) {
+	if (V.PC.majorInjury === 1) {
 		r += `The injuries received in the recent battle prevent you from undertaking tiring efforts.`;
 	} else {
 		switch (V.personalAttention) {
@@ -75,7 +75,7 @@ App.UI.View.MainLinks = function() {
 		}
 	}
 
-	if (V.PCWounded !== 1) {
+	if (V.PC.majorInjury !== 1) {
 		r += ` <span id="managePA"><strong><<link "Change plans">><<goto "Personal Attention Select">><</link>></strong></span> <span class="cyan">[A]</span>`;
 	}
 
diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js
index ad0ec052a1263b54b0acff0a2969e7f30c922c34..cd5fd6efe7a120ac3f2aa55da62c1579d685e8b8 100644
--- a/src/js/DefaultRules.js
+++ b/src/js/DefaultRules.js
@@ -16,7 +16,8 @@ window.DefaultRules = (function() {
 		if (slave.useRulesAssistant === 0) { return r; } // exempted
 		r = "";
 		({he, him, his} = getPronouns(slave));
-		let rule = MergeRules(slave);
+		let slaveReadOnly = createReadonlyProxy(slave);
+		let rule = runWithReadonlyProxy(()=>MergeRules(slaveReadOnly));
 		if (Object.keys(rule).length === 0) { return r; } // no rules apply
 
 		AssignJobToSlave(slave, rule);
@@ -2936,5 +2937,20 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	const rxCheckEqual = /[^!=<>]=[^=<>]/gi;
+	const compileCheck = function(code) {
+		try {
+			//TODO: This should use a cached Function, which should be the same as below.
+			new Function(`return ${code}`);
+		}
+		catch(e) {
+			return false;
+		}
+		return true;
+	}
+	window.RuleHasError = (rule) => rule.condition.function === "custom"
+	                             &&(rule.condition.data.match(rxCheckEqual)
+	                             || !compileCheck(rule.condition.data));
+	window.DefaultRulesError = () => V.defaultRules.some(r => RuleHasError(r));
 	return DefaultRules;
 })();
diff --git a/src/js/economyJS.js b/src/js/economyJS.js
index 4a707dceb4b9ce00938651141c3ff4c369ab7799..f4200b264b1d9ff5f631829d13cd62a1b007b992 100644
--- a/src/js/economyJS.js
+++ b/src/js/economyJS.js
@@ -943,12 +943,12 @@ window.NPCSexSupply = function(lowerDemandLeft, lowerTotalDemand, middleDemandLe
 
 	// Top class calculations
 	const topClassNPCRatio = NPCSexSupply.topClass / topDemandLeft;
-	const topClassOptimalRatio = 0.5 + V.sexSubsidies.topClass / 10 - V.sexSupplyBarriers.topClass / 10;
+	const topClassOptimalRatio = 0.5 + V.sexSubsidies.topClass / 8 - V.sexSupplyBarriers.topClass / 10;
 	const topClassOptimal = topDemandLeft * topClassOptimalRatio;
 	if (NPCSexSupply.topClass > topTotalDemand * (0.3 - V.sexSupplyBarriers.topClass / 20)) {
-		if (topClassNPCRatio >= topClassOptimalRatio + 0.05) {
+		if (topClassNPCRatio >= topClassOptimalRatio + 0.025) {
 			NPCSexSupply.topClass -= Math.min(NPCSexSupply.topClass - Math.trunc((NPCSexSupply.topClass * 4 + topClassOptimal) / 5), Math.trunc(NPCSexSupply.topClass * 0.1));
-		} else if (topClassNPCRatio <= topClassOptimalRatio - 0.05) {
+		} else if (topClassNPCRatio <= topClassOptimalRatio - 0.025) {
 			NPCSexSupply.topClass += Math.trunc(Math.clamp((NPCSexSupply.topClass * 4 + topClassOptimal) / 5 - NPCSexSupply.topClass, 500, NPCSexSupply.topClass * 0.1) * (1 - V.sexSupplyBarriers.topClass / 5));
 		} else {
 			NPCSexSupply.topClass = Math.trunc(NPCSexSupply.topClass * (1 + normalRandInt(0, 20) / 1000));
@@ -1166,6 +1166,9 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 				}
 			}
 		}
+
+		// The Madam adding to 'brothel'
+		SJVBrothel(V.slaves[V.slaveIndices[V.Madam.ID]]);
 	}
 
 
@@ -1550,14 +1553,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 		}
 
 		// The amount of sexual acts
-		s.sexAmount = Beauty(s);
-
-		if (s.assignment === "be the Madam") {
-			if ((BL + toTheBrothelTotal > 0) && (CL + toTheBrothelTotal < 10)) {
-				s.sexAmount *= ((10 - CL - toTheBrothelTotal) / 10) * 1.5;
-			}
-		}
-		s.sexAmount = Math.trunc(s.sexAmount * beautyMultiplier * (1 + (0.002 * s.skill.whoring)));
+		s.sexAmount = Math.trunc(Beauty(s) * beautyMultiplier * (1 + (0.002 * s.skill.whoring)));
 
 		// The quality/value of each sexual act
 		s.sexQuality = FResult(s);
@@ -1599,14 +1595,14 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 			// Automatically changing effectiveWhoreClass
 			// what is the initial effective whore class? Are we providing more sex than overal demand? Is the ratio of supply/demand for this tier higher than the one below it?
 			// This also takes into consideration public sluts and ignores the NPC market and arcades
-			const topSDRatio = slaveJobValues.brothel.topClass / topClassSexDemandRef;
-			const upperSDRatio = slaveJobValues.brothel.upperClass / upperClassSexDemandRef;
+			const topSDRatio = slaveJobValues.brothel.topClass / (topClassSexDemandRef - V.NPCSexSupply.topClass);
+			const upperSDRatio = slaveJobValues.brothel.upperClass / (upperClassSexDemandRef - V.NPCSexSupply.upperClass);
 			const middleClubSupply = slaveJobValues.club * slaveJobValues.clubSP * (middleClassSexDemandRef / (lowerClassSexDemandRef + middleClassSexDemandRef));
 			const middleSupply = slaveJobValues.brothel.middleClass + middleClubSupply;
-			const middleSDRatio = middleSupply / middleClassSexDemandRef;
+			const middleSDRatio = middleSupply / (middleClassSexDemandRef - V.NPCSexSupply.middleClass);
 			const lowerClubSupply = slaveJobValues.club * slaveJobValues.clubSP * (lowerClassSexDemandRef / (lowerClassSexDemandRef + middleClassSexDemandRef));
 			const lowerSupply = slaveJobValues.brothel.lowerClass + lowerClubSupply;
-			const lowerSDRatio = lowerSupply / lowerClassSexDemandRef;
+			const lowerSDRatio = lowerSupply / (lowerClassSexDemandRef - V.NPCSexSupply.lowerClass);
 			if (s.effectiveWhoreClass === 4 && topSDRatio > 1 && topSDRatio > upperSDRatio) {
 				s.effectiveWhoreClass -= 1;
 			}
@@ -1619,20 +1615,20 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 
 			// Calculate the stats
 			if (s.effectiveWhoreClass === 4) {
-				s.sexAmount = normalRandInt(50, 4); // Bringing sex amount into the desired range
-				s.sexQuality = Math.trunc(Math.min((income * 1.2) / s.sexAmount, V.whoreBudget.topClass * 0.2)); // Adjusting the price to the correct sex amount with 20% bonus for being of the highest tier
+				s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (1/3)), normalRandInt(30, 2), normalRandInt(60, 3)); // Bringing sex amount into the desired range. Beauty improves use amount between values of aprox. 90 and 180.
+				s.sexQuality = Math.min(Math.trunc(Math.min((income * 1.2) / s.sexAmount, V.whoreBudget.topClass * 0.2)), Math.trunc(V.whoreBudget.topClass * (1/3))); // Adjusting the price to the correct sex amount with 20% bonus for being of the highest tier. The top class will pay a maximum of 33% of their weekly budget per service.
 				slaveJobValues.brothel.topClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.topClass * 0.2)); // Registering the job value in the right slot
 			} else if (s.effectiveWhoreClass === 3) {
-				s.sexAmount = normalRandInt(60, 5);
-				s.sexQuality = Math.min(Math.trunc((income * 1.05) / s.sexAmount), V.whoreBudget.upperClass * 0.5); // The upper class will pay a maximum of 60% of their weekly budget per service
+				s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (2/3)), normalRandInt(40, 3), normalRandInt(80, 3)); // Beauty improves use amount between values of aprox. 60 and 120.
+				s.sexQuality = Math.min(Math.trunc((income * 1.05) / s.sexAmount), V.whoreBudget.upperClass * 0.5); // The upper class will pay a maximum of 50% of their weekly budget per service
 				slaveJobValues.brothel.upperClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.upperClass * 0.6));
 			} else if (s.effectiveWhoreClass === 2) {
-				s.sexAmount = normalRandInt(70, 6);
+				s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * 1.25), normalRandInt(50, 3), normalRandInt(120, 3)); // Beauty improves use amount between values of aprox. 40 and 96.
 				s.sexQuality = Math.min(Math.trunc((income * 0.9) / s.sexAmount), V.whoreBudget.middleClass); // The middle class will pay a maximum of 125% of their weekly budget per service
 				slaveJobValues.brothel.middleClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.middleClass * 1.25));
 			} else {
-				s.sexAmount = normalRandInt(80, 7);
-				s.sexQuality = Math.clamp((income * 0.75) / s.sexAmount, 2, V.whoreBudget.lowerClass * 2); // The lower class will pay a maximum of 300% of their weekly budget per service and a minimum of 2
+				s.sexAmount = Math.clamp(s.sexAmount * 2, normalRandInt(60, 3), normalRandInt(150, 3)); // Beauty improves use amount between values of approx. 30 and 75.
+				s.sexQuality = Math.clamp((income * 0.75) / s.sexAmount, 2, V.whoreBudget.lowerClass * 3); // The lower class will pay a maximum of 300% of their weekly budget per service and a minimum of 2
 				slaveJobValues.brothel.lowerClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.lowerClass * 3));
 			}
 		}
@@ -1641,6 +1637,13 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 			s.whoreClass = 0;
 		}
 		whoreScore(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef);
+
+		if (s.assignment === "be the Madam") {
+			if ((BL + toTheBrothelTotal > 0) && (BL + toTheBrothelTotal < 10)) {
+				s.sexAmount = Math.trunc(s.sexAmount * ((10 - BL - toTheBrothelTotal) / 10));
+				s.sexQuality = Math.trunc(s.sexQuality * 1.2);
+			}
+		}
 	}
 
 	return slaveJobValues;
diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js
index a10b2367642d63a911edf29acb5fc964fa9ce593..4f4a1da41b2dd0cf2a7389476262dfa3873cdcb0 100644
--- a/src/js/rulesAssistant.js
+++ b/src/js/rulesAssistant.js
@@ -209,6 +209,7 @@ window.ruleAppliesP = function ruleAppliesP(cond, slave) {
 			flag = cond.data.value.includes(slave[cond.data.attribute]);
 			break;
 		case "custom": // user provided JS function
+			//TODO: This should use a cached Function instead of 'eval'ing 
 			flag = eval(cond.data)(slave);
 			break;
 	}
diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js
index 6c726bb3d8a7b5f4182ee28ac9ad003174ff43e8..3d839b8b7befee682b5af6350fc4247fc26d7033 100644
--- a/src/js/rulesAssistantOptions.js
+++ b/src/js/rulesAssistantOptions.js
@@ -10,7 +10,7 @@ window.rulesAssistantOptions = (function() {
 	const noDefaultSetting = {value: "!NDS!", text: "no default setting"};
 
 	/** @type {App.RA.Rule} */
-	let current_rule;
+	let current_rule, root;
 
 	function rulesAssistantOptions(element) {
 		V.nextButton = "Back to Main";
@@ -26,19 +26,19 @@ window.rulesAssistantOptions = (function() {
 				current_rule = V.defaultRules[idx];
 			}
 		}
-		const root = new Root(element);
+		root = new Root(element);
 	}
 
 	function returnP(e) { return e.keyCode === 13; }
 
-	function newRule(root) {
+	function newRule() {
 		const rule = emptyDefaultRule();
 		V.defaultRules.push(rule);
 		V.currentRule = rule.ID;
-		reload(root);
+		reload();
 	}
 
-	function removeRule(root) {
+	function removeRule() {
 		const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID);
 		V.defaultRules.splice(idx, 1);
 		if (V.defaultRules.length > 0) {
@@ -47,33 +47,33 @@ window.rulesAssistantOptions = (function() {
 		} else {
 			V.currentRule = null;
 		}
-		reload(root);
+		reload();
 	}
 
-	function lowerPriority(root) {
+	function lowerPriority() {
 		if (V.defaultRules.length === 1) { return; } // nothing to swap with
 		const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID);
 		if (idx === 0) { return; } // no lower rule
 		arraySwap(V.defaultRules, idx, idx - 1);
-		reload(root);
+		reload();
 	}
 
-	function higherPriority(root) {
+	function higherPriority() {
 		if (V.defaultRules.length === 1) { return; } // nothing to swap with
 		const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID);
 		if (idx === V.defaultRules.length - 1) { return; } // no higher rule
 		arraySwap(V.defaultRules, idx, idx + 1);
-		reload(root);
+		reload();
 	}
 
-	function changeName(name, root) {
+	function changeName(name) {
 		if (name === current_rule.name) { return; }
 		current_rule.name = name;
-		reload(root);
+		reload();
 	}
 
 	// reload the passage
-	function reload(root) {
+	function reload() {
 		const elem = root.element;
 		elem.innerHTML = "";
 		rulesAssistantOptions(elem);
@@ -243,7 +243,7 @@ window.rulesAssistantOptions = (function() {
 		}
 	}
 
-
+	let _blockCallback=Symbol("Block Callback");
 	// list of clickable elements
 	// has a short explanation (the prefix) and a value display
 	// value display can optionally be an editable text input field
@@ -260,6 +260,7 @@ window.rulesAssistantOptions = (function() {
 		 */
 		constructor(prefix, data = [], allowNullValue = true, editor = false, capitalizeShortcuts = false, ...args) {
 			super(prefix, editor, ...args);
+			this[_blockCallback] = false;
 			this.selectedItem = null;
 			/** @protected */
 			this._allowNullValue = allowNullValue;
@@ -288,17 +289,42 @@ window.rulesAssistantOptions = (function() {
 
 		inputEdited() {
 			if (this.selectedItem) { this.selectedItem.deselect(); }
+			this.setValue(this.getTextData());
 			this.propagateChange();
 		}
 
 		selectItem(item) {
 			if (this.selectedItem) { this.selectedItem.deselect(); }
-			this.selectedItem = item;
 			this.setValue(item.data);
 			this.propagateChange();
 		}
-
+		trySetValue(what) {
+			if(what == null && this._allowNullValue) {
+				this.setValue(what);
+				return;
+			}
+			const selected = this.children.filter(listItem => _.isEqual(listItem.data, what));
+			if(selected != null && selected.length == 1)
+			{
+				this.selectItem(selected[0]);
+			}
+			else if(this._allowNullValue) {
+				this.setValue(null);
+			}
+		}
 		setValue(what) {
+			if(what == null && !this._allowNullValue) { what = ""; }
+			this.realValue = what;
+			if(this[_blockCallback]) return;
+			try {
+				this[_blockCallback] = true;
+				this.setTextValue(what);
+				this.updateSelected();
+			} finally {
+				this[_blockCallback] = false;
+			}
+		}
+		setTextValue(what) {
 			const str = what === null ? "no default setting" : `${what}`;
 			if (this.value) {
 				if (this.value.tagName === "INPUT") {
@@ -310,6 +336,9 @@ window.rulesAssistantOptions = (function() {
 		}
 
 		getData() {
+			return this.realValue;
+		}
+		getTextData() {
 			return (this.value.tagName === "INPUT" ? this.parse(this.value.value) : this.selectedItem.data);
 		}
 
@@ -321,6 +350,26 @@ window.rulesAssistantOptions = (function() {
 				this.onchange(this.getData());
 			}
 		}
+		updateSelected() {
+			const dataValue = this.getData();
+			let selected;
+			if(dataValue == null) {
+				selected = this.children.filter(listItem => listItem.data == null);
+			}
+			else {
+				selected = this.children.filter(listItem => _.isEqual(listItem.data, dataValue));
+			}
+			if (selected.length > 1) throw Error(`Multiple shortcuts matched ${JSON.stringify(dataValue)}`);
+			if (selected.length == 1) {
+				const listItem = selected[0];
+				listItem.select(false);
+				if(this.selectedItem != null
+				&& !_.isEqual(this.selectedItem, listItem)) {
+					this.selectedItem.deselect();
+				}
+				this.selectedItem = listItem;
+			}
+		}
 
 		/**
 		 * @private
@@ -360,11 +409,11 @@ window.rulesAssistantOptions = (function() {
 			return elem;
 		}
 
-		select() {
+		select(notify = true) {
 			if (this.selected) { return false; }
-			this.parent.selectItem(this);
-			this.element.classList.add("selected");
 			this.selected = true;
+			this.element.classList.add("selected");
+			if(notify) { this.parent.selectItem(this); }
 			return true;
 		}
 
@@ -524,16 +573,16 @@ window.rulesAssistantOptions = (function() {
 			return res;
 		}
 
-		getData() {
+		getTextData() {
 			return this.selectedValue;
 		}
 
-		setValue(what) {
+		setTextValue(what) {
 			this.selectedValue = what;
 			if (this.values.has(what)) {
-				super.setValue(this.values.get(what));
+				super.setTextValue(this.values.get(what));
 			} else {
-				super.setValue(what);
+				super.setTextValue(what);
 			}
 		}
 	}
@@ -546,7 +595,7 @@ window.rulesAssistantOptions = (function() {
 		createEditor() {
 			let res = document.createElement("input");
 			res.setAttribute("type", "text");
-			res.classList.add("rajs-value"); //
+			res.classList.add("rajs-value");
 			// call the variable binding when the input field is no longer being edited, and when the enter key is pressed
 			res.onblur = () => {
 				this.inputEdited();
@@ -554,14 +603,21 @@ window.rulesAssistantOptions = (function() {
 			res.onkeypress = (e) => {
 				if (returnP(e)) { this.inputEdited(); }
 			};
+			$(res).click(()=>res.setAttribute("placeholder", ""));
 			return res;
 		}
+		setValue(what) {
+			super.setValue(what);
+			this.value.setAttribute("placeholder", what == null
+			                                     ? `(${capFirstChar(noDefaultSetting.text)})`
+			                                     : '');
+		}
 
-		getData() {
+		getTextData() {
 			return this.value.value;
 		}
 
-		setValue(what) {
+		setTextValue(what) {
 			this.value.value = what;
 		}
 	}
@@ -677,7 +733,7 @@ window.rulesAssistantOptions = (function() {
 			return what === "" ? null : parseInt(what);
 		}
 
-		setValue(what) {
+		setTextValue(what) {
 			if (typeof what === 'number') { // comes from a pre-set
 				this.numEditor.value = what.toString();
 			} else if (what === null) {
@@ -689,7 +745,7 @@ window.rulesAssistantOptions = (function() {
 			}
 		}
 
-		getData() {
+		getTextData() {
 			const v = this.parse(this.numEditor.value);
 			return v === null ? null : App.RA.makeTarget(this.opSelector.value, v);
 		}
@@ -757,7 +813,7 @@ window.rulesAssistantOptions = (function() {
 			return res;
 		}
 
-		getData() {
+		getTextData() {
 			function parse(what) {
 				return what === "" ? null : parseInt(what);
 			}
@@ -768,7 +824,7 @@ window.rulesAssistantOptions = (function() {
 				App.RA.makeRange(vMin !== null ? vMin : this._min, vMax !== null ? vMax : this._max);
 		}
 
-		setValue(what) {
+		setTextValue(what) {
 			if (what === null) {
 				this._minEditor.value = null;
 				this._maxEditor.value = null;
@@ -905,9 +961,8 @@ window.rulesAssistantOptions = (function() {
 
 	// rule import field
 	class NewRuleField extends Element {
-		constructor(root) {
+		constructor() {
 			super();
-			this.root = root;
 		}
 
 		render() {
@@ -940,7 +995,7 @@ window.rulesAssistantOptions = (function() {
 				} else {
 					V.defaultRules.push(App.Entity.Utils.RARuleDatatypeCleanup(rule));
 				}
-				reload(this.root);
+				reload();
 			} catch (e) {
 				alert(`Couldn't import that rule:\n${e.message}`);
 			}
@@ -975,41 +1030,40 @@ window.rulesAssistantOptions = (function() {
 
 	// options displayed when there are no rules
 	class NoRules extends Options {
-		constructor(root) {
+		constructor() {
 			super();
-			this.root = root;
-			const newrule = new OptionsItem("Add a new rule", () => { newRule(this.root); });
+			const newrule = new OptionsItem("Add a new rule", () => { newRule(); });
 			this.appendChild(newrule);
-			const importrule = new OptionsItem("Import a rule", () => { this.root.appendChild(new NewRuleField(this.root)); });
+			const importrule = new OptionsItem("Import a rule", () => { root.appendChild(new NewRuleField()); });
 			this.appendChild(importrule);
 		}
 	}
 
 	// buttons for selecting the current rule
 	class RuleSelector extends List {
-		constructor(root) {
-			super("Current rule", V.defaultRules.map(i => [i.name, i]), false);
+		constructor() {
+			super("Current rule", V.defaultRules.map(i => [(i.name + (!!RuleHasError(i) ? " <span class='yellow'>[!]</span>" : "")), i]), false);
 			this.setValue(current_rule.name);
 			this.onchange = function(rule) {
 				V.currentRule = rule.ID;
-				reload(root);
+				reload();
 			};
 		}
 	}
 
 	// buttons for doing transformations on rules
 	class RuleOptions extends Options {
-		constructor(root) {
+		constructor() {
 			super();
-			this.appendChild(new OptionsItem("New Rule", () => newRule(root)));
-			this.appendChild(new OptionsItem("Remove Rule", () => removeRule(root)));
+			this.appendChild(new OptionsItem("New Rule", newRule));
+			this.appendChild(new OptionsItem("Remove Rule", removeRule));
 			this.appendChild(new OptionsItem("Apply rules", () => this.appendChild(new ApplicationLog())));
-			this.appendChild(new OptionsItem("Lower Priority", () => lowerPriority(root)));
-			this.appendChild(new OptionsItem("Higher Priority", () => higherPriority(root)));
-			this.appendChild(new OptionsItem("Rename", () => this.appendChild(new RenameField(root))));
+			this.appendChild(new OptionsItem("Lower Priority", lowerPriority));
+			this.appendChild(new OptionsItem("Higher Priority", higherPriority));
+			this.appendChild(new OptionsItem("Rename", () => this.appendChild(new RenameField())));
 			this.appendChild(new OptionsItem("Export this rule", () => this.appendChild(new ExportField(current_rule))));
 			this.appendChild(new OptionsItem("Export all rules", () => this.appendChild(new ExportField(...V.defaultRules))));
-			this.appendChild(new OptionsItem("Import rule(s)", () => this.appendChild(new NewRuleField(root))));
+			this.appendChild(new OptionsItem("Import rule(s)", () => this.appendChild(new NewRuleField())));
 		}
 	}
 
@@ -1024,10 +1078,10 @@ window.rulesAssistantOptions = (function() {
 	}
 
 	class RenameField extends Element {
-		constructor(root) {
+		constructor() {
 			super();
-			this.element.onblur = () => changeName(this.element.value, root);
-			this.element.onkeypress = (e) => { if (returnP(e)) { changeName(this.element.value, root); } };
+			this.element.onblur = () => changeName(this.element.value);
+			this.element.onkeypress = (e) => { if (returnP(e)) { changeName(this.element.value); } };
 		}
 
 		render() {
@@ -1092,7 +1146,7 @@ window.rulesAssistantOptions = (function() {
 				["Amputation", "amp"],
 			];
 			this.fnlist = new List("Activation function", items);
-			this.fnlist.setValue(current_rule.condition.function === "between" ? current_rule.condition.data.attribute : current_rule.condition.function);
+			this.fnlist.setValue(["between", "belongs"].includes(current_rule.condition.function) ? current_rule.condition.data.attribute : current_rule.condition.function);
 			this.fnlist.onchange = (value) => this.fnchanged(value);
 			this.appendChild(this.fnlist);
 			this.fneditor = null;
@@ -1197,8 +1251,21 @@ window.rulesAssistantOptions = (function() {
 			const elem = document.createElement("div");
 			const textarea = document.createElement("textarea");
 			textarea.innerHTML = data;
-			textarea.onblur = () => current_rule.condition.data = textarea.value;
+			$(textarea).blur(() => {
+				current_rule.condition.data = textarea.value;
+				//TODO: this would be a good place to cache the Function object that will be used by RuleHasError and ruleAppliesP
+				reload();
+			});
 			elem.appendChild(textarea);
+
+			if(RuleHasError(current_rule))
+			{
+				const errorMessage = document.createElement("div");
+				$(errorMessage).addClass("yellow");
+				errorMessage.innerText =  "WARNING: There are errors in this condition. Please ensure the syntax is correct and equality is either '==' or '===', not '='";
+				elem.appendChild(errorMessage);
+			}
+
 			const explanation = document.createElement("div");
 			explanation.innerHTML = "Insert a valid <a target='_blank' class='link-external' href='https://www.w3schools.com/js/js_comparisons.asp'>JavaScript comparison and/or logical operation</a>.";
 			elem.appendChild(explanation);
@@ -1553,7 +1620,7 @@ window.rulesAssistantOptions = (function() {
 
 	class ClearLabelSwitch extends BooleanSwitch {
 		constructor() {
-			super("Remove all tags (Gobal swith)", [false, true]);
+			super("Remove all tags (Global switch)", [false, true]);
 			this.setValue(current_rule.set.labelTagsClear);
 			this.onchange = (value) => current_rule.set.labelTagsClear = value;
 		}
@@ -2576,6 +2643,18 @@ window.rulesAssistantOptions = (function() {
 		}
 	}
 
+	const dietAddedText = function(value) {
+		switch(value) {
+			case 0:
+				return "None";
+			case 1:
+				return "Added";
+			case 2:
+				return "Based";
+			default:
+				return value;
+		}
+	}
 	class DietBaseList extends List {
 		constructor() {
 			// TODO: better data structure?
@@ -2589,16 +2668,20 @@ window.rulesAssistantOptions = (function() {
 				["Milk-Based", {cum: 0, milk: 2}],
 			];
 			super("Diet base", pairs, false);
-			this.setValue(this.value2string(current_rule.set.dietCum, current_rule.set.dietMilk));
+			this.setValue({cum: current_rule.set.dietCum, milk: current_rule.set.dietMilk });
 			this.onchange = (value) => {
 				current_rule.set.dietCum = value.cum;
 				current_rule.set.dietMilk = value.milk;
-				this.setValue(this.value2string(current_rule.set.dietCum, current_rule.set.dietMilk));
+				this.setValue(value);
 			};
 		}
-
-		value2string(cum, milk) {
-			return `cum: ${cum}, milk: ${milk}`;
+		setTextValue(what) {
+			if(what.cum == null && what.milk == null) {
+				super.setTextValue(capFirstChar(noDefaultSetting.text));
+			}
+			else {
+				super.setTextValue(`Cum: ${dietAddedText(what.cum)}, Milk: ${dietAddedText(what.milk)}`);
+			}
 		}
 	}
 
@@ -2881,7 +2964,17 @@ window.rulesAssistantOptions = (function() {
 					this.colorlist.setValue(val);
 					this.shapelist.setValue(val);
 				} else {
-					//
+					let list = val.split(' ');
+					if(list.length == 2)
+					{
+						this.colorlist.setValue(list[0]);
+						this.shapelist.setValue(list[1]);
+					}
+					else if(list.length == 1)
+					{
+						this.colorlist.trySetValue(list[0]);
+						this.shapelist.trySetValue(list[0]);
+					}
 				}
 			}
 			super.setValue(val);
diff --git a/src/js/slaveSummaryWidgets.js b/src/js/slaveSummaryWidgets.js
index 6d9ef784f0c2ff841004cf89aabf2ad5413a169c..b576a0afb403df94032c5838ff77154631197311 100644
--- a/src/js/slaveSummaryWidgets.js
+++ b/src/js/slaveSummaryWidgets.js
@@ -3348,7 +3348,7 @@ window.SlaveSummaryUncached = (function() {
 		} else if (slave.attrXX <= 35) {
 			makeSpan(c, "not attracted to women", "red", true, slave.attrXX);
 		} else if (slave.attrXX <= 65) {
-			makeSpan(c, "Disgusted by women", undefined, true, slave.attrXX);
+			makeSpan(c, "indifferent to women", undefined, true, slave.attrXX);
 		} else if (slave.attrXX <= 85) {
 			makeSpan(c, "attracted to women", "green", true, slave.attrXX);
 		} else if (slave.attrXX <= 95) {
diff --git a/src/js/storyJS.js b/src/js/storyJS.js
index 32e041e252231fdcdae3a8fb8b84bbc7138c26b6..b9ee7848a2e7fe82b9ba05a42898ac0262412fc6 100644
--- a/src/js/storyJS.js
+++ b/src/js/storyJS.js
@@ -446,7 +446,7 @@ window.overpowerCheck = function(slave, PC) {
 	strength += (185-slave.height);
 	strength -= (PC.belly/1000);
 	strength += (PC.skill.warfare/3);
-	strength -= (State.variables.PCWounded * 15);
+	strength -= (State.variables.PC.majorInjury * 15);
 
 	return strength;
 };
diff --git a/src/pregmod/personalNotes.tw b/src/pregmod/personalNotes.tw
index 9a272763877f56f023613f726491adc8623ac13b..07f94e3b6d481e1cbec8c4b9027a61582c469fc6 100644
--- a/src/pregmod/personalNotes.tw
+++ b/src/pregmod/personalNotes.tw
@@ -176,7 +176,7 @@
 						Your already huge breasts have @@.lime;grown even heavier@@ with your pregnancy.
 						<<set $PC.boobs += 25>>
 						<<if $PC.boobs >= 1400>>
-							Your desk is steadily starting to dissapear; @@.lime;H-cups will do that.@@
+							Your desk is steadily starting to disappear; @@.lime;H-cups will do that.@@
 						<</if>>
 					<</if>>
 				<<elseif $PC.boobs >= 1000>>
@@ -254,4 +254,4 @@
 			*/
 		<</if>>
 	<</if>>
-<</if>>
\ No newline at end of file
+<</if>>
diff --git a/src/pregmod/theBlackMarket.tw b/src/pregmod/theBlackMarket.tw
index 8f2424f80e46b76e812776dbc8a9f80e141418c9..154e06b2d1f5b890115bb5077194b120714b4ab6 100644
--- a/src/pregmod/theBlackMarket.tw
+++ b/src/pregmod/theBlackMarket.tw
@@ -404,12 +404,12 @@ He gestures to a door in the back of the stall. "The good shit's back there<<if
 						<<else>>
 							You cannot afford the asking price of @@.red;<<print cashFormat(25000)>>@@ for animal anal wombs and ovaries.
 						<</if>>
-						/* TODO: flesh this out some more */
+						/ TODO: flesh this out some more /
 						"Got something real special this week. These are schematics for implanting non-human organs into humans. My supplier told me they came from some military experiments or something — maybe they were trying to make some kind of super soldier. Not my business, though."
 					<<else>>
 						You lack the facilities required to grow organs.
 					<</if>>
-				<<else>>	/* if all schematics have already been purchased */
+				<<else>>	/ if all schematics have already been purchased /
 					You already possess all of the schematics for implanting animal organs.
 					<<run $merchantIllegalWares.delete("AnimalOrgans")>>
 				<</if>>
diff --git a/src/uncategorized/arcmgmt.tw b/src/uncategorized/arcmgmt.tw
index 9882b86c4cd962a6503b0154767405edb201c911..edebd87d70bf2b8138bd307e5631bb87750b5128 100644
--- a/src/uncategorized/arcmgmt.tw
+++ b/src/uncategorized/arcmgmt.tw
@@ -18,14 +18,14 @@
 		You are providing your citizens with an adequate amount of slaves to be used as sexual objects, as is expected in your degradationist society.<br>
 	<</if>>
 <</if>>
-<<if $sexDemandResult.lowerClass < 400>>
+<<if $sexDemandResult.lowerClass < 350>>
 	Your lower class citizens have @@.red;far too few options for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.lowerClass == 0>>
 		They trust you will take care of this issue as soon as you are settled in.<br>
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your lower class.<br>
 	<</if>>
-<<elseif $sexDemandResult.lowerClass < 600>>
+<<elseif $sexDemandResult.lowerClass < 550>>
 	Your lower class citizens need @@.red;some more avenues for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.lowerClass == 1>>
 		They see @@.green;you are on the right track@@ and anticipate further improvements.<br>
@@ -34,16 +34,16 @@
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your lower class.<br>
 	<</if>>
-<<elseif $sexDemandResult.lowerClass < 800>>
+<<elseif $sexDemandResult.lowerClass < 750>>
 	Your lower class citizens have no issue finding the sexual relief they need inside your arcology.
 	<<if $classSatisfied.lowerClass == 1>>
 		They are @@.green;delighted@@ with how quickly you've provided for them.<br>
 	<<else>>
 		<br>
 	<</if>>
-<<elseif $sexDemandResult.lowerClass < 1000>>
+<<elseif $sexDemandResult.lowerClass < 950>>
 	Your lower class citizens are @@.green;happy with the availability of sexual services@@ inside your arcology.<br>
-<<elseif $sexDemandResult.lowerClass == 1000>>
+<<elseif $sexDemandResult.lowerClass >= 950>>
 	Your lower class citizens are @@.green;delighted with the abundance of sexual services@@ inside your arcology.<br>
 <</if>>
 Lower class satisfaction is at <<print $sexDemandResult.lowerClass/10>>%, <<print $NPCMarketShare.lowerClass/10>>% of the market is serviced by other suppliers operating inside your arcology.<br>
@@ -61,14 +61,14 @@ Lower class satisfaction is at <<print $sexDemandResult.lowerClass/10>>%, <<prin
 	<<run cashX($NPCSlaves.lowerClass * Math.pow($sexSubsidies.lowerClass, 2) * 0.25, "policies")>>
 <</if>>
 
-<<if $sexDemandResult.middleClass < 400>>
+<<if $sexDemandResult.middleClass < 350>>
 	Your middle class citizens have @@.red;far too few options for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.middleClass == 0>>
 		They trust you will take care of this issue as soon as you are settled in.<br>
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your middle class.<br>
 	<</if>>
-<<elseif $sexDemandResult.middleClass < 600>>
+<<elseif $sexDemandResult.middleClass < 550>>
 	Your middle class citizens need @@.red;some more avenues for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.middleClass == 1>>
 		They see @@.green;you are on the right track@@ and anticipate further improvements.<br>
@@ -77,16 +77,16 @@ Lower class satisfaction is at <<print $sexDemandResult.lowerClass/10>>%, <<prin
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your middle class.<br>
 	<</if>>
-<<elseif $sexDemandResult.middleClass < 800>>
+<<elseif $sexDemandResult.middleClass < 750>>
 	Your middle class citizens have no issue finding the sexual relief they need inside your arcology.
 	<<if $classSatisfied.middleClass == 1>>
 		They are @@.green;delighted@@ with how quickly you've provided for them.<br>
 	<<else>>
 		<br>
 	<</if>>
-<<elseif $sexDemandResult.middleClass < 1000>>
+<<elseif $sexDemandResult.middleClass < 950>>
 	Your middle class citizens are @@.green;happy with the availability of sexual services@@ inside your arcology.<br>
-<<elseif $sexDemandResult.middleClass == 1000>>
+<<elseif $sexDemandResult.middleClass >= 950>>
 	Your middle class citizens are @@.green;delighted with the abundance of sexual services@@ inside your arcology.<br>
 <</if>>
 Middle class satisfaction is at <<print $sexDemandResult.middleClass/10>>%, <<print $NPCMarketShare.middleClass/10>>% of the market is serviced by other suppliers operating inside your arcology.<br>
@@ -104,14 +104,14 @@ Middle class satisfaction is at <<print $sexDemandResult.middleClass/10>>%, <<pr
 	<<run cashX($NPCSlaves.middleClass * Math.pow($sexSubsidies.middleClass, 2) * 0.25, "policies")>>
 <</if>>
 
-<<if $sexDemandResult.upperClass < 400>>
+<<if $sexDemandResult.upperClass < 350>>
 	Your upper class citizens have @@.red;far too few options for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.upperClass == 0>>
 		They trust you will take care of this issue as soon as you are settled in.<br>
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your upper class.<br>
 	<</if>>
-<<elseif $sexDemandResult.upperClass < 600>>
+<<elseif $sexDemandResult.upperClass < 550>>
 	Your upper class citizens need @@.red;some more avenues for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.upperClass == 1>>
 		They see @@.green;you are on the right track@@ and anticipate further improvements.<br>
@@ -120,16 +120,16 @@ Middle class satisfaction is at <<print $sexDemandResult.middleClass/10>>%, <<pr
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your upper class.<br>
 	<</if>>
-<<elseif $sexDemandResult.upperClass < 800>>
+<<elseif $sexDemandResult.upperClass < 750>>
 	Your upper class citizens have no issue finding the sexual relief they need inside your arcology.
 	<<if $classSatisfied.upperClass == 1>>
 		They are @@.green;delighted@@ with how quickly you've provided for them.<br>
 	<<else>>
 		<br>
 	<</if>>
-<<elseif $sexDemandResult.upperClass < 1000>>
+<<elseif $sexDemandResult.upperClass < 950>>
 	Your upper class citizens are @@.green;happy with the availability of sexual services@@ inside your arcology.<br>
-<<elseif $sexDemandResult.upperClass == 1000>>
+<<elseif $sexDemandResult.upperClass >= 950>>
 	Your upper class citizens are @@.green;delighted with the abundance of sexual services@@ inside your arcology.<br>
 <</if>>
 Upper class satisfaction is at <<print $sexDemandResult.upperClass/10>>%, <<print $NPCMarketShare.upperClass/10>>% of the market is serviced by other suppliers operating inside your arcology.<br>
@@ -147,14 +147,14 @@ Upper class satisfaction is at <<print $sexDemandResult.upperClass/10>>%, <<prin
 	<<run cashX($NPCSlaves.upperClass * Math.pow($sexSubsidies.upperClass, 2) * 0.25, "policies")>>
 <</if>>
 
-<<if $sexDemandResult.topClass < 400>>
+<<if $sexDemandResult.topClass < 350>>
 	Your arcology's millionaires have @@.red;far too few options for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.topClass == 0>>
 		They trust you will take care of this issue as soon as you are settled in.<br>
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your millionaires.<br>
 	<</if>>
-<<elseif $sexDemandResult.topClass < 600>>
+<<elseif $sexDemandResult.topClass < 550>>
 	Your arcology's millionaires need @@.red;some more avenues for sexual relief@@ inside your arcology.
 	<<if $classSatisfied.topClass == 1>>
 		They see @@.green;you are on the right track@@ and anticipate further improvements.<br>
@@ -163,16 +163,16 @@ Upper class satisfaction is at <<print $sexDemandResult.upperClass/10>>%, <<prin
 	<<else>>
 		It is @@.red;causing dissatisfaction@@ among your millionaires.<br>
 	<</if>>
-<<elseif $sexDemandResult.topClass < 800>>
+<<elseif $sexDemandResult.topClass < 750>>
 	Your arcology's millionaires have no issue finding the sexual relief they need inside your arcology.
 	<<if $classSatisfied.topClass == 1>>
 		They are @@.green;delighted@@ with how quickly you've provided for them.<br>
 	<<else>>
 		<br>
 	<</if>>
-<<elseif $sexDemandResult.topClass < 1000>>
+<<elseif $sexDemandResult.topClass < 950>>
 	Your arcology's millionaires are @@.green;happy with the availability of sexual services@@ inside your arcology.<br>
-<<elseif $sexDemandResult.topClass == 1000>>
+<<elseif $sexDemandResult.topClass >= 950>>
 	Your arcology's millionaires are @@.green;delighted with the abundance of sexual services@@ inside your arcology.<br>
 <</if>>
 Millionaire satisfaction is at <<print $sexDemandResult.topClass/10>>%, <<print $NPCMarketShare.topClass/10>>% of the market is serviced by other suppliers operating inside your arcology.<br>
diff --git a/src/uncategorized/main.tw b/src/uncategorized/main.tw
index aab6e91ab2fde5f34fbbf4a921ae2c1059c7fbf1..481b4988cf4f00abe3718a7da18905884c1efeab 100644
--- a/src/uncategorized/main.tw
+++ b/src/uncategorized/main.tw
@@ -96,17 +96,6 @@
 <</if>>
 <<if ($seeDesk == 1) && ($seeFCNN == 0)>><br><</if>>
 
-/* Check if custom rules have an assignation operator */
-<<set _RL = $defaultRules.length>>
-<<set _regex = /[^!=<>]=[^=<>]/gi>>
-<<set $rulesError = false>>
-<<for _itr = 0; _itr < _RL; _itr++>>
-	<<if $defaultRules[_itr].condition.function == "custom" && $defaultRules[_itr].condition.data.match(_regex)>>
-		<<set $rulesError = true>>
-		<<break>>
-	<</if>>
-<</for>>
-
 __''MAIN MENU''__&nbsp;&nbsp;&nbsp;&nbsp;//[[Summary Options]]//
 <<if $rulesAssistantMain != 0>>
 	| //<span id="RAButton"><<link "Rules Assistant Options" "Rules Assistant">><</link>></span>// @@.cyan;[R]@@
@@ -115,7 +104,7 @@ __''MAIN MENU''__&nbsp;&nbsp;&nbsp;&nbsp;//[[Summary Options]]//
 	<<else>>
 		| //<<link "Stop applying Rules Assistant at week end" "Main">><<set $rulesAssistantAuto = 0>><</link>>//
 	<</if>>
-	| //<<if $rulesError>>@@.yellow; WARNING: some custom rules will change slave variables @@<</if>><<link "Re-apply Rules Assistant now (this will only check slaves in the Penthouse)" "Main">><<for _i = 0;_i < _SL;_i++>><<if $slaves[_i].assignmentVisible == 1 && $slaves[_i].useRulesAssistant == 1>><<= DefaultRules($slaves[_i])>><</if>><</for>><</link>>//
+	| //<<if DefaultRulesError()>>@@.yellow; WARNING: One or more rules' custom conditions has errors! @@<</if>><<link "Re-apply Rules Assistant now (this will only check slaves in the Penthouse)" "Main">><<for _i = 0;_i < _SL;_i++>><<if $slaves[_i].assignmentVisible == 1 && $slaves[_i].useRulesAssistant == 1>><<= DefaultRules($slaves[_i])>><</if>><</for>><</link>>//
 <</if>>
 
 <<print App.UI.SlaveList.penthousePage()>>
@@ -203,4 +192,4 @@ __''MAIN MENU''__&nbsp;&nbsp;&nbsp;&nbsp;//[[Summary Options]]//
 <</if>>
 <<if ($debugMode == 1)>>
 	//| [[Show all walk past scenes|Walk Past List]]//
-<</if>>
\ No newline at end of file
+<</if>>
diff --git a/src/uncategorized/slaveAssignmentsReport.tw b/src/uncategorized/slaveAssignmentsReport.tw
index b8ec2375276066a5439e1146aec0d51a0756593a..999c467f35541a292512b9d302e296abfa41cb56 100644
--- a/src/uncategorized/slaveAssignmentsReport.tw
+++ b/src/uncategorized/slaveAssignmentsReport.tw
@@ -106,28 +106,28 @@ _middleClassClubRatio = (_middleClassSexDemand + _visitorsSexDemand) / _clubDema
 
 /*Brothel or street whore sex supply*/
 <<if _lowerClassSexDemand < $slaveJobValues.brothel.lowerClass>>
-	<<set $whorePriceAdjustment.lowerClass = Math.pow(_lowerClassSexDemand / ($slaveJobValues.brothel.lowerClass + $NPCSexSupply.lowerClass), 2),
+	<<set $whorePriceAdjustment.lowerClass = Math.max(Math.pow(_lowerClassSexDemand / ($slaveJobValues.brothel.lowerClass + $NPCSexSupply.lowerClass), 2), 0.25),
 	_lowerClassSexDemand = 0>> /*This accounts for people having too much choice and getting more picky how they spend their money*/
 <<else>>
 	<<set $whorePriceAdjustment.lowerClass = Math.pow(_lowerClassSexDemand / ($slaveJobValues.brothel.lowerClass + $NPCSexSupply.lowerClass), 0.25),
 	_lowerClassSexDemand -= $slaveJobValues.brothel.lowerClass>> /* People are willing to pay more for a scarce good, but within reason */
 <</if>>
 <<if _middleClassSexDemand < $slaveJobValues.brothel.middleClass>>
-	<<set $whorePriceAdjustment.middleClass = Math.pow(_middleClassSexDemand / ($slaveJobValues.brothel.middleClass + $NPCSexSupply.middleClass), 2),
+	<<set $whorePriceAdjustment.middleClass = Math.max(Math.pow(_middleClassSexDemand / ($slaveJobValues.brothel.middleClass + $NPCSexSupply.middleClass), 2), 0.25),
 	_middleClassSexDemand = 0>>
 <<else>>
 	<<set $whorePriceAdjustment.middleClass = Math.pow(_middleClassSexDemand / ($slaveJobValues.brothel.middleClass + $NPCSexSupply.middleClass), 0.25),
 	_middleClassSexDemand -= $slaveJobValues.brothel.middleClass>>
 <</if>>
 <<if _upperClassSexDemand < $slaveJobValues.brothel.upperClass>>
-	<<set $whorePriceAdjustment.upperClass = Math.pow(_upperClassSexDemand / ($slaveJobValues.brothel.upperClass + $NPCSexSupply.upperClass), 2),
+	<<set $whorePriceAdjustment.upperClass = Math.max(Math.pow(_upperClassSexDemand / ($slaveJobValues.brothel.upperClass + $NPCSexSupply.upperClass), 2), 0.25),
 	_upperClassSexDemand = 0>>
 <<else>>
 	<<set $whorePriceAdjustment.upperClass = Math.pow(_upperClassSexDemand / ($slaveJobValues.brothel.upperClass + $NPCSexSupply.upperClass), 0.25),
 	_upperClassSexDemand -= $slaveJobValues.brothel.upperClass>>
 <</if>>
 <<if _topClassSexDemand < $slaveJobValues.brothel.topClass>>
-	<<set $whorePriceAdjustment.topClass = Math.pow(_topClassSexDemand / ($slaveJobValues.brothel.topClass + $NPCSexSupply.topClass), 2),
+	<<set $whorePriceAdjustment.topClass = Math.max(Math.pow(_topClassSexDemand / ($slaveJobValues.brothel.topClass + $NPCSexSupply.topClass), 2), 0.25),
 	_topClassSexDemand = 0>>
 <<else>>
 	<<set $whorePriceAdjustment.topClass = Math.pow(_topClassSexDemand / ($slaveJobValues.brothel.topClass + $NPCSexSupply.topClass), 0.25),
diff --git a/src/uncategorized/storyCaption.tw b/src/uncategorized/storyCaption.tw
index 1cf0d746140aab6c0fbfcac2562d74765d73c616..2b58dccd294e4df2728f0471ea874f7b7a0438b0 100644
--- a/src/uncategorized/storyCaption.tw
+++ b/src/uncategorized/storyCaption.tw
@@ -9,8 +9,8 @@
 			<strong> <span id="endWeekButton"> <br><br>
 			<<link "$nextButton">> <<goto $nextLink>> <</link>> @@.cyan;[Ent]@@
 			</span> </strong>
-			<<if $rulesError && $rulesAssistantAuto == 1>>
-				<br>@@.yellow;WARNING: some custom rules will change slave variables@@
+			<<if $rulesAssistantAuto == 1 && DefaultRulesError()>>
+				<br>@@.yellow;WARNING: Rules Assistant has rules with errors!@@
 			<</if>>
 		<<else>>
 			<strong> <span id="nextButton"> <<if $nextButton != " ">> <br><br>