diff --git a/Readme.md b/Readme.md
index 6150def..f41309b 100644
--- a/Readme.md
+++ b/Readme.md
@@ -22,14 +22,15 @@ game specific things:
### v1.9
- Added a new `CoopSupport.HostOnly` value.
+- Added a helper `RestartToDisable` mod class, for mods which need a restart to fully disable.
+
- Specifying a custom class when calling `build_mod` now type hints returning an instance of it,
instead of just `Mod`.
- `SliderOption`s now throw if initialized with a step larger than their allowed range.
-- Added `_(to|from)_json()` methods to all options.
-
-- Changed settings saving and loading to use above methods.
+- Added `_(to|from)_json()` methods to all options, and changed settings saving and loading to use
+ them.
### v1.8
- Fixed that nested and grouped options' children would not get their `.mod` attribute set.
diff --git a/__init__.py b/__init__.py
index 52f4244..c231b3a 100644
--- a/__init__.py
+++ b/__init__.py
@@ -31,7 +31,7 @@
from .hook import HookType, bind_all_hooks, hook
from .html_to_plain_text import html_to_plain_text
from .keybinds import EInputEvent, KeybindType, keybind
-from .mod import CoopSupport, Game, Library, Mod, ModType
+from .mod import CoopSupport, Game, Library, Mod, ModType, RestartToDisable
from .mod_factory import build_mod
from .mod_list import (
deregister_mod,
@@ -77,6 +77,7 @@
"Mod",
"ModType",
"NestedOption",
+ "RestartToDisable",
"SliderOption",
"SpinnerOption",
"ValueOption",
diff --git a/mod.py b/mod.py
index 44a0486..e050a3c 100644
--- a/mod.py
+++ b/mod.py
@@ -334,3 +334,30 @@ def get_status(self) -> str:
if Game.get_current() not in self.supported_games:
return "Incompatible"
return "Loaded"
+
+
+@dataclass
+class RestartToDisable(Mod):
+ """
+ Helper subclass for mods which cannot be fully disabled without restarting the game.
+
+ Mods will still run the normal enable/disable logic. However, after being disabled, the status
+ will show that the mod requires a restart.
+ """
+
+ _ever_enabled: bool = field(default=False, init=False, repr=False)
+
+ def enable(self) -> None:
+ """Called to enable the mod."""
+ super().enable()
+
+ # In case we weren't allowed to enable
+ if self.is_enabled:
+ self._ever_enabled = True
+
+ def get_status(self) -> str:
+ """Gets the current status of this mod."""
+ if self._ever_enabled and not self.is_enabled:
+ return "Disabling on Restart"
+
+ return super().get_status()