diff --git a/src/init/setupVars.tw b/src/init/setupVars.tw
index a1de3392ff992389f7fde6eea4a32e24a14ae09d..5a23e12fa460c70ee4f1d872dd9b5aa110c4dee8 100644
--- a/src/init/setupVars.tw
+++ b/src/init/setupVars.tw
@@ -2082,6 +2082,12 @@ Then pick _namePool.random(), or display those names as possible choices, or do
 	{name: "Anal chastity belt", value: "anal chastity"},
 	{name: "Combined chastity belt", value: "combined chastity"}]>>
 
+<<set setup.vaginalAttachments = [
+	{name: "No default setting", value: "no default setting"},
+	{name: "None", value: "none"},
+	{name: "Bullet vibrator", value: "bullet vibrator"},
+	{name: "Vibrating dildo", value: "vibrating dildo"}]>>
+
 <<set setup.dickAccessories = [
 	{name: "No default setting", value: "no default setting"},
 	{name: "None", value: "none"},
diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js
index ddc98c3653ed9ca07972d17158760721bf29012f..0fff91422223a2dbc21531668aa9a1fcf7f763c3 100644
--- a/src/js/SlaveState.js
+++ b/src/js/SlaveState.js
@@ -1529,6 +1529,12 @@ App.Entity.SlaveState = class SlaveState {
 		 * * "anal chastity"
 		 * * "combined chastity"
 		 */
+		this.vaginalAttachment = "none";
+		/**
+		 * * "none"
+		 * * "bullet vibrator"
+		 * * "vibrating dildo"
+		 */
 		this.dickAccessory = "none";
 		/**
 		 * * "none"
diff --git a/src/js/datatypeCleanupJS.js b/src/js/datatypeCleanupJS.js
index bad5c1431f63d58beedfb791b1fc2156f2d68909..ee9df56b7e041178ab30b29546608e0f3f015da0 100644
--- a/src/js/datatypeCleanupJS.js
+++ b/src/js/datatypeCleanupJS.js
@@ -372,6 +372,9 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		if (typeof slave.vaginalAccessory !== "string") {
 			slave.vaginalAccessory = "none";
 		}
+		if (typeof slave.vaginalAttachments !== "string") {
+			slave.vaginalAttachments = "none";
+		}
 		if (typeof slave.dickAccessory !== "string") {
 			slave.dickAccessory = "none";
 		}
@@ -942,6 +945,9 @@ window.childCosmeticsDatatypeCleanup = function childCosmeticsDatatypeCleanup(ch
 	if (typeof child.vaginalAccessory !== "string") {
 		child.vaginalAccessory = "none";
 	}
+	if (typeof child.vaginalAttachments !== "string") {
+		child.vaginalAttachments = "none";
+	}
 	if (typeof child.dickAccessory !== "string") {
 		child.dickAccessory = "none";
 	}
diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js
index f9daa49363c33083c9dc5138f06e28afa93b35ce..49f07cb2bd63301da12adbd835205581cf4e6f91 100644
--- a/src/js/rulesAssistantOptions.js
+++ b/src/js/rulesAssistantOptions.js
@@ -917,6 +917,7 @@ window.rulesAssistantOptions = (function() {
 			this.appendChild(new VagAccVirginsList());
 			this.appendChild(new VagAccAVirginsList());
 			this.appendChild(new VagAccOtherList());
+			this.appendChild(new VagAccAttachmentsList();)
 			if (V.seeDicks !== 0 || V.makeDicks !== 0) {
 				this.appendChild(new DickAccVirginsList());
 				this.appendChild(new DickAccOtherList());
@@ -1334,6 +1335,14 @@ window.rulesAssistantOptions = (function() {
 		}
 	}
 
+	class VagAccAttachmentsList extends List {	/**TODO: this will need expanding */
+		constructor() {
+			super("Vaginal attachments for slaves with vaginal accessories", accs);
+			this.setValue(current_rule.set.vaginalAttachment);
+			this.onchange = (value) => current_rule.set.vaginalAttachment = value;
+		}
+	}
+
 	class DickAccVirginsList extends List {
 		constructor() {
 			super("Dick accessories for anal virgins", setup.dickAccessories.map(i => [i.name, i.value]));
diff --git a/src/js/slaveSummaryWidgets.js b/src/js/slaveSummaryWidgets.js
index 6a73d9818b104530d70105909b562f0433f9acd3..3598ce92af9677e0d92d26c90464672c023dd17b 100644
--- a/src/js/slaveSummaryWidgets.js
+++ b/src/js/slaveSummaryWidgets.js
@@ -4631,6 +4631,14 @@ window.SlaveSummaryUncached = (function(){
 				break;
 		}
 		r += " ";
+		switch (slave.vaginalAttachment) {	/** TODO: this will need serious work */
+			case "bullet vibrator":
+				r += `Attached bullet vibrator.`;
+				break;
+			case "vibrating dildo":
+				r += `Vibrating dildo.`;
+				break;
+		}
 	}
 
 	/** @param {App.Entity.SlaveState} slave */
diff --git a/src/pregmod/widgets/bodyswapWidgets.tw b/src/pregmod/widgets/bodyswapWidgets.tw
index 612aee850961b571a69370547bd3ee0924e18821..6e284a0f88b530c93b452923b25cb40d3563dd1a 100644
--- a/src/pregmod/widgets/bodyswapWidgets.tw
+++ b/src/pregmod/widgets/bodyswapWidgets.tw
@@ -118,6 +118,7 @@
 <<set $args[0].teeth = $args[1].teeth>>
 <<set $args[0].tonguePiercing = $args[1].tonguePiercing>>
 <<set $args[0].vagina = $args[1].vagina>>
+<<set $args[0].vaginalAttachment = $args[1].vaginalAttachment>>
 <<set $args[0].vaginaLube = $args[1].vaginaLube>>
 <<set $args[0].vaginaPiercing = $args[1].vaginaPiercing>>
 <<set $args[0].vaginaTat = $args[1].vaginaTat>>
diff --git a/src/uncategorized/reRelativeRecruiter.tw b/src/uncategorized/reRelativeRecruiter.tw
index a1a3fa2449a446f441d1dc79667d3100c7e5a1a3..45890cc72e87646ebb16a8689bcff852e1770922 100644
--- a/src/uncategorized/reRelativeRecruiter.tw
+++ b/src/uncategorized/reRelativeRecruiter.tw
@@ -485,6 +485,7 @@
 <<set $activeSlave.inflation = 0, $activeSlave.inflationType = "none", $activeSlave.inflationMethod = 0>>
 <<set $activeSlave.bodySwap = 0>>
 <<set $activeSlave.pregControl = "none">>
+<<set $activeSlave.vaginalAttachment = "none">>
 <<set $activeSlave.buttplugAttachment = "none">>
 <<run SetBellySize($activeSlave)>>
 <<if $activeSlave.physicalAge < 6>>
diff --git a/src/uncategorized/slaveStats.tw b/src/uncategorized/slaveStats.tw
index 1795cfc1d3e1850fae4365878596c78a7b3f36eb..c8487ab2b20113fa6f52de2af822748b2e0e29c6 100644
--- a/src/uncategorized/slaveStats.tw
+++ b/src/uncategorized/slaveStats.tw
@@ -248,6 +248,7 @@ slaveName: $activeSlave.slaveName	   /* TODO: figure out why this is being inden
 <br>collar: $activeSlave.collar
 <br>shoes: $activeSlave.shoes
 <br>vaginalAccessory: $activeSlave.vaginalAccessory
+<br>vaginalAttachment: $activeSlave.vaginalAttachment
 <br>dickAccessory: $activeSlave.dickAccessory
 <br>legAccessory: $activeSlave.legAccessory
 <br>buttplug: $activeSlave.buttplug