diff --git a/src/game/formulas.ts b/src/game/formulas.ts
index 7453c05..6b183e0 100644
--- a/src/game/formulas.ts
+++ b/src/game/formulas.ts
@@ -1,5 +1,5 @@
 import Decimal, { DecimalSource } from "util/bignum";
-import { ProcessedComputable } from "util/computed";
+import { Computable, convertComputable, ProcessedComputable } from "util/computed";
 import { ref, Ref, unref } from "vue";
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -439,26 +439,27 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
      * @param start The value at which to start applying the step
      * @param formulaModifier How this step should modify the formula. The incoming value will be the unmodified formula value _minus the start value_. So for example if an incoming formula evaluates to 200 and has a step that starts at 150, the formulaModifier would be given 50 as the parameter
      */
-    public static step<T extends FormulaSource>(
-        value: T,
-        start: ProcessedComputable<DecimalSource>,
+    public static step(
+        value: FormulaSource,
+        start: Computable<DecimalSource>,
         formulaModifier: (value: Ref<DecimalSource>) => GenericFormula
     ) {
         const lhsRef = ref<DecimalSource>(0);
         const formula = formulaModifier(lhsRef);
+        const processedStart = convertComputable(start);
         function evalStep(lhs: DecimalSource) {
-            if (Decimal.lt(lhs, unref(start))) {
+            if (Decimal.lt(lhs, unref(processedStart))) {
                 return lhs;
             }
-            lhsRef.value = Decimal.sub(lhs, unref(start));
-            return Decimal.add(formula.evaluate(), unref(start));
+            lhsRef.value = Decimal.sub(lhs, unref(processedStart));
+            return Decimal.add(formula.evaluate(), unref(processedStart));
         }
         function invertStep(value: DecimalSource, lhs: FormulaSource) {
             if (hasVariable(lhs)) {
-                if (Decimal.gt(value, unref(start))) {
+                if (Decimal.gt(value, unref(processedStart))) {
                     value = Decimal.add(
-                        formula.invert(Decimal.sub(value, unref(start))),
-                        unref(start)
+                        formula.invert(Decimal.sub(value, unref(processedStart))),
+                        unref(processedStart)
                     );
                 }
                 return lhs.invert(value);
@@ -472,6 +473,46 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
         );
     }
 
+    public static if(
+        value: FormulaSource,
+        condition: Computable<boolean>,
+        formulaModifier: (value: Ref<DecimalSource>) => GenericFormula
+    ) {
+        const lhsRef = ref<DecimalSource>(0);
+        const formula = formulaModifier(lhsRef);
+        const processedCondition = convertComputable(condition);
+        function evalStep(lhs: DecimalSource) {
+            if (unref(processedCondition)) {
+                lhsRef.value = lhs;
+                return formula.evaluate();
+            } else {
+                return lhs;
+            }
+        }
+        function invertStep(value: DecimalSource, lhs: FormulaSource) {
+            if (!hasVariable(lhs)) {
+                throw "Could not invert due to no input being a variable";
+            }
+            if (unref(processedCondition)) {
+                return lhs.invert(formula.invert(value));
+            } else {
+                return lhs.invert(value);
+            }
+        }
+        return new Formula(
+            [value],
+            evalStep,
+            formula.isInvertible() && !formula.hasVariable() ? invertStep : undefined
+        );
+    }
+    public static conditional(
+        value: FormulaSource,
+        condition: Computable<boolean>,
+        formulaModifier: (value: Ref<DecimalSource>) => GenericFormula
+    ) {
+        return Formula.if(value, condition, formulaModifier);
+    }
+
     public static constant(value: InvertibleFormulaSource): InvertibleFormula {
         return new Formula([value]) as InvertibleFormula;
     }
diff --git a/tests/game/formulas.test.ts b/tests/game/formulas.test.ts
index cb5f4d4..a998e26 100644
--- a/tests/game/formulas.test.ts
+++ b/tests/game/formulas.test.ts
@@ -530,3 +530,58 @@ describe("Step-wise", () => {
             ).compare_tolerance(10));
     });
 });
+
+describe("Conditionals", () => {
+    let variable: GenericFormula;
+    let constant: GenericFormula;
+    beforeAll(() => {
+        variable = Formula.variable(10);
+        constant = Formula.constant(10);
+    });
+
+    test("Formula without variable is marked as such", () => {
+        expect(Formula.if(constant, true, value => Formula.sqrt(value)).isInvertible()).toBe(true);
+        expect(Formula.if(constant, true, value => Formula.sqrt(value)).hasVariable()).toBe(false);
+    });
+
+    test("Formula with variable is marked as such", () => {
+        expect(Formula.if(variable, true, value => Formula.sqrt(value)).isInvertible()).toBe(true);
+        expect(Formula.if(variable, true, value => Formula.sqrt(value)).hasVariable()).toBe(true);
+    });
+
+    test("Non-invertible formula modifier marks formula as such", () => {
+        expect(Formula.if(constant, true, value => Formula.abs(value)).isInvertible()).toBe(false);
+        expect(Formula.if(constant, true, value => Formula.abs(value)).hasVariable()).toBe(false);
+    });
+
+    test("Formula modifiers with variables mark formula as non-invertible", () => {
+        expect(
+            Formula.if(constant, true, value => Formula.add(value, variable)).isInvertible()
+        ).toBe(false);
+        expect(
+            Formula.if(constant, true, value => Formula.add(value, variable)).hasVariable()
+        ).toBe(false);
+    });
+
+    describe("Pass-through with condition false", () => {
+        test("Evaluates correctly", () =>
+            expect(
+                Formula.if(constant, false, value => Formula.sqrt(value)).evaluate()
+            ).compare_tolerance(10));
+        test("Inverts correctly with variable in input", () =>
+            expect(
+                Formula.if(variable, false, value => Formula.sqrt(value)).invert(10)
+            ).compare_tolerance(10));
+    });
+
+    describe("Evaluates correctly with condition true", () => {
+        test("Evaluates correctly", () =>
+            expect(
+                Formula.if(variable, true, value => Formula.add(value, 2)).evaluate()
+            ).compare_tolerance(12));
+        test("Inverts correctly", () =>
+            expect(
+                Formula.if(variable, true, value => Formula.add(value, 2)).invert(12)
+            ).compare_tolerance(10));
+    });
+});