diff --git a/src/js/releaseRules.js b/src/js/releaseRules.js
index 2a19f47f112afc74d6709569995d9ecdf8fd63ff..03df626bd74b90d0fbcb0e48cba38d8649b61f4b 100644
--- a/src/js/releaseRules.js
+++ b/src/js/releaseRules.js
@@ -21,6 +21,52 @@ App.Utils.sexAllowed = function sexAllowed(slaveA, slaveB) {
 	}
 };
 
+/**
+ * Returns true if a slave has a romantic partner other than the PC who is both willing and allowed to have sex with her.
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+App.Utils.hasPartnerSex = function hasPartnerSex(slave) {
+	const hasWillingSlavePartner = (slave.rules.relationship === "permissive") && (slave.relationship >= 3) && (slave.relationshipTarget > 0);
+	return hasWillingSlavePartner && this.sexAllowed(slave, getSlave(slave.relationshipTarget));
+};
+
+/**
+ * Returns true if a slave has a close family member other than the PC who is both willing and allowed to have sex with her.
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+App.Utils.hasFamilySex = function hasFamilySex(slave) {
+	if (V.seeIncest === 0 || slave.rules.release.family === 0) {
+		return false;
+	}
+	if (V.familyTesting === 0 && slave.relationTarget > 0) {
+		return this.sexAllowed(slave, getSlave(slave.relationTarget));
+	} else { // familyTesting === 1
+		return jsDef(randomRelatedSlave(slave, (s) => { return this.sexAllowed(slave, s); }));
+	}
+};
+
+/**
+ * Returns true if a slave has no practical form of release.
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+App.Utils.hasNoOutlet = function hasNoOutlet(slave) {
+	const rel = slave.rules.release;
+	return (rel.masturbation === 0) && (rel.master === 0) && (rel.slaves === 0) && !this.hasPartnerSex(slave) && !this.hasFamilySex(slave);
+};
+
+/**
+ * Returns true if a slave's only practical form of release is masturbation.
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+App.Utils.mustMasturbate = function mustMasturbate(slave) {
+	const rel = slave.rules.release;
+	return (rel.masturbation === 1) && (rel.master === 0) && (rel.slaves === 0) && !this.hasPartnerSex(slave) && !this.hasFamilySex(slave);
+};
+
 /**
  * Returns a short summary of the slave's release rules
  * @param {App.Entity.SlaveState} slave