diff --git a/src/js/utilJS.js b/src/js/utilJS.js
index 008044413dee80374e3f15e1139a14c5254b8ff8..e449acae44b6208241736bc114dd9c922b8d7eef 100644
--- a/src/js/utilJS.js
+++ b/src/js/utilJS.js
@@ -3218,6 +3218,25 @@ window.mapIdList = function(list) {
 	return mappedList;
 };
 
+/**
+ * Returns a "disobedience factor" between 0 (perfectly obedient) and 100 (completely defiant)
+ * @param {App.Entity.SlaveState} slave
+ * @returns {number}
+ */
+window.disobedience = function(slave) {
+	const devotionBaseline = 20; // with devotion above this number slaves will obey completely
+	const trustBaseline = -20; // with trust below this number slaves will obey completely
+
+	if (slave.devotion > devotionBaseline || slave.trust < trustBaseline) {
+		return 0; // no chance of disobedience
+	}
+
+	// factors are between 0 (right on the boundary of perfectly obedient) and 10 (completely disobedient)
+	let devotionFactor = 10 - ((10 * (slave.devotion + 100))/(devotionBaseline + 100));
+	let trustFactor = (10 * (slave.trust - trustBaseline))/(100 - trustBaseline);
+	return Math.round(devotionFactor * trustFactor);
+};
+
 /**
  * Topological sorting algorithm
  * https://gist.github.com/shinout/1232505