Back to the toolbelt

Quill

Text input without the pain!

GM sucks at text input. Quill fixes that.

Get it on itch.io >FreeCurrent release: v1.0.3
Also available in

Text input for GM that behaves like every other text input a player has used before!

Dodge the pain of text input in GM.

At some point your game needs the player to type something. A character name. A save file name. A search box. A notes field. An in-game console. Whatever it is, you sit down to implement it and you immediately remember: text input in GameMaker is a pain in the arse.

keyboard_string gives you a plain raw string. Caret positioning is manual. Text selection is manual. Clipboard is manual. Backspace, delete, home, end, ctrl+A, ctrl+C, ctrl+V…all of it manual. And that’s before you even think about placeholder text, labels, validation messages, or a right-click context menu. By the time you have something that behaves like a normal text box, you’ve written several hundred lines of code that have nothing to do with your actual game.

Quill handles all of that.

Textboxes in three lines of code.

Create a text box in your Create event:

textbox = QuillSingle("Character Name", "Enter your name...");

Draw it in your Draw GUI event:

textbox.Draw(x, y);
textbox.DrawOverlay();

That’s it. You now have a text box with a label, placeholder text, mouse click to position caret, click-drag to select, double-click to select word, triple-click to select all, Ctrl+A, Ctrl+C, Ctrl+X, Ctrl+V, Ctrl+Z, Ctrl+Y, Home, End, Shift+arrow key selection, and a right-click context menu with Cut/Copy/Paste/Select All. All of that, three lines.

Multiline compatible.

Swap QuillSingle for QuillMulti and you get a multiline text area instead. Word wrap, scrolling, resizable via a drag grip, auto-indent, tab-inserts-spaces if you want it. There’s also an overlay editor mode for when you want a small inline box that opens into a proper full editor when the user clicks into it (you might want it for things like a ‘notes’ input in a detective game UI or something like that).

notes = QuillMulti("Notes", "Write something...")
    .SetWrap(true)
    .SetResizable(true)
    .SetVisibleRows(4);

All the setters chain, so you can configure a box in one expression and move on.

Input modes (filtering the text).

Quill has a few different built-in input modes for when you need something more specific than all the possible characters a user might enter. QUILL_TEXTMODE_INT\FLOAT restricts input to numbers (with optional negative and decimal support). QUILL_TEXTMODE_PATH handles file path input. QUILL_TEXTMODE_PASSWORD masks the text, with a configurable mask character and an option to allow or deny clipboard copy. Plus a few other ones for specialty cases.

// Integer only, no negatives
speed_input = QuillSingle("Move Speed", "0")
    .SetInputMode(QUILL_TEXTMODE_INT);
// Password, using underscore as the mask character
password_box = QuillSingle("Password", "")
    .SetPasswordMask(true, "_");

You can even set your own specific function to change or reject user input via SetFilterFn, and SetAllowedChars / SetDeniedChars gives you simpler allow/block lists without having to go through the bother of writing a full custom function.

Validation.

When the player types something wrong (a letter in a textbox that should only accept numbers, for instance), you’ll probably want to tell them, so I’ve implemented a validation message system. Show an error (or warning, or info) message attached to the text box, and clear it when the input is valid again.

username_box.OnSubmit(function(_tb, _value) {
    if (string_length(_value) < 3) {
        _tb.SetValidationMessage("Name must be at least 3 characters.", "error");
    } else {
        _tb.ClearValidationMessage();
        save_character_name(_value);
    }
});

Callbacks.

You have access to five callbacks: OnChange, OnFocus, OnBlur, OnSubmit, and OnCancel. There’s also SetOnLiveChange with an optional rate limiter in milliseconds, for when you want to react to keystrokes without firing on every single one (useful for search boxes or live filtering).

BindText goes one step further: bind the textbox directly to a field on a struct so that it stays in sync automatically without you having to manually wire it up.

player_name_box.BindText(save_data, "player_name");

Tab order and focus.

When you have a form with multiple text boxes, Tab should cycle through them in a sensible order. SetTabOrder assigns a position in the cycle, and Quill handles the rest. Focus() and Blur() let you move focus programmatically, and SetSelectAllOnFocus auto-selects the contents when a box becomes active, which is usually what you want for things like score entry or settings fields. Custom context menus

The right-click context menu comes with Cut/Copy/Paste/Select All by default. You can add your own items on top of that, either globally (so they appear in every Quill textbox) or per-textbox. Separators, click callbacks, keyboard shortcut labels, enable/disable state. Basically what you’d expect from a right-click context menu.

username_box.ContextMenuAddItem(
    QuillContextMenuItem("Generate Random Name", function() {
        username_box.SetValue(generate_random_name());
    }, "random_name")
);

Theming.

Quill has a full theme system. Two built-in presets (QuillTheme_VoidMango and QuillTheme_ChunkyCandy) to get you started, or build your own with QuillTheme and its subtheme constructors. Covers fonts, textbox appearance, label styles, selection highlight, caret, scrollbar, context menu, and the overlay editor. Both primitive-drawn and 9-slice sprite options are supported throughout, so you can make it match your game’s existing art style rather than fighting against a hardcoded look.

Set a global theme for everything, or override it per-box when one needs to look different from the rest.

GET QUILL.

Get Quill on itch.io

More from the workshop

Quill
Whisper