diff --git a/js/003-data/slaveWearData.js b/js/003-data/slaveWearData.js
index ee5f17b6f40c2bd78e4fb0360f5554ebc3d9450c..737c020d0284e3fede3ea03c02cb5a32d06bd353 100644
--- a/js/003-data/slaveWearData.js
+++ b/js/003-data/slaveWearData.js
@@ -983,53 +983,6 @@ App.Data.slaveWear = {
 		]
 	]),
 
-	vaginalAccessories: new Map([
-		["none", {name: "None"}],
-		["bullet vibrator", {name: "Bullet vibrator"}],
-		["smart bullet vibrator",
-			{
-				name: "Smart bullet vibrator",
-				get requirements() {
-					return V.boughtItem.toys.smartVibes === 1;
-				}
-			}
-		],
-		["dildo", {name: "Dildo"}],
-		["long dildo",
-			{
-				name: "Long dildo",
-				get requirements() {
-					return V.boughtItem.toys.dildos === 1;
-				}
-			}
-		],
-		["large dildo", {name: "Large dildo"}],
-		["long, large dildo",
-			{
-				name: "Long, large dildo",
-				get requirements() {
-					return V.boughtItem.toys.dildos === 1;
-				}
-			}
-		],
-		["huge dildo",
-			{
-				name: "Huge dildo",
-				get requirements() {
-					return V.boughtItem.toys.dildos === 1;
-				}
-			}
-		],
-		["long, huge dildo",
-			{
-				name: "Long, huge dildo",
-				get requirements() {
-					return V.boughtItem.toys.dildos === 1;
-				}
-			}
-		]
-	]),
-
 	vaginalAttachments: new Map([
 		["none", {name: "None"}],
 		["vibrator",
@@ -1263,7 +1216,101 @@ App.Data.buttplugs = new Map([
 		}
 	]
 ]);
+/**
+ * @typedef {object} vaginalAccessories
+ * @property {string} name
+ * @property {FC.FutureSociety} [fs] Automatically unlocked with this FS.
+ * @property {boolean} [requirements]
+ * @property {0|1|2|3} width
+ * @property {0|1|2} length
+ * @property {0|1|2} [vibrates=0] 0: none, 1: standard, 2: "smart" vibe
+ */
 
+/**
+ * @type {Map<string, vaginalAccessories>}
+ */
+App.Data.vaginalAccessories = new Map([
+	["none",
+		{
+			name: "None",
+			width: 0,
+			length: 0
+		}
+	],
+	["bullet vibrator",
+		{
+			name: "Bullet vibrator",
+			width: 0,
+			length: 1,
+			vibrates: 1
+		}
+	],
+	["smart bullet vibrator",
+		{
+			name: "Smart bullet vibrator",
+			get requirements() {
+				return V.boughtItem.toys.smartVibes === 1;
+			},
+			width: 0,
+			length: 1,
+			vibrates: 2
+		}
+	],
+	["dildo",
+		{
+			name: "Dildo",
+			width: 1,
+			length: 1
+		}
+	],
+	["long dildo",
+		{
+			name: "Long dildo",
+			get requirements() {
+				return V.boughtItem.toys.dildos === 1;
+			},
+			width: 1,
+			length: 2
+		}
+	],
+	["large dildo",
+		{
+			name: "Large dildo",
+			width: 2,
+			length: 1
+		}
+	],
+	["long, large dildo",
+		{
+			name: "Long, large dildo",
+			get requirements() {
+				return V.boughtItem.toys.dildos === 1;
+			},
+			width: 2,
+			length: 2
+		}
+	],
+	["huge dildo",
+		{
+			name: "Huge dildo",
+			get requirements() {
+				return V.boughtItem.toys.dildos === 1;
+			},
+			width: 3,
+			length: 1
+		}
+	],
+	["long, huge dildo",
+		{
+			name: "Long, huge dildo",
+			get requirements() {
+				return V.boughtItem.toys.dildos === 1;
+			},
+			width: 3,
+			length: 2
+		}
+	]
+]);
 /**
  * @typedef {object} slaveWearChastity
  * @property {string} name
@@ -1381,3 +1428,4 @@ App.Data.chastityDevices = new Map([
 		}
 	]
 ]);
+
diff --git a/src/art/vector/VectorArtJS.js b/src/art/vector/VectorArtJS.js
index 05f494ec1451c625adb5cec15ef0962e1ffd8c42..d58a6ce3ed272f59a680a1cada7789984ef2df1e 100644
--- a/src/art/vector/VectorArtJS.js
+++ b/src/art/vector/VectorArtJS.js
@@ -1771,7 +1771,7 @@ App.Art.vectorArtElement = (function() {
 						} else if (slave.vaginalAccessory === "long, huge dildo") {
 							svgQueue.add("Art_Vector_Dildo_Huge_Long");
 						}
-					} /* else if (slave.vaginalAccessory === "bullet vibrator" || slave.vaginalAccessory === "smart bullet vibrator") {
+					} /* else if (dildoWidth(slave) === 0) {
 						svgQueue.add("Art_Vector_Bullet_Vibrator");
 					} */
 			}
diff --git a/src/endWeek/saClothes.js b/src/endWeek/saClothes.js
index 30075c19d6384c3c14d08d3fd865829da542269d..e2cd5e60178d1842c8a1267bf8c76334295a3345 100644
--- a/src/endWeek/saClothes.js
+++ b/src/endWeek/saClothes.js
@@ -71,7 +71,7 @@ App.SlaveAssignment.clothes = (function() {
 			slave.vaginalAccessory = "none";
 			slave.vaginalAttachment = "none";
 		} else {
-			if (["none", "bullet vibrator", "smart bullet vibrator"].includes(slave.vaginalAccessory)) {
+			if (dildoWidth(slave) === 0) {
 				slave.vaginalAttachment = "none";
 			}
 		}
@@ -920,9 +920,10 @@ App.SlaveAssignment.clothes = (function() {
 	 *
 	 */
 	function vaginaAccessories(slave) {
+		const dildo = App.Data.vaginalAccessories.get(slave.vaginalAccessory) || V.customItem.vaginalAccessories.get(slave.vaginalAccessory);
 		if (slave.vaginalAccessory !== "none") {
-			if (slave.vaginalAccessory === "bullet vibrator" || slave.vaginalAccessory === "smart bullet vibrator") {
-				r.push(`Constantly wearing a bullet vibrator`);
+			if (dildo.width === 0) {
+				r.push(`Constantly wearing a ${slave.vaginalAccessory}`);
 				if (slave.devotion < 20) {
 					r.push(`habituates ${him} to sexual slavery and <span class="hotpink">increases ${his} submissiveness.</span>`);
 					slave.devotion += 2;
@@ -930,7 +931,7 @@ App.SlaveAssignment.clothes = (function() {
 					r.push(`reminds ${him} of ${his} place and <span class="hotpink">increases ${his} devotion to you.</span>`);
 					slave.devotion++;
 				}
-			} else if (slave.vaginalAccessory === "dildo") {
+			} else if (dildo.width === 1) {
 				if (slave.vagina < 1 && jsRandom(1, 100) > 50) {
 					r.push(`Constantly wearing a dildo in ${his} virgin pussy <span class="lime">gets it used to penetration.</span>`);
 					slave.vagina += 1;
@@ -943,29 +944,16 @@ App.SlaveAssignment.clothes = (function() {
 						slave.sexualFlaw = "none";
 					}
 				}
-			} else if (slave.vaginalAccessory === "long dildo") {
-				if (slave.vagina < 1 && jsRandom(1, 100) > 50) {
-					r.push(`Constantly wearing a dildo in ${his} virgin pussy <span class="lime">gets it used to penetration.</span>`);
-					slave.vagina += 1;
-				} else {
-					r.push(`${His} pussy easily accommodates the dildo ${he}'s required to wear.`);
-				}
-				if (slave.fuckdoll === 0) {
-					if (slave.fetish !== "mindbroken") {
-						if (slave.sexualFlaw === "hates penetration" && jsRandom(1, 100) > 50) {
-							r.push(`The habit <span class="green">reduces ${his} dislike of having ${his} pussy filled.</span>`);
-							slave.sexualFlaw = "none";
-						}
-						if (slave.sexualQuirk === "size queen") {
-							r.push(`Being able to hold such a long dildo is a <span class="hotpink">point of pride</span> for the ostentatious size queen.`);
-							slave.devotion += 2;
-						} else {
-							r.push(`It penetrates ${his} cervix causing ${him} tremendous discomfort, making ${him} a little <span class="gold">less trusting</span> of you.`);
-							slave.trust -= 1;
-						}
+				if (dildo.length > 1) {
+					if (slave.sexualQuirk === "size queen") {
+						r.push(`Being able to hold such a long dildo is a <span class="hotpink">point of pride</span> for the ostentatious size queen.`);
+						slave.devotion += 2;
+					} else {
+						r.push(`It penetrates ${his} cervix causing ${him} tremendous discomfort, making ${him} a little <span class="gold">less trusting</span> of you.`);
+						slave.trust -= 1;
 					}
 				}
-			} else if (slave.vaginalAccessory === "large dildo") {
+			} else if (dildo.width === 2) {
 				if (slave.vagina < 3) {
 					if (jsRandom(1, 4) === 1) {
 						r.push(`Constantly wearing a large dildo in ${his} pussy <span class="lime">stretches it out.</span>`);
@@ -979,105 +967,93 @@ App.SlaveAssignment.clothes = (function() {
 				if (slave.fuckdoll === 0) {
 					if (slave.fetish !== "mindbroken") {
 						if (slave.vagina < 2) {
-							r.push(`The big dildo in ${his} tight cunt`);
-							if (slave.sexualQuirk === "size queen") {
-								r.push(`is a <span class="hotpink">point of pride</span> for the ostentatious size queen.`);
-								slave.devotion += 2;
-							} else {
-								r.push(`<span class="hotpink">breaks ${him} to sexual slavery</span> slightly.`);
-								slave.devotion += 1;
-							}
-							if (slave.vagina === 1) {
-								r.push(`It stretches ${his} tight cunt to soreness by the end of every day, so it also makes ${him} a little <span class="gold">less trusting</span> of you.`);
-								slave.trust -= 1;
-							}
-						}
-					}
-				}
-			} else if (slave.vaginalAccessory === "long, large dildo") {
-				if (slave.vagina < 3) {
-					if (jsRandom(1, 4) === 1) {
-						r.push(`Constantly wearing a large dildo in ${his} pussy <span class="lime">stretches it out.</span>`);
-						slave.vagina += 1;
-					} else {
-						r.push(`The large dildo ${he}'s required to wear is a stretch for ${his} cunt, but pussies are resilient and ${he}rs isn't seriously affected.`);
-					}
-				} else {
-					r.push(`${His} pussy accommodates the large dildo ${he}'s required to wear.`);
-				}
-				if (slave.vagina < 2) {
-					if (slave.fuckdoll === 0) {
-						if (slave.fetish !== "mindbroken") {
-							r.push(`The big, long dildo in ${his} tight cunt`);
-							if (slave.sexualQuirk === "size queen") {
-								r.push(`is a <span class="hotpink">point of pride</span> for the ostentatious size queen.`);
-								slave.devotion += 2;
+							if (dildo.length === 1) {
+								r.push(`The big dildo in ${his} tight cunt`);
+								if (slave.sexualQuirk === "size queen") {
+									r.push(`is a <span class="hotpink">point of pride</span> for the ostentatious size queen.`);
+									slave.devotion += 2;
+								} else {
+									r.push(`<span class="hotpink">breaks ${him} to sexual slavery</span> slightly.`);
+									slave.devotion += 1;
+								}
+								if (slave.vagina === 1) {
+									r.push(`It stretches ${his} tight cunt to soreness by the end of every day, so it also makes ${him} a little <span class="gold">less trusting</span> of you.`);
+									slave.trust -= 1;
+								}
 							} else {
-								r.push(`<span class="hotpink">breaks ${him} to sexual slavery</span> slightly. It also penetrates ${his} cervix, causing ${him} tremendous discomfort, and making ${him} a little <span class="gold">less trusting</span> of you.`);
-								slave.devotion += 1;
-								slave.trust -= 1;
-							}
-							if (slave.vagina === 1) {
-								r.push(`It stretches ${his} tight cunt to soreness by the end of every day, so it also makes ${him} a little <span class="gold">less trusting</span> of you.`);
-								slave.trust -= 1;
+								r.push(`The big, long dildo in ${his} tight cunt`);
+								if (slave.sexualQuirk === "size queen") {
+									r.push(`is a <span class="hotpink">point of pride</span> for the ostentatious size queen.`);
+									slave.devotion += 2;
+								} else {
+									r.push(`<span class="hotpink">breaks ${him} to sexual slavery</span> slightly. It also penetrates ${his} cervix, causing ${him} tremendous discomfort, and making ${him} a little <span class="gold">less trusting</span> of you.`);
+									slave.devotion += 1;
+									slave.trust -= 1;
+								}
+								if (slave.vagina === 1) {
+									r.push(`It stretches ${his} tight cunt to soreness by the end of every day, so it also makes ${him} a little <span class="gold">less trusting</span> of you.`);
+									slave.trust -= 1;
+								}
 							}
 						}
 					}
 				}
-			} else if (slave.vaginalAccessory === "huge dildo") {
-				if (slave.vagina < 4) {
-					if (slave.fuckdoll === 0) {
-						if (slave.fetish !== "mindbroken") {
-							if (slave.sexualQuirk === "size queen") {
-								r.push(`${He} thinks of the massive dildo stretching out ${his} womanhood as <span class="lime">preparation for the biggest cocks,</span> and <span class="hotpink">looks forward</span> to take anything — dicks, hands, truly anything — inside ${his} newly capacious cunt.`);
-								slave.devotion += 4;
-							} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-								r.push(`${He} gets off on the agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
-								slave.devotion += 5;
-								slave.trust -= 5;
-							} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-								r.push(`${He} submits to the agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo. Having ${his} hole ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
-								slave.devotion += 5;
-								slave.trust -= 5;
-							} else {
-								r.push(`The agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
-								slave.devotion -= 5;
-								slave.trust -= 5;
+			} else if (dildo.width === 3) {
+				if (dildo.length === 1) {
+					if (slave.vagina < 4) {
+						if (slave.fuckdoll === 0) {
+							if (slave.fetish !== "mindbroken") {
+								if (slave.sexualQuirk === "size queen") {
+									r.push(`${He} thinks of the massive dildo stretching out ${his} womanhood as <span class="lime">preparation for the biggest cocks,</span> and <span class="hotpink">looks forward</span> to take anything — dicks, hands, truly anything — inside ${his} newly capacious cunt.`);
+									slave.devotion += 4;
+								} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+									r.push(`${He} gets off on the agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									slave.devotion += 5;
+									slave.trust -= 5;
+								} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+									r.push(`${He} submits to the agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo. Having ${his} hole ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									slave.devotion += 5;
+									slave.trust -= 5;
+								} else {
+									r.push(`The agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
+									slave.devotion -= 5;
+									slave.trust -= 5;
+								}
 							}
 						}
+						slave.vagina += 1;
+					} else {
+						r.push(`${His} cavernous pussy accommodates the huge dildo ${he}'s required to wear.`);
 					}
-					slave.vagina += 1;
-				} else {
-					r.push(`${His} cavernous pussy accommodates the huge dildo ${he}'s required to wear.`);
-				}
-			} else if (slave.vaginalAccessory === "long, huge dildo") {
-				if (slave.vagina < 4) {
-					if (slave.fuckdoll === 0) {
-						if (slave.fetish !== "mindbroken") {
-							if (slave.sexualQuirk === "size queen") {
-								r.push(`${He} thinks of the massive dildo stretching out ${his} womanhood and stomach as <span class="lime">preparation for the biggest cocks,</span> and <span class="hotpink">looks forward</span> to take anything — dicks, hands, arms, truly anything — inside ${his} newly capacious cunt.`);
-								slave.devotion += 4;
-							} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-								r.push(`${He} gets off on the agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
-								slave.devotion += 5;
-								slave.trust -= 5;
-							} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-								r.push(`${He} submits to the agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo. Having ${his} hole and cervix ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
-								slave.devotion += 5;
-								slave.trust -= 5;
-							} else {
-								r.push(`The agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
-								slave.devotion -= 5;
-								slave.trust -= 5;
+				} else  {
+					if (slave.vagina < 4) {
+						if (slave.fuckdoll === 0) {
+							if (slave.fetish !== "mindbroken") {
+								if (slave.sexualQuirk === "size queen") {
+									r.push(`${He} thinks of the massive dildo stretching out ${his} womanhood and stomach as <span class="lime">preparation for the biggest cocks,</span> and <span class="hotpink">looks forward</span> to take anything — dicks, hands, arms, truly anything — inside ${his} newly capacious cunt.`);
+									slave.devotion += 4;
+								} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+									r.push(`${He} gets off on the agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									slave.devotion += 5;
+									slave.trust -= 5;
+								} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+									r.push(`${He} submits to the agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo. Having ${his} hole and cervix ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									slave.devotion += 5;
+									slave.trust -= 5;
+								} else {
+									r.push(`The agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
+									slave.devotion -= 5;
+									slave.trust -= 5;
+								}
 							}
 						}
+						slave.vagina += 1;
+					} else {
+						r.push(`${His} cavernous pussy accommodates the huge dildo ${he}'s required to wear.`);
 					}
-					slave.vagina += 1;
-				} else {
-					r.push(`${His} cavernous pussy accommodates the huge dildo ${he}'s required to wear.`);
 				}
 			}
-			if (slave.vaginalAccessory === "long, huge dildo" || slave.vaginalAccessory === "long, large dildo" || slave.vaginalAccessory === "long dildo") {
+			if (dildo.length > 1) {
 				if ((slave.preg > slave.pregData.normalBirth / 10) && slave.pregKnown === 1) {
 					if (jsRandom(1, 100) > 50) {
 						r.push(`The dildo penetrating ${his} womb <span class="orange">caused ${him} to miscarry,</span> which <span class="health dec">damages ${his} health.</span>`);
diff --git a/src/endWeek/saLongTermPhysicalEffects.js b/src/endWeek/saLongTermPhysicalEffects.js
index b900d14cad38a796c175906622d970b80024d41e..c5238e801b77a78108b47354d897f669db6b1a41 100644
--- a/src/endWeek/saLongTermPhysicalEffects.js
+++ b/src/endWeek/saLongTermPhysicalEffects.js
@@ -233,7 +233,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 			if (slave.assignment !== "serve in the master suite" || V.masterSuiteUpgradeLuxury < 2) {
 				if (slave.assignment !== "work in the dairy" || V.dairyStimulatorsSetting === 0) {
 					if (slave.geneMods.rapidCellGrowth !== 1) {
-						if (slave.vagina >= 3 && !["huge dildo", "large dildo", "long, huge dildo", "long, large dildo"].includes(slave.vaginalAccessory)) {
+						if (slave.vagina >= 3 && dildoWidth(slave) < 2) {
 							r.push(`With a rest from strenuous use, <span class="improvement">${his} loose vagina recovers a little.</span>`);
 							slave.vagina -= 1;
 						} else if (slave.anus >= 3 && plugWidth(slave) < 2) {
diff --git a/src/endWeek/saSmartPiercingEffects.js b/src/endWeek/saSmartPiercingEffects.js
index 7b13bbba49b4293714d45b25fa80c3eee48c523c..56bdc815258f98808601d286cc9bf1c209807011 100644
--- a/src/endWeek/saSmartPiercingEffects.js
+++ b/src/endWeek/saSmartPiercingEffects.js
@@ -409,7 +409,7 @@ App.SlaveAssignment.SmartPiercing.sadist = class extends App.SlaveAssignment.Sma
 App.SlaveAssignment.saSmartPiercingEffects = function(slave) {
 	const {he, his, His, him} = getPronouns(slave);
 	const hasBV = slave.vaginalAccessory === "bullet vibrator" || slave.dickAccessory === "bullet vibrator";
-	const hasSmartBV = slave.vaginalAccessory === "smart bullet vibrator" || slave.dickAccessory === "smart bullet vibrator";
+	const hasSmartBV = dildoVibeLevel(slave) > 1 || slave.dickAccessory === "smart bullet vibrator";
 	const hasDildoVibe = slave.vaginalAttachment === "vibrator";
 	const hasSmartDildoVibe = slave.vaginalAttachment === "smart vibrator";
 	const hasSP = slave.clitPiercing === 3;
diff --git a/src/interaction/main/walkPast.js b/src/interaction/main/walkPast.js
index 516e06e3e8e2d7ac1e6af9de0ef477bf78c4d90e..4e7e2a8267e464aa028447e84de82fe004130a71 100644
--- a/src/interaction/main/walkPast.js
+++ b/src/interaction/main/walkPast.js
@@ -8374,7 +8374,7 @@ globalThis.walkPast = (function() {
 					t += `You get a good view of ${his} pussy.`;
 				}
 		}
-		if ((slave.vaginalAccessory === "long dildo") || (slave.vaginalAccessory === "long, large dildo") || (slave.vaginalAccessory === "long, huge dildo")) {
+		if (dildoLength(slave) > 1) {
 			t += `With every motion ${he} makes, ${his} dildo shifts, bulging out ${his} stomach.`;
 			if (plugLength(slave) > 1) {
 				t += `Beside it, a second bulge caused by ${his} extra long buttplug.`;
@@ -8964,7 +8964,7 @@ globalThis.walkPast = (function() {
 					t += `You get a good view of ${his} pussy.`;
 				}
 		}
-		if ((slave.vaginalAccessory === "long dildo") || (slave.vaginalAccessory === "long, large dildo") || (slave.vaginalAccessory === "long, huge dildo")) {
+		if (dildoLength(slave) > 1) {
 			t += `With every motion ${he} makes, ${his} dildo shifts, bulging out ${his} stomach.`;
 			if (plugLength(slave) > 1) {
 				t += `Beside it, a second bulge caused by ${his} extra long buttplug.`;
diff --git a/src/interaction/siRules.js b/src/interaction/siRules.js
index b5e02a194109390fe129440b443977390d131e8e..2d96e64db46a466810f4c76f21e32b5591372196 100644
--- a/src/interaction/siRules.js
+++ b/src/interaction/siRules.js
@@ -374,7 +374,7 @@ App.UI.SlaveInteract.rules = function(slave) {
 
 	function smartSettings(slave) {
 		let el = document.createElement('div');
-		const smartBulletVibe = slave.vaginalAccessory === "smart bullet vibrator" || slave.dickAccessory === "smart bullet vibrator";
+		const smartBulletVibe = dildoVibeLevel(slave) > 1 || slave.dickAccessory === "smart bullet vibrator";
 		const smartDildoVibe = slave.vaginalAttachment === "smart vibrator";
 
 		if (slave.clitPiercing === 3 || smartBulletVibe || smartDildoVibe) {
diff --git a/src/interaction/siWardrobe.js b/src/interaction/siWardrobe.js
index aeb67b22c3633c317b48f98fb9f3947f6eff0c20..41862a1791f9738bf707c76fd7f30657003b01a2 100644
--- a/src/interaction/siWardrobe.js
+++ b/src/interaction/siWardrobe.js
@@ -588,9 +588,11 @@ App.UI.SlaveInteract.wardrobe = function(slave) {
 		}
 		el.appendChild(label);
 
-		let optionsArray = [];
+		let bulletArray = [];
+		let normalArray = [];
+		let longArray = [];
 
-		for (const [key, object] of App.Data.slaveWear.vaginalAccessories) {
+		for (const [key, object] of App.Data.vaginalAccessories) {
 			if (key === "none") {
 				// skip none in set, we set the link elsewhere.
 				continue;
@@ -600,24 +602,29 @@ App.UI.SlaveInteract.wardrobe = function(slave) {
 				updateSlave: {vaginalAccessory: key},
 				FS: object.fs,
 			};
-			optionsArray.push(reshapedItem);
+			if (object.width === 0) {
+				bulletArray.push(reshapedItem);
+			} else if (object.length > 1) {
+				longArray.push(reshapedItem);
+			} else {
+				normalArray.push(reshapedItem);
+			}
 		}
 
 		// Sort
 		// No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1);
 
 		// Options
-		let links = document.createElement('div');
-		links.className = "choices";
-		links.appendChild(generateRows(optionsArray, "vaginalAccessory", true));
-		el.appendChild(links);
+		App.UI.DOM.appendNewElement("div", el, generateRows(bulletArray, "vaginalAccessory", true), "choices");
+		App.UI.DOM.appendNewElement("div", el, generateRows(normalArray, "vaginalAccessory", true), "choices");
+		App.UI.DOM.appendNewElement("div", el, generateRows(longArray, "vaginalAccessory", true), "choices");
 
 		return el;
 	}
 
 	function vaginalAttachment() {
 		let el = document.createElement('div');
-		if (["none", "bullet vibrator", "smart bullet vibrator"].includes(slave.vaginalAccessory)) {
+		if (dildoWidth(slave) === 0) {
 			return el;
 		}
 
diff --git a/src/js/itemAvailability.js b/src/js/itemAvailability.js
index d8975c4fcb1d77997979d22ff243bb5cce4960ca..67115860977d7e917be75ed6a895fc493460a6ad 100644
--- a/src/js/itemAvailability.js
+++ b/src/js/itemAvailability.js
@@ -34,7 +34,7 @@ globalThis.isItemAccessible = (function() {
 				selectedDB = App.Data.slaveWear.buttplugAttachments;
 				break;
 			case "vaginalAccessory":
-				selectedDB = App.Data.slaveWear.vaginalAccessories;
+				selectedDB = App.Data.vaginalAccessories;
 				break;
 			case "vaginalAttachment":
 				selectedDB = App.Data.slaveWear.vaginalAttachments;
@@ -224,7 +224,9 @@ globalThis.isItemAccessible = (function() {
 					case "vibrator":
 						if (slave.vaginalAccessory === "none") {
 							return "No vaginal accessory to attach it to";
-						} else if (slave.vaginalAccessory === "bullet vibrator" || slave.vaginalAccessory === "smart bullet vibrator") {
+						} else if (dildoWidth(slave) === 0) {
+							return "Vaginal accessory is too small";
+						} else if (dildoVibeLevel(slave)) {
 							return "Vaginal accessory already vibrates";
 						} else {
 							return true;
diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js
index 294b86564f30c9595c969fb68c540dbb72a02da9..23c59b39e43381f354f08f40a589136c55afc656 100644
--- a/src/js/rulesAssistantOptions.js
+++ b/src/js/rulesAssistantOptions.js
@@ -1928,7 +1928,7 @@ App.RA.options = (function() {
 
 	class VagAccVirginsList extends ListSelector {
 		constructor() {
-			super("Vaginal accessories for virgins", isItemAccessible.array(App.Data.slaveWear.vaginalAccessories));
+			super("Vaginal accessories for virgins", isItemAccessible.array(App.Data.vaginalAccessories));
 			this.setValue(current_rule.set.virginAccessory);
 			this.onchange = (value) => current_rule.set.virginAccessory = value;
 		}
@@ -1936,7 +1936,7 @@ App.RA.options = (function() {
 
 	class VagAccAVirginsList extends ListSelector {
 		constructor() {
-			super("Vaginal accessories for anal virgins", isItemAccessible.array(App.Data.slaveWear.vaginalAccessories));
+			super("Vaginal accessories for anal virgins", isItemAccessible.array(App.Data.vaginalAccessories));
 			this.setValue(current_rule.set.aVirginAccessory);
 			this.onchange = (value) => current_rule.set.aVirginAccessory = value;
 		}
@@ -1944,7 +1944,7 @@ App.RA.options = (function() {
 
 	class VagAccOtherList extends ListSelector {
 		constructor() {
-			super("Vaginal accessories for other slaves", isItemAccessible.array(App.Data.slaveWear.vaginalAccessories));
+			super("Vaginal accessories for other slaves", isItemAccessible.array(App.Data.vaginalAccessories));
 			this.setValue(current_rule.set.vaginalAccessory);
 			this.onchange = (value) => current_rule.set.vaginalAccessory = value;
 		}
diff --git a/src/js/utilsAssessSlave.js b/src/js/utilsAssessSlave.js
index 5dfda9f45376541bcf3a49cdc56a67136472f72a..acd47c0bf2b31895bb19c12194c6ace86138ab20 100644
--- a/src/js/utilsAssessSlave.js
+++ b/src/js/utilsAssessSlave.js
@@ -285,5 +285,29 @@ globalThis.plugLength = function(slave) {
 	return App.Data.buttplugs.get(slave.buttplug) ? App.Data.buttplugs.get(slave.buttplug).length : 0;
 };
 
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {0|1|2|3}
+ */
+globalThis.dildoWidth = function(slave) {
+	const dildo = App.Data.vaginalAccessories.get(slave.vaginalAccessory) || V.customItem.vaginalAccessories.get(slave.vaginalAccessory);
+	return dildo.width || 0;
+};
 
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {0|1|2}
+ */
+globalThis.dildoLength = function(slave) {
+	const dildo = App.Data.vaginalAccessories.get(slave.vaginalAccessory) || V.customItem.vaginalAccessories.get(slave.vaginalAccessory);
+	return dildo.length || 0;
+};
 
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {number}
+ */
+globalThis.dildoVibeLevel = function(slave) {
+	const dildo = App.Data.vaginalAccessories.get(slave.vaginalAccessory) || V.customItem.vaginalAccessories.get(slave.vaginalAccessory);
+	return dildo.vibrates || 0;
+};
diff --git a/src/npc/descriptions/crotch/vaginalAccessory.js b/src/npc/descriptions/crotch/vaginalAccessory.js
index 847437102c87cd652268f90f032854b154cf3911..8d98cadd1b8e07fe68047bb50e9f169613091d22 100644
--- a/src/npc/descriptions/crotch/vaginalAccessory.js
+++ b/src/npc/descriptions/crotch/vaginalAccessory.js
@@ -10,35 +10,25 @@ App.Desc.vaginalAccessory = function(slave) {
 	let held;
 	if (slave.chastityVagina) {
 		held = "held in place by a chastity belt";
-	} else if (slave.vaginalAccessory === "bullet vibrator" || slave.vaginalAccessory === "smart bullet vibrator") {
+	} else if (dildoWidth(slave) === 0) {
 		held = "held in place by a strap";
 	} else {
 		held = `held in place by a strap, which ${he} can remove for vaginal intercourse`;
 	}
-	switch (slave.vaginalAccessory) {
-		case "bullet vibrator":
-		case "smart bullet vibrator":	// FIXME: two different descriptions?
-			r.push(`A bullet vibrator is attached on ${his} clit, ${held}.`);	// FIXME: not super happy with this
+	const dildo = App.Data.vaginalAccessories.get(slave.vaginalAccessory) || V.customItem.vaginalAccessories.get(slave.vaginalAccessory);
+	switch (dildo.width) {
+		case 0:
+			r.push(`A ${slave.vaginalAccessory} is attached on ${his} clit, ${held}.`);	// FIXME: not super happy with this
 			break;
-		case "dildo":
-			/* TODO: these may need to be updated for slaves with gaping+ vaginas */
-			r.push(`${His} pussy is filled by a dildo ${held}.`);
-			break;
-		case "long dildo":
-			r.push(`${His} pussy is filled by a very long dildo ${held}. It noticeably bulges ${his} stomach.`);
-			break;
-		case "large dildo":
-			r.push(`${His} pussy is`);
-			if (slave.vagina < 2) {
-				r.push(`painfully stretched`);
-			} else if (slave.vagina < 3) {
-				r.push(`uncomfortably filled`);
+		case 1:
+			if (dildo.length === 1) {
+				/* TODO: these may need to be updated for slaves with gaping+ vaginas */
+				r.push(`${His} pussy is filled by a dildo ${held}.`);
 			} else {
-				r.push(`comfortably filled`);
+				r.push(`${His} pussy is filled by a very long dildo ${held}. It noticeably bulges ${his} stomach.`);
 			}
-			r.push(`by a large dildo ${held}.`);
 			break;
-		case "long, large dildo":
+		case 2:
 			r.push(`${His} pussy is`);
 			if (slave.vagina < 2) {
 				r.push(`painfully stretched`);
@@ -47,33 +37,35 @@ App.Desc.vaginalAccessory = function(slave) {
 			} else {
 				r.push(`comfortably filled`);
 			}
-			r.push(`by a very long and large dildo ${held}. It noticeably bulges ${his} stomach.`);
-			break;
-		case "huge dildo":
-			if (slave.vagina < 4) {
-				r.push(`${His} pussy is filled to the breaking point by an enormous dildo.`);
-				if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-					r.push(`${He} can barely move with the discomfort, but ${he} frequently climaxes with agony.`);
-				} else {
-					r.push(`${He} can barely move with the discomfort, and ${he} sometimes breaks down in tears at having ${his} cunt permanently stretched.`);
-				}
+			if (dildo.length === 1) {
+				r.push(`by a large dildo ${held}.`);
 			} else {
-				r.push(`${His} cavernous pussy is comfortably filled by a huge dildo.`);
-			}
-			if (slave.chastityVagina) {
-				r.push(`A chastity belt locks it securely in place.`);
+				r.push(`by a very long and large dildo ${held}. It noticeably bulges ${his} stomach.`);
 			}
 			break;
-		case "long, huge dildo":
-			if (slave.vagina < 4) {
-				r.push(`${His} pussy is filled to the breaking point by an enormously wide and long dildo. It noticeably bulges ${his} stomach.`);
-				if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-					r.push(`${He} can barely move with the discomfort, but ${he} frequently climaxes with agony.`);
+		case 3:
+			if (dildo.length === 1) {
+				if (slave.vagina < 4) {
+					r.push(`${His} pussy is filled to the breaking point by an enormous dildo.`);
+					if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+						r.push(`${He} can barely move with the discomfort, but ${he} frequently climaxes with agony.`);
+					} else {
+						r.push(`${He} can barely move with the discomfort, and ${he} sometimes breaks down in tears at having ${his} cunt permanently stretched.`);
+					}
 				} else {
-					r.push(`${He} can barely move with the discomfort, and ${he} sometimes breaks down in tears at having ${his} cunt permanently stretched.`);
+					r.push(`${His} cavernous pussy is comfortably filled by a huge dildo.`);
 				}
 			} else {
-				r.push(`${His} cavernous pussy is comfortably filled by an enormously wide and long dildo. It noticeably bulges ${his} stomach.`);
+				if (slave.vagina < 4) {
+					r.push(`${His} pussy is filled to the breaking point by an enormously wide and long dildo. It noticeably bulges ${his} stomach.`);
+					if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+						r.push(`${He} can barely move with the discomfort, but ${he} frequently climaxes with agony.`);
+					} else {
+						r.push(`${He} can barely move with the discomfort, and ${he} sometimes breaks down in tears at having ${his} cunt permanently stretched.`);
+					}
+				} else {
+					r.push(`${His} cavernous pussy is comfortably filled by an enormously wide and long dildo. It noticeably bulges ${his} stomach.`);
+				}
 			}
 			if (slave.chastityVagina) {
 				r.push(`A chastity belt locks it securely in place.`);
@@ -107,27 +99,25 @@ App.Desc.vaginalAttachment = function(slave) {
 	const {
 		his, He, His
 	} = getPronouns(slave);
-	switch (slave.vaginalAttachment) {
-		case "vibrator":
+	switch (dildoVibeLevel(slave)) {
+		case 2:
 			// TODO: not sure about this description
-			r.push(`${He} looks distinctly uncomfortable as ${his} dildo buzzes every so often.`);
+			r.push(`${His} dildo buzzes every so often, when prompted by the arcology's systems to train ${his} sexuality.`);
 			if (slave.chastityVagina) {
 				r.push(`The chastity belt locking it in place means there is no escape.`);
 			}
 			// TODO: add descriptions for slaves with gaping+ vaginas
 			break;
-		case "smart vibrator":
+		case 1:
 			// TODO: not sure about this description
-			r.push(`${His} dildo buzzes every so often, when prompted by the arcology's systems to train ${his} sexuality.`);
+			r.push(`${He} looks distinctly uncomfortable as ${his} dildo buzzes every so often.`);
 			if (slave.chastityVagina) {
 				r.push(`The chastity belt locking it in place means there is no escape.`);
 			}
 			// TODO: add descriptions for slaves with gaping+ vaginas
 			break;
-		default:
-			if (!(["none", "bullet vibrator", "smart bullet vibrator"].includes(slave.vaginalAccessory))) {
-				r.push(`${His} current accessory is silent.`);
-			}
+		case 0:
+			r.push(`${His} current accessory is silent.`);
 	}
 	return r.join(" ");
 };