diff --git a/lang/de.json b/lang/de.json
index 2c0dfd5f..b4beb543 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -303,10 +303,19 @@
     "DS4.ErrorItemDoesNotHaveEffect": "Das Item '{item}' hat keinen Effekt mit der ID '{id}'.",
     "DS4.ErrorActorDoesNotHaveEffect": "Der Aktor '{actor}' hat keinen Effekt mit der ID '{id}'.",
     "DS4.DialogRollOptionsCheckTargetNumberLabel": "Probenwert",
-    "DS4.DialogRollOptionsGMModifierLabel": "SL-Modifikator",
+    "DS4.DialogRollOptionsCheckModifierLabel": "Modifikator",
+    "DS4.DialogRollOptionsCheckModifierCustomLabel": "Individueller Modifikator",
     "DS4.DialogRollOptionsMaximumCoupResultLabel": "Immersieg bis",
     "DS4.DialogRollOptionsMinimumFumbleResultLabel": "Patzer ab",
     "DS4.DialogRollOptionsRollModeLabel": "Sichtbarkeit",
+    "DS4.CheckModifierRoutine": "Routine",
+    "DS4.CheckModifierVeryEasy": "Sehr Leicht",
+    "DS4.CheckModifierEasy": "Leicht",
+    "DS4.CheckModifierMormal": "Normal",
+    "DS4.CheckModifierDifficult": "Schwer",
+    "DS4.CheckModifierVeryDifficult": "Sehr Schwer",
+    "DS4.CheckModifierExtremelyDifficult": "Äußerst Schwer",
+    "DS4.CheckModifierCustom": "Individuell",
     "DS4.TooltipBaseValue": "Basiswert",
     "DS4.TooltipModifier": "Modifikator",
     "DS4.TooltipEffects": "Effekte",
diff --git a/lang/en.json b/lang/en.json
index 19973936..485e9eed 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -303,10 +303,19 @@
     "DS4.ErrorItemDoesNotHaveEffect": "The item '{item}' does not have any effect with the id '{id}'.",
     "DS4.ErrorActorDoesNotHaveEffect": "The actor '{actor}' does not have any effect with the id '{id}'.",
     "DS4.DialogRollOptionsCheckTargetNumberLabel": "Check Target Number",
-    "DS4.DialogRollOptionsGMModifierLabel": "Game Master Modifier",
+    "DS4.DialogRollOptionsCheckModifierLabel": "Modifier",
+    "DS4.DialogRollOptionsCheckModifierCustomLabel": "Custom Modifier",
     "DS4.DialogRollOptionsMaximumCoupResultLabel": "Coup to",
     "DS4.DialogRollOptionsMinimumFumbleResultLabel": "Fumble from",
     "DS4.DialogRollOptionsRollModeLabel": "Visibility",
+    "DS4.CheckModifierRoutine": "Routine",
+    "DS4.CheckModifierVeryEasy": "Very Easy",
+    "DS4.CheckModifierEasy": "Easy",
+    "DS4.CheckModifierMormal": "Normal",
+    "DS4.CheckModifierDifficult": "Difficult",
+    "DS4.CheckModifierVeryDifficult": "Very Difficult",
+    "DS4.CheckModifierExtremelyDifficult": "Extremely Difficult",
+    "DS4.CheckModifierCustom": "Custom",
     "DS4.TooltipBaseValue": "Base Value",
     "DS4.TooltipModifier": "Modifier",
     "DS4.TooltipEffects": "Effects",
diff --git a/scss/global/_accessibility.scss b/scss/global/_accessibility.scss
index cb2172cc..0456cc76 100644
--- a/scss/global/_accessibility.scss
+++ b/scss/global/_accessibility.scss
@@ -8,3 +8,8 @@
 .ds4-hidden {
     display: none;
 }
+
+// This is needed for higher specifity
+form .ds4-hidden {
+    display: none;
+}
diff --git a/src/apps/dialog-with-listeners.ts b/src/apps/dialog-with-listeners.ts
new file mode 100644
index 00000000..574bbe9d
--- /dev/null
+++ b/src/apps/dialog-with-listeners.ts
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: 2022 Johannes Loher
+//
+// SPDX-License-Identifier: MIT
+
+/**
+ * A simple extension to the {@link Dialog} class that allows attaching additional listeners.
+ */
+export class DialogWithListeners extends Dialog<DialogWithListenersOptions> {
+    /** @inheritdoc */
+    activateListeners(html: JQuery): void {
+        super.activateListeners(html);
+        if (this.options.activateAdditionalListeners !== undefined) {
+            this.options.activateAdditionalListeners(html, this);
+        }
+    }
+}
+
+interface DialogWithListenersOptions extends DialogOptions {
+    activateAdditionalListeners?: ((html: JQuery, app: DialogWithListeners) => void) | undefined;
+}
diff --git a/src/config.ts b/src/config.ts
index 731744d8..9d7ba5f7 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -331,6 +331,20 @@ const i18nKeys = {
         wakeUp: "DS4.ChecksWakeUp",
         workMechanism: "DS4.ChecksWorkMechanism",
     },
+
+    /**
+     * Translations for the standard check modifiers
+     */
+    checkModifiers: {
+        routine: "DS4.CheckModifierRoutine",
+        veryEasy: "DS4.CheckModifierVeryEasy",
+        easy: "DS4.CheckModifierEasy",
+        normal: "DS4.CheckModifierMormal",
+        difficult: "DS4.CheckModifierDifficult",
+        veryDifficult: "DS4.CheckModifierVeryDifficult",
+        extremelyDifficult: "DS4.CheckModifierExtremelyDifficult",
+        custom: "DS4.CheckModifierCustom",
+    },
 };
 
 export const DS4 = {
@@ -412,7 +426,7 @@ export const DS4 = {
     },
 
     /**
-     * Define the profile info types for handlebars of a character
+     * Profile info types for handlebars of a character
      */
     characterProfileDTypes: {
         biography: "String",
@@ -426,4 +440,17 @@ export const DS4 = {
         eyeColor: "String",
         specialCharacteristics: "String",
     },
+
+    /**
+     * Standard check modifiers
+     */
+    checkModifiers: {
+        routine: 8,
+        veryEasy: 4,
+        easy: 2,
+        normal: 0,
+        difficult: -2,
+        veryDifficult: -4,
+        extremelyDifficult: -8,
+    },
 };
diff --git a/src/hooks/setup.ts b/src/hooks/setup.ts
index 0a548f2c..84d4d380 100644
--- a/src/hooks/setup.ts
+++ b/src/hooks/setup.ts
@@ -25,6 +25,7 @@ function localizeAndSortConfigObjects() {
         "creatureSizeCategories",
         "spellCategories",
         "traits",
+        "checkModifiers",
     ];
 
     const localizeObject = <T extends { [s: string]: string }>(obj: T, sort = true): T => {
diff --git a/src/rolls/check-factory.ts b/src/rolls/check-factory.ts
index dd475d6c..ed714375 100644
--- a/src/rolls/check-factory.ts
+++ b/src/rolls/check-factory.ts
@@ -3,6 +3,8 @@
 //
 // SPDX-License-Identifier: MIT
 
+import { DialogWithListeners } from "../apps/dialog-with-listeners";
+import { DS4 } from "../config";
 import { getGame } from "../helpers";
 
 /**
@@ -31,7 +33,7 @@ const defaultCheckOptions = new DefaultCheckOptions();
 class CheckFactory {
     constructor(
         private checkTargetNumber: number,
-        private gmModifier: number,
+        private checkModifier: number,
         options: Partial<DS4CheckFactoryOptions> = {},
     ) {
         this.options = defaultCheckOptions.mergeWith(options);
@@ -58,7 +60,7 @@ class CheckFactory {
     }
 
     createCheckTargetNumberModifier(): string {
-        const totalCheckTargetNumber = Math.max(this.checkTargetNumber + this.gmModifier, 0);
+        const totalCheckTargetNumber = Math.max(this.checkTargetNumber + this.checkModifier, 0);
         return `v${totalCheckTargetNumber}`;
     }
 
@@ -85,22 +87,22 @@ export async function createCheckRoll(
     options: Partial<DS4CheckFactoryOptions> = {},
 ): Promise<ChatMessage | unknown> {
     // Ask for additional required data;
-    const gmModifierData = await askGmModifier(checkTargetNumber, options);
+    const interactiveRollData = await askForInteractiveRollData(checkTargetNumber, options);
 
-    const newTargetValue = gmModifierData.checkTargetNumber ?? checkTargetNumber;
-    const gmModifier = gmModifierData.gmModifier ?? 0;
+    const newTargetValue = interactiveRollData.checkTargetNumber ?? checkTargetNumber;
+    const checkModifier = interactiveRollData.checkModifier ?? 0;
     const newOptions: Partial<DS4CheckFactoryOptions> = {
-        maximumCoupResult: gmModifierData.maximumCoupResult ?? options.maximumCoupResult,
-        minimumFumbleResult: gmModifierData.minimumFumbleResult ?? options.minimumFumbleResult,
+        maximumCoupResult: interactiveRollData.maximumCoupResult ?? options.maximumCoupResult,
+        minimumFumbleResult: interactiveRollData.minimumFumbleResult ?? options.minimumFumbleResult,
         useSlayingDice: getGame().settings.get("ds4", "useSlayingDiceForAutomatedChecks"),
-        rollMode: gmModifierData.rollMode ?? options.rollMode,
+        rollMode: interactiveRollData.rollMode ?? options.rollMode,
         flavor: options.flavor,
         flavorData: options.flavorData,
         speaker: options.speaker,
     };
 
     // Create Factory
-    const cf = new CheckFactory(newTargetValue, gmModifier, newOptions);
+    const cf = new CheckFactory(newTargetValue, checkModifier, newOptions);
 
     // Possibly additional processing
 
@@ -109,18 +111,19 @@ export async function createCheckRoll(
 }
 
 /**
- * Responsible for rendering the modal interface asking for the modifier specified by GM and (currently) additional data.
+ * Responsible for rendering the modal interface asking for the check modifier and (currently) additional
+ * data.
  *
  * @notes
  * At the moment, this asks for more data than it will do after some iterations.
  *
  * @returns The data given by the user.
  */
-async function askGmModifier(
+async function askForInteractiveRollData(
     checkTargetNumber: number,
     options: Partial<DS4CheckFactoryOptions> = {},
     { template, title }: { template?: string; title?: string } = {},
-): Promise<Partial<IntermediateGmModifierData>> {
+): Promise<Partial<IntermediateInteractiveRollData>> {
     const usedTemplate = template ?? "systems/ds4/templates/dialogs/roll-options.hbs";
     const usedTitle = title ?? getGame().i18n.localize("DS4.DialogRollOptionsDefaultTitle");
     const templateData = {
@@ -130,43 +133,72 @@ async function askGmModifier(
         minimumFumbleResult: options.minimumFumbleResult ?? defaultCheckOptions.minimumFumbleResult,
         rollMode: options.rollMode ?? getGame().settings.get("core", "rollMode"),
         rollModes: CONFIG.Dice.rollModes,
+        checkModifiers: Object.entries(DS4.i18n.checkModifiers).map(([key, translation]) => {
+            if (key in DS4.checkModifiers) {
+                const value = DS4.checkModifiers[key as keyof typeof DS4.checkModifiers];
+                const label = `${translation} (${value >= 0 ? `+${value}` : value})`;
+                return { value, label };
+            }
+            return { value: key, label: translation };
+        }),
     };
     const renderedHtml = await renderTemplate(usedTemplate, templateData);
 
     const dialogPromise = new Promise<HTMLFormElement>((resolve) => {
-        new Dialog({
-            title: usedTitle,
-            content: renderedHtml,
-            buttons: {
-                ok: {
-                    icon: '<i class="fas fa-check"></i>',
-                    label: getGame().i18n.localize("DS4.GenericOkButton"),
-                    callback: (html) => {
-                        if (!("jquery" in html)) {
-                            throw new Error(
-                                getGame().i18n.format("DS4.ErrorUnexpectedHtmlType", {
-                                    exType: "JQuery",
-                                    realType: "HTMLElement",
-                                }),
-                            );
-                        } else {
-                            const innerForm = html[0]?.querySelector("form");
-                            if (!innerForm) {
+        new DialogWithListeners(
+            {
+                title: usedTitle,
+                content: renderedHtml,
+                buttons: {
+                    ok: {
+                        icon: '<i class="fas fa-check"></i>',
+                        label: getGame().i18n.localize("DS4.GenericOkButton"),
+                        callback: (html) => {
+                            if (!("jquery" in html)) {
                                 throw new Error(
-                                    getGame().i18n.format("DS4.ErrorCouldNotFindHtmlElement", { htmlElement: "form" }),
+                                    getGame().i18n.format("DS4.ErrorUnexpectedHtmlType", {
+                                        exType: "JQuery",
+                                        realType: "HTMLElement",
+                                    }),
                                 );
+                            } else {
+                                const innerForm = html[0]?.querySelector("form");
+                                if (!innerForm) {
+                                    throw new Error(
+                                        getGame().i18n.format("DS4.ErrorCouldNotFindHtmlElement", {
+                                            htmlElement: "form",
+                                        }),
+                                    );
+                                }
+                                resolve(innerForm);
                             }
-                            resolve(innerForm);
-                        }
+                        },
+                    },
+                    cancel: {
+                        icon: '<i class="fas fa-times"></i>',
+                        label: getGame().i18n.localize("DS4.GenericCancelButton"),
                     },
                 },
-                cancel: {
-                    icon: '<i class="fas fa-times"></i>',
-                    label: getGame().i18n.localize("DS4.GenericCancelButton"),
+                default: "ok",
+            },
+            {
+                activateAdditionalListeners: (html, app) => {
+                    const checkModifierCustomFormGroup = html.find("#check-modifier-custom").parent(".form-group");
+                    html.find("#check-modifier").on("change", (event) => {
+                        if (
+                            (event.currentTarget as HTMLSelectElement).value === "custom" &&
+                            checkModifierCustomFormGroup.hasClass("ds4-hidden")
+                        ) {
+                            checkModifierCustomFormGroup.removeClass("ds4-hidden");
+                            app.setPosition({ height: "auto" });
+                        } else if (!checkModifierCustomFormGroup.hasClass("ds4-hidden")) {
+                            checkModifierCustomFormGroup.addClass("ds4-hidden");
+                            app.setPosition({ height: "auto" });
+                        }
+                    });
                 },
             },
-            default: "ok",
-        }).render(true);
+        ).render(true);
     });
     const dialogForm = await dialogPromise;
     return parseDialogFormData(dialogForm);
@@ -176,16 +208,22 @@ async function askGmModifier(
  * Extracts Dialog data from the returned DOM element.
  * @param formData - The filed dialog
  */
-function parseDialogFormData(formData: HTMLFormElement): Partial<IntermediateGmModifierData> {
+function parseDialogFormData(formData: HTMLFormElement): Partial<IntermediateInteractiveRollData> {
     const chosenCheckTargetNumber = parseInt(formData["check-target-number"]?.value);
-    const chosenGMModifier = parseInt(formData["gm-modifier"]?.value);
+    const chosenCheckModifier = formData["check-modifier"]?.value;
+
+    const chosenCheckModifierValue =
+        chosenCheckModifier === "custom"
+            ? parseInt(formData["check-modifier-custom"]?.value)
+            : parseInt(chosenCheckModifier);
+
     const chosenMaximumCoupResult = parseInt(formData["maximum-coup-result"]?.value);
     const chosenMinimumFumbleResult = parseInt(formData["minimum-fumble-result"]?.value);
     const chosenRollMode = formData["roll-mode"]?.value;
 
     return {
         checkTargetNumber: Number.isSafeInteger(chosenCheckTargetNumber) ? chosenCheckTargetNumber : undefined,
-        gmModifier: Number.isSafeInteger(chosenGMModifier) ? chosenGMModifier : undefined,
+        checkModifier: Number.isSafeInteger(chosenCheckModifierValue) ? chosenCheckModifierValue : undefined,
         maximumCoupResult: Number.isSafeInteger(chosenMaximumCoupResult) ? chosenMaximumCoupResult : undefined,
         minimumFumbleResult: Number.isSafeInteger(chosenMinimumFumbleResult) ? chosenMinimumFumbleResult : undefined,
         rollMode: Object.keys(CONFIG.Dice.rollModes).includes(chosenRollMode) ? chosenRollMode : undefined,
@@ -195,8 +233,8 @@ function parseDialogFormData(formData: HTMLFormElement): Partial<IntermediateGmM
 /**
  * Contains data that needs retrieval from an interactive Dialog.
  */
-interface GmModifierData {
-    gmModifier: number;
+interface InteractiveRollData {
+    checkModifier: number;
     rollMode: keyof CONFIG.Dice.RollModes;
 }
 
@@ -207,15 +245,14 @@ interface GmModifierData {
  * Quite a lot of this information is requested due to a lack of automation:
  *  - maximumCoupResult
  *  - minimumFumbleResult
- *  - useSlayingDice
  *  - checkTargetNumber
  *
  * They will and should be removed once effects and data retrieval is in place.
  * If a "raw" roll dialog is necessary, create another pre-processing Dialog
  * class asking for the required information.
- * This interface should then be replaced with the `GmModifierData`.
+ * This interface should then be replaced with the `InteractiveRollData`.
  */
-interface IntermediateGmModifierData extends GmModifierData {
+interface IntermediateInteractiveRollData extends InteractiveRollData {
     checkTargetNumber: number;
     maximumCoupResult: number;
     minimumFumbleResult: number;
diff --git a/templates/dialogs/roll-options.hbs b/templates/dialogs/roll-options.hbs
index 57f76556..cf67c2a0 100644
--- a/templates/dialogs/roll-options.hbs
+++ b/templates/dialogs/roll-options.hbs
@@ -12,6 +12,7 @@ SPDX-License-Identifier: MIT
 !-- @param minimumFumbleResult: The preselected minimum fumble result.
 !-- @param rollMode: The preselected roll mode (= chat roll-mode).
 !-- @param rollModes: A map of all roll modes and their i18n keys.
+!-- @param checkModifiers: A map of all check difficulty modifiers and their translations.
 --}}
 <form class="ds4-roll-options">
     <div class="form-group">
@@ -20,8 +21,22 @@ SPDX-License-Identifier: MIT
             value="{{checkTargetNumber}}" />
     </div>
     <div class="form-group">
-        <label for="gm-modifier">{{localize "DS4.DialogRollOptionsGMModifierLabel"}}</label>
-        <input id="gm-modifier" data-dtype="Number" type="number" name="gm-modifier" value="0" />
+        <label for="check-modifier">{{localize "DS4.DialogRollOptionsCheckModifierLabel"}}</label>
+        <div class="form-fields">
+            {{log checkModifiers}}
+            <select id="check-modifier" name="check-modifier" data-dtype="String">
+                {{#select "0"}}
+                {{#each checkModifiers as |checkModifier|}}
+                <option value="{{checkModifier.value}}">{{checkModifier.label}}</option>
+                {{/each}}
+                {{/select}}
+            </select>
+        </div>
+    </div>
+    <div class="form-group ds4-hidden">
+        <label for="check-modifier-custom">{{localize "DS4.DialogRollOptionsCheckModifierCustomLabel"}}</label>
+        <input id="check-modifier-custom" data-dtype="Number" type="number" name="check-modifier-custom"
+            value="0" />
     </div>
     <div class="form-group">
         <label for="maximum-coup-result">{{localize "DS4.DialogRollOptionsMaximumCoupResultLabel"}}</label>