diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js
index 493ef0cea96d4b2b1052d67ef54d85606efa0d1c..692bf16d9da127785acc243c907ec7f15b3360f4 100644
--- a/js/003-data/gameVariableData.js
+++ b/js/003-data/gameVariableData.js
@@ -111,6 +111,8 @@ App.Data.defaultGameStateVariables = {
 	retainCareer: 1,
 	RIERemaining: 0,
 	RIEPerWeek: 1,
+	/** @type {number[]} */
+	RIESkip: [],
 	rulesAssistantAuto: 0,
 	rulesAssistantMain: 1,
 	seeAge: 1,
diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js
index a3371a950110195dfd71c0b7424e347d87c53fe0..8814ed472cbbc70b4555afdb63601f2c21a13a0b 100644
--- a/src/endWeek/nextWeek/nextWeek.js
+++ b/src/endWeek/nextWeek/nextWeek.js
@@ -324,6 +324,7 @@ App.EndWeek.nextWeek = function() {
 		V.prisonCircuitIndex = 0;
 	}
 
+	V.RIESkip = [];
 	V.independenceDay = 1;
 	V.coursed = 0;
 	V.JFC.reorder = 0;
diff --git a/src/events/randomEvent.js b/src/events/randomEvent.js
index 6b5932640178db1c852fac583baa3ff303b71f5c..9968c6ce98a851e104fa404022c075fdaa7178ba 100644
--- a/src/events/randomEvent.js
+++ b/src/events/randomEvent.js
@@ -439,6 +439,7 @@ App.Events.playRandomIndividualEvent = function() {
 	if (V.event instanceof App.Events.BaseEvent) {
 		// we've deserialized a saved game with an event active, or a player has picked one, so just play it immediately
 		V.event.execute(d);
+		V.RIESkip.push(V.event.actors[0]);
 		V.passageSwitchHandler = clearEvent;
 	} else {
 		const eligibleSlaves = getRieEligibleSlaves();
@@ -448,9 +449,14 @@ App.Events.playRandomIndividualEvent = function() {
 		} else if (V.debugMode > 0 && V.debugModeEventSelection > 0) {
 			V.nextButton = "Refresh";
 			V.nextLink = passage();
+			V.RIERemaining++; // we've consumed one of our event possibilities already, but we haven't played the event yet, so put it back
 
 			// show all the possible random individual events
 			App.UI.DOM.appendNewElement("h2", d, "Random Individual Events");
+			const countPara = App.UI.DOM.appendNewElement("p", d, `At most ${numberWithPluralOne(V.RIEPerWeek, "slave")} will get Random Individual Events per week, and you have ${num(V.RIERemaining)} left.`);
+			if (V.RIESkip.length > 0) {
+				countPara.append(` An event has already played for ${toSentence(V.RIESkip.map(s => SlaveFullName(getSlave(s))))}, so they are not eligible to play another.`);
+			}
 			const slaveDiv = App.UI.DOM.appendNewElement("div", d, "Show events for this slave: ");
 			const slaveDropdown = App.UI.DOM.appendNewElement("select", slaveDiv);
 			const startingSlave = eligibleSlaves.random();
@@ -497,6 +503,7 @@ App.Events.playRandomIndividualEvent = function() {
 			// @ts-ignore - under-defined object
 			State.current.variables.event = V.event = event;
 			event.execute(d);
+			V.RIESkip.push(event.actors[0]);
 			V.passageSwitchHandler = clearEvent;
 		}
 	}
diff --git a/src/js/utilsSlaves.js b/src/js/utilsSlaves.js
index 5047bb64333dca8ae8430f7bc9ef7b2c43cbdea9..ff2af07ed4ca649ba62ef475ecd87faf5592089d 100644
--- a/src/js/utilsSlaves.js
+++ b/src/js/utilsSlaves.js
@@ -6,7 +6,10 @@ globalThis.fuckSlavesLength = function() {
 };
 
 globalThis.getRieEligibleSlaves = function() {
-	return V.slaves.filter(s => assignmentVisible(s) || ["serve in the master suite", "be your Concubine", "work as a servant"].includes(s.assignment) && s.fuckdoll === 0);
+	return V.slaves.filter(s => s.fuckdoll === 0 &&
+		(assignmentVisible(s) || [Job.MASTERSUITE, Job.CONCUBINE, Job.QUARTER].includes(s.assignment)) &&
+		!V.RIESkip.includes(s.ID)
+	);
 };
 
 globalThis.SlaveSort = function() {