diff --git a/src/App.vue b/src/App.vue
index 6a365ef..ebdf971 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -6,6 +6,7 @@
             <Nav v-if="useHeader" />
             <Game />
             <TPS v-if="unref(showTPS)" />
+            <AddictionWarning />
             <GameOverScreen />
             <NaNScreen />
             <component :is="gameComponent" />
@@ -16,14 +17,14 @@
 <script setup lang="tsx">
 import "@fontsource/roboto-mono";
 import Error from "components/Error.vue";
+import AddictionWarning from "components/modals/AddictionWarning.vue";
+import GameOverScreen from "components/modals/GameOverScreen.vue";
+import NaNScreen from "components/modals/NaNScreen.vue";
 import { jsx } from "features/feature";
 import state from "game/state";
 import { coerceComponent, render } from "util/vue";
-import { CSSProperties, watch } from "vue";
-import { computed, toRef, unref } from "vue";
+import { CSSProperties, computed, toRef, unref } from "vue";
 import Game from "./components/Game.vue";
-import GameOverScreen from "./components/GameOverScreen.vue";
-import NaNScreen from "./components/NaNScreen.vue";
 import Nav from "./components/Nav.vue";
 import TPS from "./components/TPS.vue";
 import projInfo from "./data/projInfo.json";
@@ -69,3 +70,4 @@ const gameComponent = computed(() => {
     position: static;
 }
 </style>
+./components/modals/GameOverScreen.vue./components/modals/NaNScreen.vue
\ No newline at end of file
diff --git a/src/components/Nav.vue b/src/components/Nav.vue
index c5d0026..4c8ef93 100644
--- a/src/components/Nav.vue
+++ b/src/components/Nav.vue
@@ -101,9 +101,9 @@ import Tooltip from "features/tooltips/Tooltip.vue";
 import { Direction } from "util/common";
 import type { ComponentPublicInstance } from "vue";
 import { ref } from "vue";
-import Info from "./Info.vue";
-import Options from "./Options.vue";
-import SavesManager from "./SavesManager.vue";
+import Info from "./modals/Info.vue";
+import Options from "./modals/Options.vue";
+import SavesManager from "./modals/SavesManager.vue";
 
 const info = ref<ComponentPublicInstance<typeof Info> | null>(null);
 const savesManager = ref<ComponentPublicInstance<typeof SavesManager> | null>(null);
@@ -265,3 +265,4 @@ function openDiscord() {
     text-shadow: none;
 }
 </style>
+./modals/Info.vue./modals/Options.vue./modals/SavesManager.vue
diff --git a/src/components/modals/AddictionWarning.vue b/src/components/modals/AddictionWarning.vue
new file mode 100644
index 0000000..14eaf1e
--- /dev/null
+++ b/src/components/modals/AddictionWarning.vue
@@ -0,0 +1,83 @@
+<template>
+    <Modal v-model="isOpen" v-bind="$attrs">
+        <template v-slot:header>
+            <div class="vga-modal-header">
+                <h2>Kindly consider taking a break.</h2>
+            </div>
+        </template>
+        <template v-slot:body>
+            <p>
+                You've been actively enjoying this game for awhile recently - and it's great that
+                you've been having a good time! That said, there are dangers to games like these that you should be aware of:
+            </p>
+            <p>
+                While incremental games can be fun and even healthy in certain contexts, they can
+                exacerbate video game addiction even more than other genres. If you feel like
+                playing incremental games is taking priority over other things in your life, or
+                manipulating your sleep schedule, it may be prudent to seek help.
+            </p>
+            <p>
+                <h4>Resources:</h4>
+                <span>
+                    <a style="display: inline" href="https://www.samhsa.gov/" target="_blank">
+                        SAMHSA
+                    </a>
+                    (<a style="display: inline" href="tel:1-800-662-4357">1-800-662-HELP</a>)
+                </span>
+                <br />
+                <a href="https://www.reddit.com/r/StopGaming/">r/StopGaming</a>
+            </p>
+        </template>
+        <template v-slot:footer>
+            <div class="vga-footer">
+                <button @click="neverShow" class="button">Never show this again</button>
+                <button @click="isOpen = false" class="button">Close</button>
+            </div>
+        </template>
+    </Modal>
+    <SavesManager ref="savesManager" />
+</template>
+
+<script setup lang="ts">
+import projInfo from "data/projInfo.json";
+import settings from "game/settings";
+import state from "game/state";
+import { ref, watchEffect } from "vue";
+import Modal from "./Modal.vue";
+
+const isOpen = ref(false);
+watchEffect(() => {
+    if (
+        projInfo.disableHealthWarning === false &&
+        settings.showHealthWarning &&
+        state.mouseActivity.filter(i => i).length > 6
+    ) {
+        isOpen.value = true;
+    }
+});
+
+function neverShow() {
+    settings.showHealthWarning = false;
+    isOpen.value = false;
+}
+</script>
+
+<style scoped>
+.vga-modal-header {
+    padding-top: 10px;
+    margin-left: 10px;
+}
+
+.vga-footer {
+    display: flex;
+    justify-content: flex-end;
+}
+
+.vga-footer button {
+    margin: 0 10px;
+}
+
+p {
+    margin-bottom: 10px;
+}
+</style>
diff --git a/src/components/GameOverScreen.vue b/src/components/modals/GameOverScreen.vue
similarity index 97%
rename from src/components/GameOverScreen.vue
rename to src/components/modals/GameOverScreen.vue
index 999554d..e7e375a 100644
--- a/src/components/GameOverScreen.vue
+++ b/src/components/modals/GameOverScreen.vue
@@ -37,14 +37,14 @@
 </template>
 
 <script setup lang="ts">
-import Modal from "components/Modal.vue";
 import { hasWon } from "data/projEntry";
 import projInfo from "data/projInfo.json";
 import player from "game/player";
 import { formatTime } from "util/bignum";
 import { loadSave, newSave } from "util/save";
 import { computed, toRef } from "vue";
-import Toggle from "./fields/Toggle.vue";
+import Toggle from "../fields/Toggle.vue";
+import Modal from "./Modal.vue";
 
 const { title, logo, discordName, discordLink, versionNumber, versionTitle } = projInfo;
 
diff --git a/src/components/Info.vue b/src/components/modals/Info.vue
similarity index 98%
rename from src/components/Info.vue
rename to src/components/modals/Info.vue
index 15395bf..12be65d 100644
--- a/src/components/Info.vue
+++ b/src/components/modals/Info.vue
@@ -60,7 +60,6 @@
 </template>
 
 <script setup lang="tsx">
-import Modal from "components/Modal.vue";
 import type Changelog from "data/Changelog.vue";
 import projInfo from "data/projInfo.json";
 import { jsx } from "features/feature";
@@ -69,6 +68,7 @@ import { infoComponents } from "game/settings";
 import { formatTime } from "util/bignum";
 import { coerceComponent, render } from "util/vue";
 import { computed, ref, toRefs, unref } from "vue";
+import Modal from "./Modal.vue";
 
 const { title, logo, author, discordName, discordLink, versionNumber, versionTitle } = projInfo;
 
diff --git a/src/components/Modal.vue b/src/components/modals/Modal.vue
similarity index 98%
rename from src/components/Modal.vue
rename to src/components/modals/Modal.vue
index 9fd5f06..728807e 100644
--- a/src/components/Modal.vue
+++ b/src/components/modals/Modal.vue
@@ -41,7 +41,7 @@
 <script setup lang="ts">
 import type { FeatureNode } from "game/layers";
 import { computed, ref, toRefs, unref } from "vue";
-import Context from "./Context.vue";
+import Context from "../Context.vue";
 
 const _props = defineProps<{
     modelValue: boolean;
diff --git a/src/components/NaNScreen.vue b/src/components/modals/NaNScreen.vue
similarity index 97%
rename from src/components/NaNScreen.vue
rename to src/components/modals/NaNScreen.vue
index f9c7b6f..f8735f4 100644
--- a/src/components/NaNScreen.vue
+++ b/src/components/modals/NaNScreen.vue
@@ -46,7 +46,6 @@
 </template>
 
 <script setup lang="ts">
-import Modal from "components/Modal.vue";
 import projInfo from "data/projInfo.json";
 import player from "game/player";
 import state from "game/state";
@@ -54,7 +53,8 @@ import type { DecimalSource } from "util/bignum";
 import Decimal, { format } from "util/bignum";
 import type { ComponentPublicInstance } from "vue";
 import { computed, ref, toRef, watch } from "vue";
-import Toggle from "./fields/Toggle.vue";
+import Toggle from "../fields/Toggle.vue";
+import Modal from "./Modal.vue";
 import SavesManager from "./SavesManager.vue";
 
 const { discordName, discordLink } = projInfo;
diff --git a/src/components/Options.vue b/src/components/modals/Options.vue
similarity index 86%
rename from src/components/Options.vue
rename to src/components/modals/Options.vue
index 93b57fa..11df99e 100644
--- a/src/components/Options.vue
+++ b/src/components/modals/Options.vue
@@ -14,6 +14,7 @@
                 <Toggle :title="unthrottledTitle" v-model="unthrottled" />
                 <Toggle v-if="projInfo.enablePausing" :title="isPausedTitle" v-model="isPaused" />
                 <Toggle :title="offlineProdTitle" v-model="offlineProd" />
+                <Toggle :title="showHealthWarningTitle" v-model="showHealthWarning" v-if="!projInfo.disableHealthWarning" />
                 <Toggle :title="autosaveTitle" v-model="autosave" />
                 <FeedbackButton v-if="!autosave" class="button save-button" @click="save()">Manually save</FeedbackButton>
             </div>
@@ -28,20 +29,20 @@
 </template>
 
 <script setup lang="tsx">
-import Modal from "components/Modal.vue";
 import projInfo from "data/projInfo.json";
-import { save } from "util/save";
 import rawThemes from "data/themes";
 import { jsx } from "features/feature";
 import Tooltip from "features/tooltips/Tooltip.vue";
 import player from "game/player";
 import settings, { settingFields } from "game/settings";
 import { camelToTitle, Direction } from "util/common";
+import { save } from "util/save";
 import { coerceComponent, render } from "util/vue";
 import { computed, ref, toRefs } from "vue";
-import Select from "./fields/Select.vue";
-import Toggle from "./fields/Toggle.vue";
-import FeedbackButton from "./fields/FeedbackButton.vue";
+import FeedbackButton from "../fields/FeedbackButton.vue";
+import Select from "../fields/Select.vue";
+import Toggle from "../fields/Toggle.vue";
+import Modal from "./Modal.vue";
 
 const isOpen = ref(false);
 const currentTab = ref("behaviour");
@@ -72,7 +73,7 @@ const settingFieldsComponent = computed(() => {
     return coerceComponent(jsx(() => (<>{settingFields.map(render)}</>)));
 });
 
-const { showTPS, theme, unthrottled, alignUnits } = toRefs(settings);
+const { showTPS, theme, unthrottled, alignUnits, showHealthWarning } = toRefs(settings);
 const { autosave, offlineProd } = toRefs(player);
 const isPaused = computed({
     get() {
@@ -91,10 +92,16 @@ const unthrottledTitle = jsx(() => (
 ));
 const offlineProdTitle = jsx(() => (
     <span class="option-title">
-        Offline Production<Tooltip display="Save-specific" direction={Direction.Right}>*</Tooltip>
+        Offline production<Tooltip display="Save-specific" direction={Direction.Right}>*</Tooltip>
         <desc>Simulate production that occurs while the game is closed.</desc>
     </span>
 ));
+const showHealthWarningTitle = jsx(() => (
+    <span class="option-title">
+        Show videogame addiction warning
+        <desc>Show a helpful warning after playing for a long time about video game addiction and encouraging you to take a break.</desc>
+    </span>
+));
 const autosaveTitle = jsx(() => (
     <span class="option-title">
         Autosave<Tooltip display="Save-specific" direction={Direction.Right}>*</Tooltip>
diff --git a/src/components/Save.vue b/src/components/modals/Save.vue
similarity index 96%
rename from src/components/Save.vue
rename to src/components/modals/Save.vue
index 77d2988..1876860 100644
--- a/src/components/Save.vue
+++ b/src/components/modals/Save.vue
@@ -74,9 +74,9 @@ import Tooltip from "features/tooltips/Tooltip.vue";
 import player from "game/player";
 import { Direction } from "util/common";
 import { computed, ref, toRefs, watch } from "vue";
-import DangerButton from "./fields/DangerButton.vue";
-import FeedbackButton from "./fields/FeedbackButton.vue";
-import Text from "./fields/Text.vue";
+import DangerButton from "../fields/DangerButton.vue";
+import FeedbackButton from "../fields/FeedbackButton.vue";
+import Text from "../fields/Text.vue";
 import type { LoadablePlayerData } from "./SavesManager.vue";
 
 const _props = defineProps<{
@@ -202,3 +202,4 @@ function changeName() {
     margin: 0;
 }
 </style>
+./modals/SavesManager.vue
diff --git a/src/components/SavesManager.vue b/src/components/modals/SavesManager.vue
similarity index 98%
rename from src/components/SavesManager.vue
rename to src/components/modals/SavesManager.vue
index b1bf7e0..f40cec8 100644
--- a/src/components/SavesManager.vue
+++ b/src/components/modals/SavesManager.vue
@@ -57,7 +57,6 @@
 </template>
 
 <script setup lang="ts">
-import Modal from "components/Modal.vue";
 import projInfo from "data/projInfo.json";
 import type { Player } from "game/player";
 import player, { stringifySave } from "game/player";
@@ -67,8 +66,9 @@ import { getUniqueID, loadSave, newSave, save } from "util/save";
 import type { ComponentPublicInstance } from "vue";
 import { computed, nextTick, ref, shallowReactive, watch } from "vue";
 import Draggable from "vuedraggable";
-import Select from "./fields/Select.vue";
-import Text from "./fields/Text.vue";
+import Select from "../fields/Select.vue";
+import Text from "../fields/Text.vue";
+import Modal from "./Modal.vue";
 import Save from "./Save.vue";
 
 export type LoadablePlayerData = Omit<Partial<Player>, "id"> & { id: string; error?: unknown };
@@ -332,3 +332,4 @@ function editSave(id: string, newName: string) {
     visibility: hidden;
 }
 </style>
+./Save.vue
diff --git a/src/data/Changelog.vue b/src/data/Changelog.vue
index 54e53a5..675fe38 100644
--- a/src/data/Changelog.vue
+++ b/src/data/Changelog.vue
@@ -19,7 +19,7 @@
 </template>
 
 <script setup lang="ts">
-import Modal from "components/Modal.vue";
+import Modal from "components/modals/Modal.vue";
 import { ref } from "vue";
 
 const isOpen = ref(false);
diff --git a/src/data/projInfo-schema.json b/src/data/projInfo-schema.json
index 0cea13c..ceb448e 100644
--- a/src/data/projInfo-schema.json
+++ b/src/data/projInfo-schema.json
@@ -88,6 +88,10 @@
             "type": "string",
             "enum": ["base64", "lz", "plain"],
             "description": "The encoding to use when exporting to the clipboard. Plain-text is fast to generate but is easiest for the player to manipulate and cheat with. Base 64 is slightly slower and the string will be longer but will offer a small barrier to people trying to cheat. LZ-String is the slowest method, but produces the smallest strings and still offers a small barrier to those trying to cheat. Some sharing platforms like pastebin may automatically delete base64 encoded text, and some sites might not support all the characters used in lz-string exports."
+        },
+        "disableHealthWarning": {
+            "type": "boolean",
+            "description": "Whether or not to disable the health warning that appears to the player after excessive playtime (activity during 6 of the last 8 hours). If left enabled, the player will still be able to individually turn off the health warning in settings or by clicking \"Do not show again\" in the warning itself."
         }
     }
 }
\ No newline at end of file
diff --git a/src/data/projInfo.json b/src/data/projInfo.json
index b32ef22..6618d79 100644
--- a/src/data/projInfo.json
+++ b/src/data/projInfo.json
@@ -22,5 +22,6 @@
 	"maxTickLength": 3600,
 	"offlineLimit": 1,
 	"enablePausing": true,
-	"exportEncoding": "base64"
+	"exportEncoding": "base64",
+	"disableHealthWarning": false
 }
diff --git a/src/game/events.ts b/src/game/events.ts
index a167042..9e74714 100644
--- a/src/game/events.ts
+++ b/src/game/events.ts
@@ -2,6 +2,7 @@ import type { Settings } from "game/settings";
 import { createNanoEvents } from "nanoevents";
 import type { App } from "vue";
 import type { GenericLayer } from "./layers";
+import state from "./state";
 
 /** All types of events able to be sent or emitted from the global event bus. */
 export interface GlobalEvents {
@@ -59,3 +60,7 @@ if ("fonts" in document) {
     // JSDom doesn't add document.fonts, and Object.defineProperty doesn't seem to work on document
     document.fonts.onloadingdone = () => globalBus.emit("fontsLoaded");
 }
+
+document.onmousemove = function () {
+    state.mouseActivity[state.mouseActivity.length - 1] = true;
+};
diff --git a/src/game/gameLoop.ts b/src/game/gameLoop.ts
index b001dd6..a50476d 100644
--- a/src/game/gameLoop.ts
+++ b/src/game/gameLoop.ts
@@ -107,3 +107,7 @@ export async function startGameLoop() {
         intervalID = setInterval(update, 50);
     }
 }
+
+setInterval(() => {
+    state.mouseActivity = [...state.mouseActivity.slice(-7), false];
+}, 1000 * 60 * 60);
diff --git a/src/game/layers.tsx b/src/game/layers.tsx
index bbb6079..7e82ead 100644
--- a/src/game/layers.tsx
+++ b/src/game/layers.tsx
@@ -1,4 +1,4 @@
-import Modal from "components/Modal.vue";
+import Modal from "components/modals/Modal.vue";
 import type {
     CoercableComponent,
     JSXFunction,
diff --git a/src/game/settings.ts b/src/game/settings.ts
index 0748d68..52ff08d 100644
--- a/src/game/settings.ts
+++ b/src/game/settings.ts
@@ -20,6 +20,8 @@ export interface Settings {
     unthrottled: boolean;
     /** Whether to align modifiers to the unit. */
     alignUnits: boolean;
+    /** Whether or not to show a video game health warning after playing excessively. */
+    showHealthWarning: boolean;
 }
 
 const state = reactive<Partial<Settings>>({
@@ -28,7 +30,8 @@ const state = reactive<Partial<Settings>>({
     showTPS: true,
     theme: Themes.Nordic,
     unthrottled: false,
-    alignUnits: false
+    alignUnits: false,
+    showHealthWarning: true
 });
 
 watch(
@@ -56,12 +59,15 @@ declare global {
 export default window.settings = state as Settings;
 /** A function that erases all player settings, including all saves. */
 export const hardResetSettings = (window.hardResetSettings = () => {
-    const settings = {
+    // Only partial because of any properties that are only added during the loadSettings event.
+    const settings: Partial<Settings> = {
         active: "",
         saves: [],
         showTPS: true,
         theme: Themes.Nordic,
-        alignUnits: false
+        unthrottled: false,
+        alignUnits: false,
+        showHealthWarning: true
     };
     globalBus.emit("loadSettings", settings);
     Object.assign(state, settings);
diff --git a/src/game/state.ts b/src/game/state.ts
index 9e672c3..95c17bb 100644
--- a/src/game/state.ts
+++ b/src/game/state.ts
@@ -6,6 +6,8 @@ import type { Persistent } from "./persistence";
 export interface Transient {
     /** A list of the duration, in ms, of the last 10 game ticks. Used for calculating TPS. */
     lastTenTicks: number[];
+    /** A list of bools represnting which of the last few hours had mouse activity. */
+    mouseActivity: boolean[];
     /** Whether or not a NaN value has been detected and undealt with. */
     hasNaN: boolean;
     /** The location within the player save data object of the NaN value. */
@@ -25,6 +27,7 @@ declare global {
 /** The global transient state object. */
 export default window.state = shallowReactive<Transient>({
     lastTenTicks: [],
+    mouseActivity: [false],
     hasNaN: false,
     NaNPath: [],
     errors: reactive([])