diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3ced052..4fa0c76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
     - Requires referencing persistent refs either through a proxy or by wrapping in `noPersist()`
 - **BREAKING** Visibility properties can now take booleans
     - Removed showIf util
+- **BREAKING** Lazy proxies and options functions now pass the base object in as `this` as well as the first parameter.
 - Tweaked settings display
 - setupPassiveGeneration will no longer lower the resource
 - displayResource now floors resource amounts
diff --git a/src/data/common.tsx b/src/data/common.tsx
index 304208b..ab33aa6 100644
--- a/src/data/common.tsx
+++ b/src/data/common.tsx
@@ -5,11 +5,10 @@ import { createClickable } from "features/clickables/clickable";
 import type { GenericConversion } from "features/conversion";
 import type { CoercableComponent, JSXFunction, OptionsFunc, Replace } from "features/feature";
 import { jsx, setDefault } from "features/feature";
-import { displayResource, Resource } from "features/resources/resource";
+import { Resource, displayResource } from "features/resources/resource";
 import type { GenericTree, GenericTreeNode, TreeNode, TreeNodeOptions } from "features/trees/tree";
 import { createTreeNode } from "features/trees/tree";
-import Formula from "game/formulas/formulas";
-import type { FormulaSource, GenericFormula } from "game/formulas/types";
+import type { GenericFormula } from "game/formulas/types";
 import type { Modifier } from "game/modifiers";
 import type { Persistent } from "game/persistence";
 import { DefaultValue, persistent } from "game/persistence";
@@ -99,8 +98,8 @@ export type GenericResetButton = Replace<
 export function createResetButton<T extends ClickableOptions & ResetButtonOptions>(
     optionsFunc: OptionsFunc<T>
 ): ResetButton<T> {
-    return createClickable(() => {
-        const resetButton = optionsFunc();
+    return createClickable(feature => {
+        const resetButton = optionsFunc.call(feature, feature);
 
         processComputable(resetButton as T, "showNextAt");
         setDefault(resetButton, "showNextAt", true);
@@ -213,8 +212,8 @@ export type GenericLayerTreeNode = Replace<
 export function createLayerTreeNode<T extends LayerTreeNodeOptions>(
     optionsFunc: OptionsFunc<T>
 ): LayerTreeNode<T> {
-    return createTreeNode(() => {
-        const options = optionsFunc();
+    return createTreeNode(feature => {
+        const options = optionsFunc.call(feature, feature);
         processComputable(options as T, "display");
         setDefault(options, "display", options.layerID);
         processComputable(options as T, "append");
diff --git a/src/features/achievements/achievement.tsx b/src/features/achievements/achievement.tsx
index 07292a0..3af6650 100644
--- a/src/features/achievements/achievement.tsx
+++ b/src/features/achievements/achievement.tsx
@@ -143,8 +143,10 @@ export function createAchievement<T extends AchievementOptions>(
 ): Achievement<T> {
     const earned = persistent<boolean>(false, false);
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const achievement = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>);
+    return createLazyProxy(feature => {
+        const achievement =
+            optionsFunc?.call(feature, feature) ??
+            ({} as ReturnType<NonNullable<typeof optionsFunc>>);
         achievement.id = getUniqueID("achievement-");
         achievement.type = AchievementType;
         achievement[Component] = AchievementComponent as GenericComponent;
diff --git a/src/features/action.tsx b/src/features/action.tsx
index 1f601bb..3b15756 100644
--- a/src/features/action.tsx
+++ b/src/features/action.tsx
@@ -108,8 +108,10 @@ export function createAction<T extends ActionOptions>(
 ): Action<T> {
     const progress = persistent<DecimalSource>(0);
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const action = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>);
+    return createLazyProxy(feature => {
+        const action =
+            optionsFunc?.call(feature, feature) ??
+            ({} as ReturnType<NonNullable<typeof optionsFunc>>);
         action.id = getUniqueID("action-");
         action.type = ActionType;
         action[Component] = ClickableComponent as GenericComponent;
diff --git a/src/features/bars/bar.ts b/src/features/bars/bar.ts
index 025d782..32e45c6 100644
--- a/src/features/bars/bar.ts
+++ b/src/features/bars/bar.ts
@@ -106,8 +106,8 @@ export function createBar<T extends BarOptions>(
     ...decorators: Decorator<T, BaseBar, GenericBar>[]
 ): Bar<T> {
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const bar = optionsFunc();
+    return createLazyProxy(feature => {
+        const bar = optionsFunc.call(feature, feature);
         bar.id = getUniqueID("bar-");
         bar.type = BarType;
         bar[Component] = BarComponent as GenericComponent;
diff --git a/src/features/boards/board.ts b/src/features/boards/board.ts
index b8f66b4..e10bf67 100644
--- a/src/features/boards/board.ts
+++ b/src/features/boards/board.ts
@@ -297,8 +297,8 @@ export function createBoard<T extends BoardOptions>(
         false
     );
 
-    return createLazyProxy(() => {
-        const board = optionsFunc();
+    return createLazyProxy(feature => {
+        const board = optionsFunc.call(feature, feature);
         board.id = getUniqueID("board-");
         board.type = BoardType;
         board[Component] = BoardComponent as GenericComponent;
diff --git a/src/features/challenges/challenge.tsx b/src/features/challenges/challenge.tsx
index a30bf17..095b15a 100644
--- a/src/features/challenges/challenge.tsx
+++ b/src/features/challenges/challenge.tsx
@@ -155,8 +155,8 @@ export function createChallenge<T extends ChallengeOptions>(
     const completions = persistent(0);
     const active = persistent(false, false);
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const challenge = optionsFunc();
+    return createLazyProxy(feature => {
+        const challenge = optionsFunc.call(feature, feature);
 
         challenge.id = getUniqueID("challenge-");
         challenge.type = ChallengeType;
diff --git a/src/features/clickables/clickable.ts b/src/features/clickables/clickable.ts
index d96dd47..0da6fda 100644
--- a/src/features/clickables/clickable.ts
+++ b/src/features/clickables/clickable.ts
@@ -100,8 +100,10 @@ export function createClickable<T extends ClickableOptions>(
     ...decorators: Decorator<T, BaseClickable, GenericClickable>[]
 ): Clickable<T> {
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const clickable = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>);
+    return createLazyProxy(feature => {
+        const clickable =
+            optionsFunc?.call(feature, feature) ??
+            ({} as ReturnType<NonNullable<typeof optionsFunc>>);
         clickable.id = getUniqueID("clickable-");
         clickable.type = ClickableType;
         clickable[Component] = ClickableComponent as GenericComponent;
diff --git a/src/features/conversion.ts b/src/features/conversion.ts
index 7732c42..41b7f32 100644
--- a/src/features/conversion.ts
+++ b/src/features/conversion.ts
@@ -127,8 +127,8 @@ export function createConversion<T extends ConversionOptions>(
     optionsFunc: OptionsFunc<T, BaseConversion, GenericConversion>,
     ...decorators: Decorator<T, BaseConversion, GenericConversion>[]
 ): Conversion<T> {
-    return createLazyProxy(() => {
-        const conversion = optionsFunc();
+    return createLazyProxy(feature => {
+        const conversion = optionsFunc.call(feature, feature);
 
         for (const decorator of decorators) {
             decorator.preConstruct?.(conversion);
@@ -221,8 +221,8 @@ export function createCumulativeConversion<S extends ConversionOptions>(
 export function createIndependentConversion<S extends ConversionOptions>(
     optionsFunc: OptionsFunc<S, BaseConversion, GenericConversion>
 ): Conversion<S> {
-    return createConversion(() => {
-        const conversion: S = optionsFunc();
+    return createConversion(feature => {
+        const conversion: S = optionsFunc.call(feature, feature);
 
         setDefault(conversion, "buyMax", false);
 
diff --git a/src/features/feature.ts b/src/features/feature.ts
index 082376c..2bd1fad 100644
--- a/src/features/feature.ts
+++ b/src/features/feature.ts
@@ -42,9 +42,9 @@ export type Replace<T, S> = S & Omit<T, keyof S>;
  * with "this" bound to what the type will eventually be processed into.
  * Intended for making lazily evaluated objects.
  */
-export type OptionsFunc<T, R = Record<string, unknown>, S = R> = () => OptionsObject<T,R,S>;
+export type OptionsFunc<T, R = unknown, S = R> = (obj: R) => OptionsObject<T,R,S>;
 
-export type OptionsObject<T, R = Record<string, unknown>, S = R> = T & Partial<R> & ThisType<T & S>;
+export type OptionsObject<T, R = unknown, S = R> = T & Partial<R> & ThisType<T & S>;
 
 let id = 0;
 /**
diff --git a/src/features/grids/grid.ts b/src/features/grids/grid.ts
index 57eb399..454bbfc 100644
--- a/src/features/grids/grid.ts
+++ b/src/features/grids/grid.ts
@@ -307,8 +307,8 @@ export function createGrid<T extends GridOptions>(
     optionsFunc: OptionsFunc<T, BaseGrid, GenericGrid>
 ): Grid<T> {
     const cellState = persistent<Record<string | number, State>>({}, false);
-    return createLazyProxy(() => {
-        const grid = optionsFunc();
+    return createLazyProxy(feature => {
+        const grid = optionsFunc.call(feature, feature);
         grid.id = getUniqueID("grid-");
         grid[Component] = GridComponent as GenericComponent;
 
diff --git a/src/features/hotkey.tsx b/src/features/hotkey.tsx
index dcfdade..51fafbb 100644
--- a/src/features/hotkey.tsx
+++ b/src/features/hotkey.tsx
@@ -68,8 +68,8 @@ const uppercaseNumbers = [")", "!", "@", "#", "$", "%", "^", "&", "*", "("];
 export function createHotkey<T extends HotkeyOptions>(
     optionsFunc: OptionsFunc<T, BaseHotkey, GenericHotkey>
 ): Hotkey<T> {
-    return createLazyProxy(() => {
-        const hotkey = optionsFunc();
+    return createLazyProxy(feature => {
+        const hotkey = optionsFunc.call(feature, feature);
         hotkey.type = HotkeyType;
 
         processComputable(hotkey as T, "enabled");
diff --git a/src/features/infoboxes/infobox.ts b/src/features/infoboxes/infobox.ts
index f5c7a2f..551d86c 100644
--- a/src/features/infoboxes/infobox.ts
+++ b/src/features/infoboxes/infobox.ts
@@ -91,8 +91,8 @@ export function createInfobox<T extends InfoboxOptions>(
     optionsFunc: OptionsFunc<T, BaseInfobox, GenericInfobox>
 ): Infobox<T> {
     const collapsed = persistent<boolean>(false, false);
-    return createLazyProxy(() => {
-        const infobox = optionsFunc();
+    return createLazyProxy(feature => {
+        const infobox = optionsFunc.call(feature, feature);
         infobox.id = getUniqueID("infobox-");
         infobox.type = InfoboxType;
         infobox[Component] = InfoboxComponent as GenericComponent;
diff --git a/src/features/links/links.ts b/src/features/links/links.ts
index 5b28c46..c5603c5 100644
--- a/src/features/links/links.ts
+++ b/src/features/links/links.ts
@@ -59,8 +59,8 @@ export type GenericLinks = Replace<
 export function createLinks<T extends LinksOptions>(
     optionsFunc: OptionsFunc<T, BaseLinks, GenericLinks>
 ): Links<T> {
-    return createLazyProxy(() => {
-        const links = optionsFunc();
+    return createLazyProxy(feature => {
+        const links = optionsFunc.call(feature, feature);
         links.type = LinksType;
         links[Component] = LinksComponent as GenericComponent;
 
diff --git a/src/features/particles/particles.tsx b/src/features/particles/particles.tsx
index 8edaab1..d2797d5 100644
--- a/src/features/particles/particles.tsx
+++ b/src/features/particles/particles.tsx
@@ -69,8 +69,10 @@ export type GenericParticles = Particles<ParticlesOptions>;
 export function createParticles<T extends ParticlesOptions>(
     optionsFunc?: OptionsFunc<T, BaseParticles, GenericParticles>
 ): Particles<T> {
-    return createLazyProxy(() => {
-        const particles = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>);
+    return createLazyProxy(feature => {
+        const particles =
+            optionsFunc?.call(feature, feature) ??
+            ({} as ReturnType<NonNullable<typeof optionsFunc>>);
         particles.id = getUniqueID("particles-");
         particles.type = ParticlesType;
         particles[Component] = ParticlesComponent as GenericComponent;
diff --git a/src/features/repeatable.tsx b/src/features/repeatable.tsx
index edad6bb..1a4774c 100644
--- a/src/features/repeatable.tsx
+++ b/src/features/repeatable.tsx
@@ -135,8 +135,8 @@ export function createRepeatable<T extends RepeatableOptions>(
 ): Repeatable<T> {
     const amount = persistent<DecimalSource>(0);
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const repeatable = optionsFunc();
+    return createLazyProxy(feature => {
+        const repeatable = optionsFunc.call(feature, feature);
 
         repeatable.id = getUniqueID("repeatable-");
         repeatable.type = RepeatableType;
diff --git a/src/features/reset.ts b/src/features/reset.ts
index 0bba943..b7c40ed 100644
--- a/src/features/reset.ts
+++ b/src/features/reset.ts
@@ -54,8 +54,8 @@ export type GenericReset = Reset<ResetOptions>;
 export function createReset<T extends ResetOptions>(
     optionsFunc: OptionsFunc<T, BaseReset, GenericReset>
 ): Reset<T> {
-    return createLazyProxy(() => {
-        const reset = optionsFunc();
+    return createLazyProxy(feature => {
+        const reset = optionsFunc.call(feature, feature);
         reset.id = getUniqueID("reset-");
         reset.type = ResetType;
 
diff --git a/src/features/tabs/tab.ts b/src/features/tabs/tab.ts
index d19dfdd..111f954 100644
--- a/src/features/tabs/tab.ts
+++ b/src/features/tabs/tab.ts
@@ -62,8 +62,8 @@ export type GenericTab = Tab<TabOptions>;
 export function createTab<T extends TabOptions>(
     optionsFunc: OptionsFunc<T, BaseTab, GenericTab>
 ): Tab<T> {
-    return createLazyProxy(() => {
-        const tab = optionsFunc();
+    return createLazyProxy(feature => {
+        const tab = optionsFunc.call(feature, feature);
         tab.id = getUniqueID("tab-");
         tab.type = TabType;
         tab[Component] = TabComponent as GenericComponent;
diff --git a/src/features/tabs/tabFamily.ts b/src/features/tabs/tabFamily.ts
index 316b309..2ca544b 100644
--- a/src/features/tabs/tabFamily.ts
+++ b/src/features/tabs/tabFamily.ts
@@ -156,8 +156,10 @@ export function createTabFamily<T extends TabFamilyOptions>(
     }
 
     const selected = persistent(Object.keys(tabs)[0], false);
-    return createLazyProxy(() => {
-        const tabFamily = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>);
+    return createLazyProxy(feature => {
+        const tabFamily =
+            optionsFunc?.call(feature, feature) ??
+            ({} as ReturnType<NonNullable<typeof optionsFunc>>);
 
         tabFamily.id = getUniqueID("tabFamily-");
         tabFamily.type = TabFamilyType;
diff --git a/src/features/trees/tree.ts b/src/features/trees/tree.ts
index de3616c..22aa627 100644
--- a/src/features/trees/tree.ts
+++ b/src/features/trees/tree.ts
@@ -106,8 +106,10 @@ export function createTreeNode<T extends TreeNodeOptions>(
     ...decorators: Decorator<T, BaseTreeNode, GenericTreeNode>[]
 ): TreeNode<T> {
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const treeNode = optionsFunc?.() ?? ({} as ReturnType<NonNullable<typeof optionsFunc>>);
+    return createLazyProxy(feature => {
+        const treeNode =
+            optionsFunc?.call(feature, feature) ??
+            ({} as ReturnType<NonNullable<typeof optionsFunc>>);
         treeNode.id = getUniqueID("treeNode-");
         treeNode.type = TreeNodeType;
         treeNode[Component] = TreeNodeComponent as GenericComponent;
@@ -257,8 +259,8 @@ export type GenericTree = Replace<
 export function createTree<T extends TreeOptions>(
     optionsFunc: OptionsFunc<T, BaseTree, GenericTree>
 ): Tree<T> {
-    return createLazyProxy(() => {
-        const tree = optionsFunc();
+    return createLazyProxy(feature => {
+        const tree = optionsFunc.call(feature, feature);
         tree.id = getUniqueID("tree-");
         tree.type = TreeType;
         tree[Component] = TreeComponent as GenericComponent;
diff --git a/src/features/upgrades/upgrade.ts b/src/features/upgrades/upgrade.ts
index 6137317..08fd2e6 100644
--- a/src/features/upgrades/upgrade.ts
+++ b/src/features/upgrades/upgrade.ts
@@ -123,8 +123,8 @@ export function createUpgrade<T extends UpgradeOptions>(
 ): Upgrade<T> {
     const bought = persistent<boolean>(false, false);
     const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
-    return createLazyProxy(() => {
-        const upgrade = optionsFunc();
+    return createLazyProxy(feature => {
+        const upgrade = optionsFunc.call(feature, feature);
         upgrade.id = getUniqueID("upgrade-");
         upgrade.type = UpgradeType;
         upgrade[Component] = UpgradeComponent as GenericComponent;
diff --git a/src/game/formulas/formulas.ts b/src/game/formulas/formulas.ts
index d0a0f81..9f6ad5a 100644
--- a/src/game/formulas/formulas.ts
+++ b/src/game/formulas/formulas.ts
@@ -1,7 +1,8 @@
 import { Resource } from "features/resources/resource";
+import { NonPersistent } from "game/persistence";
 import Decimal, { DecimalSource, format } from "util/bignum";
-import { Computable, convertComputable, ProcessedComputable } from "util/computed";
-import { computed, ComputedRef, ref, unref } from "vue";
+import { Computable, ProcessedComputable, convertComputable } from "util/computed";
+import { ComputedRef, Ref, computed, ref, unref } from "vue";
 import * as ops from "./operations";
 import type {
     EvaluateFunction,
@@ -58,7 +59,15 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
 
     constructor(options: FormulaOptions<T>) {
         let readonlyProperties;
+        if ("inputs" in options) {
+            options.inputs = options.inputs.map(input =>
+                typeof input === "object" && NonPersistent in input ? input[NonPersistent] : input
+            ) as T | [FormulaSource];
+        }
         if ("variable" in options) {
+            if (typeof options.variable === "object" && NonPersistent in options.variable) {
+                options.variable = options.variable[NonPersistent] as Ref<DecimalSource>;
+            }
             readonlyProperties = this.setupVariable(options);
         } else if (!("evaluate" in options)) {
             readonlyProperties = this.setupConstant(options);
@@ -364,21 +373,30 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
      * @param value The incoming formula value
      * @param condition Whether or not to apply the modifier
      * @param formulaModifier The modifier to apply to the incoming formula if the condition is true
+     * @param elseFormulaModifier An optional modifier to apply to the incoming formula if the condition is false
      */
     public static if(
         value: FormulaSource,
         condition: Computable<boolean>,
         formulaModifier: (
             value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
+        ) => GenericFormula,
+        elseFormulaModifier?: (
+            value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
         ) => GenericFormula
     ): GenericFormula {
         const lhsRef = ref<DecimalSource>(0);
-        const formula = formulaModifier(Formula.variable(lhsRef));
+        const variable = Formula.variable(lhsRef);
+        const formula = formulaModifier(variable);
+        const elseFormula = elseFormulaModifier?.(variable);
         const processedCondition = convertComputable(condition);
         function evalStep(lhs: DecimalSource) {
             if (unref(processedCondition)) {
                 lhsRef.value = lhs;
                 return formula.evaluate();
+            } else if (elseFormula) {
+                lhsRef.value = lhs;
+                return elseFormula.evaluate();
             } else {
                 return lhs;
             }
@@ -389,6 +407,8 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
             }
             if (unref(processedCondition)) {
                 return lhs.invert(formula.invert(value));
+            } else if (elseFormula) {
+                return lhs.invert(elseFormula.invert(value));
             } else {
                 return lhs.invert(value);
             }
@@ -399,15 +419,17 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
             invert: formula.isInvertible() && formula.hasVariable() ? invertStep : undefined
         });
     }
-    /** @see {@link if} */
     public static conditional(
         value: FormulaSource,
         condition: Computable<boolean>,
         formulaModifier: (
             value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
+        ) => GenericFormula,
+        elseFormulaModifier?: (
+            value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
         ) => GenericFormula
     ) {
-        return Formula.if(value, condition, formulaModifier);
+        return Formula.if(value, condition, formulaModifier, elseFormulaModifier);
     }
 
     public static abs(value: FormulaSource): GenericFormula {
diff --git a/src/game/layers.tsx b/src/game/layers.tsx
index 532daba..6294592 100644
--- a/src/game/layers.tsx
+++ b/src/game/layers.tsx
@@ -220,7 +220,7 @@ export function createLayer<T extends LayerOptions>(
         addingLayers.push(id);
         persistentRefs[id] = new Set();
         layer.minimized = persistent(false, false);
-        Object.assign(layer, optionsFunc.call(layer as BaseLayer));
+        Object.assign(layer, optionsFunc.call(layer, layer as BaseLayer));
         if (
             addingLayers[addingLayers.length - 1] == null ||
             addingLayers[addingLayers.length - 1] !== id
diff --git a/src/game/modifiers.tsx b/src/game/modifiers.tsx
index 74692b0..cceacd8 100644
--- a/src/game/modifiers.tsx
+++ b/src/game/modifiers.tsx
@@ -1,5 +1,5 @@
 import "components/common/modifiers.css";
-import type { CoercableComponent } from "features/feature";
+import type { CoercableComponent, OptionsFunc } from "features/feature";
 import { jsx } from "features/feature";
 import settings from "game/settings";
 import type { DecimalSource } from "util/bignum";
@@ -66,10 +66,13 @@ export interface AdditiveModifierOptions {
  * @param optionsFunc Additive modifier options.
  */
 export function createAdditiveModifier<T extends AdditiveModifierOptions>(
-    optionsFunc: () => T
+    optionsFunc: OptionsFunc<T>
 ): ModifierFromOptionalParams<T["description"], T["enabled"]> {
-    return createLazyProxy(() => {
-        const { addend, description, enabled, smallerIsBetter } = optionsFunc();
+    return createLazyProxy(feature => {
+        const { addend, description, enabled, smallerIsBetter } = optionsFunc.call(
+            feature,
+            feature
+        );
 
         const processedAddend = convertComputable(addend);
         const processedDescription = convertComputable(description);
@@ -128,10 +131,13 @@ export interface MultiplicativeModifierOptions {
  * @param optionsFunc Multiplicative modifier options.
  */
 export function createMultiplicativeModifier<T extends MultiplicativeModifierOptions>(
-    optionsFunc: () => T
+    optionsFunc: OptionsFunc<T>
 ): ModifierFromOptionalParams<T["description"], T["enabled"]> {
-    return createLazyProxy(() => {
-        const { multiplier, description, enabled, smallerIsBetter } = optionsFunc();
+    return createLazyProxy(feature => {
+        const { multiplier, description, enabled, smallerIsBetter } = optionsFunc.call(
+            feature,
+            feature
+        );
 
         const processedMultiplier = convertComputable(multiplier);
         const processedDescription = convertComputable(description);
@@ -191,11 +197,11 @@ export interface ExponentialModifierOptions {
  * @param optionsFunc Exponential modifier options.
  */
 export function createExponentialModifier<T extends ExponentialModifierOptions>(
-    optionsFunc: () => T
+    optionsFunc: OptionsFunc<T>
 ): ModifierFromOptionalParams<T["description"], T["enabled"]> {
-    return createLazyProxy(() => {
+    return createLazyProxy(feature => {
         const { exponent, description, enabled, supportLowNumbers, smallerIsBetter } =
-            optionsFunc();
+            optionsFunc.call(feature, feature);
 
         const processedExponent = convertComputable(exponent);
         const processedDescription = convertComputable(description);
diff --git a/src/game/requirements.tsx b/src/game/requirements.tsx
index acb7f7b..35504b6 100644
--- a/src/game/requirements.tsx
+++ b/src/game/requirements.tsx
@@ -3,6 +3,7 @@ import {
     CoercableComponent,
     isVisible,
     jsx,
+    OptionsFunc,
     Replace,
     setDefault,
     Visibility
@@ -108,10 +109,10 @@ export type CostRequirement = Replace<
  * @param optionsFunc Cost requirement options.
  */
 export function createCostRequirement<T extends CostRequirementOptions>(
-    optionsFunc: () => T
+    optionsFunc: OptionsFunc<T>
 ): CostRequirement {
-    return createLazyProxy(() => {
-        const req = optionsFunc() as T & Partial<Requirement>;
+    return createLazyProxy(feature => {
+        const req = optionsFunc.call(feature, feature) as T & Partial<Requirement>;
 
         req.partialDisplay = amount => (
             <span
diff --git a/src/util/proxies.ts b/src/util/proxies.ts
index 174378b..6e7a6f1 100644
--- a/src/util/proxies.ts
+++ b/src/util/proxies.ts
@@ -31,14 +31,14 @@ export type Proxied<T> = NonNullable<T> extends Record<PropertyKey, unknown>
 // Takes a function that returns an object and pretends to be that object
 // Note that the object is lazily calculated
 export function createLazyProxy<T extends object, S extends T>(
-    objectFunc: (baseObject: S) => T & S,
+    objectFunc: (this: S, baseObject: S) => T & S,
     baseObject: S = {} as S
 ): T {
     const obj: S & Partial<T> = baseObject;
     let calculated = false;
     function calculateObj(): T {
         if (!calculated) {
-            Object.assign(obj, objectFunc(obj));
+            Object.assign(obj, objectFunc.call(obj, obj));
             calculated = true;
         }
         return obj as S & T;
@@ -73,7 +73,7 @@ export function createLazyProxy<T extends object, S extends T>(
         },
         getOwnPropertyDescriptor(target, key) {
             if (!calculated) {
-                Object.assign(obj, objectFunc(obj));
+                Object.assign(obj, objectFunc.call(obj, obj));
                 calculated = true;
             }
             return Object.getOwnPropertyDescriptor(target, key);
diff --git a/tests/game/formulas.test.ts b/tests/game/formulas.test.ts
index ed5adb2..7da6226 100644
--- a/tests/game/formulas.test.ts
+++ b/tests/game/formulas.test.ts
@@ -868,6 +868,26 @@ describe("Conditionals", () => {
                 Formula.if(variable, false, value => Formula.sqrt(value)).invert(10)
             ).compare_tolerance(10));
     });
+    describe("Evaluates correctly with condition false and else statement", () => {
+        test("Evaluates correctly", () =>
+            expect(
+                Formula.if(
+                    constant,
+                    false,
+                    value => Formula.sqrt(value),
+                    value => value.times(2)
+                ).evaluate()
+            ).compare_tolerance(20));
+        test("Inverts correctly with variable in input", () =>
+            expect(
+                Formula.if(
+                    variable,
+                    false,
+                    value => Formula.sqrt(value),
+                    value => value.times(2)
+                ).invert(20)
+            ).compare_tolerance(10));
+    });
 
     describe("Evaluates correctly with condition true", () => {
         test("Evaluates correctly", () =>