diff --git a/game/base-clothing.js b/game/base-clothing.js
new file mode 100644
index 0000000000000000000000000000000000000000..f849491b743362d2fb0e0eee2cfc25951956e2c6
--- /dev/null
+++ b/game/base-clothing.js
@@ -0,0 +1,51 @@
+function underintegrity(){
+	var output='';
+	var V = State.variables;
+	if (V.underintegritymax !== 0) {
+		if (V.underintegrity <= (V.underintegritymax / 10) * 2) {
+			output += "tattered \t";
+		} else if (V.underintegrity <= (V.underintegritymax / 10) * 5) {
+			output += "torn \t";
+		} else if (V.underintegrity <= (V.underintegritymax / 10) * 9) {
+			output += "frayed \t";
+		} else {
+		}
+	}
+	return output;
+}
+DefineMacroS("underintegrity", underintegrity);
+
+function lowerintegrity(){
+	var output='';
+	var V = State.variables;
+	if (V.lowerintegritymax !== 0) {
+		if (V.lowerintegrity <= (V.lowerintegritymax / 10) * 2) {
+			output += "tattered \t";
+		} else if (V.lowerintegrity <= (V.lowerintegritymax / 10) * 5) {
+			output += "torn \t";
+		} else if (V.lowerintegrity <= (V.lowerintegritymax / 10) * 9) {
+			output += "frayed \t";
+		} else {
+		}
+	}
+	return output;
+}
+DefineMacroS("lowerintegrity", lowerintegrity);
+
+function upperintegrity(){
+	var output='';
+	var V = State.variables;
+	if (V.upperintegritymax !== 0) {
+		if (V.upperintegrity <= (V.upperintegritymax / 10) * 2) {
+			output += "tattered \t";
+		} else if (V.upperintegrity <= (V.upperintegritymax / 10) * 5) {
+			output += "torn \t";
+		} else if (V.upperintegrity <= (V.upperintegritymax / 10) * 9) {
+			output += "frayed \t";
+		} else {
+		}
+	}
+	return output;
+}
+DefineMacroS("upperintegrity", upperintegrity);
+
diff --git a/game/base-clothing.twee b/game/base-clothing.twee
index 64375afa11d7c068804bfa281b0b9a7621544bb9..7bfe6fba44ec95d0b80d2f5db5b3ea82feff1384 100644
--- a/game/base-clothing.twee
+++ b/game/base-clothing.twee
@@ -3625,51 +3625,6 @@ You are conscious of your <<nuditystop>><br><br>
 
 
 
-:: Widgets Integrity [widget]
-<<widget "underintegrity">><<nobr>>
-
-<<if $underintegritymax isnot 0>>
-	<<if $underintegrity lte ($underintegritymax / 10) * 2>>tattered
-	<<elseif $underintegrity lte ($underintegritymax / 10) * 5>>torn
-	<<elseif $underintegrity lte ($underintegritymax / 10) * 9>>frayed
-	<<else>>
-	<</if>>
-<</if>>
-
-<</nobr>><</widget>>
-
-
-<<widget "lowerintegrity">><<nobr>>
-
-<<if $lowerintegritymax isnot 0>>
-	<<if $lowerintegrity lte ($lowerintegritymax / 10) * 2>>tattered
-	<<elseif $lowerintegrity lte ($lowerintegritymax / 10) * 5>>torn
-	<<elseif $lowerintegrity lte ($lowerintegritymax / 10) * 9>>frayed
-	<<else>>
-	<</if>>
-<</if>>
-
-<</nobr>><</widget>>
-
-
-<<widget "upperintegrity">><<nobr>>
-
-<<if $upperintegritymax isnot 0>>
-	<<if $upperintegrity lte ($upperintegritymax / 10) * 2>>tattered
-	<<elseif $upperintegrity lte ($upperintegritymax / 10) * 5>>torn
-	<<elseif $upperintegrity lte ($upperintegritymax / 10) * 9>>frayed
-	<<else>>
-	<</if>>
-<</if>>
-
-<</nobr>><</widget>>
-
-
-
-
-
-
-
 :: Clothing Rebuy [nobr]
 <<set $outside to 0>><<effects>>
 
diff --git a/game/globals.js b/game/globals.js
new file mode 100644
index 0000000000000000000000000000000000000000..48aa4a17379daea36784600f8945abd12a056588
--- /dev/null
+++ b/game/globals.js
@@ -0,0 +1,21 @@
+function DefineMacro(macroName, macroFunction) {
+	Macro.add(macroName, { isWidget: true, handler: function() {
+		var oldArgs = State.variables.args;
+		State.variables.args = this.args.slice();
+		macroFunction.apply(this, this.args);
+		if (typeof oldArgs === 'undefined') {
+			delete State.variables.args;
+		} else {
+			State.variables.args = oldArgs;
+		}
+	} });
+}
+
+/**
+ * Define macro, where macroFunction returns text to wikify & print
+ */
+function DefineMacroS(macroName, macroFunction) {
+	DefineMacro(macroName, function() {
+		$(this.output).wiki(macroFunction.apply(null,this.args))
+	});
+}
\ No newline at end of file