Skip to content

Instantly share code, notes, and snippets.

@maow-tty
Created July 12, 2023 22:59
Show Gist options
  • Save maow-tty/782bdb8c3ec5e0540cfc88275c760f3f to your computer and use it in GitHub Desktop.
Save maow-tty/782bdb8c3ec5e0540cfc88275c760f3f to your computer and use it in GitHub Desktop.
UI/UX Design for Minecraft Server Plugins

UI/UX Design for Minecraft Server Plugins

  • Author: maow-tty
  • Date: July 12th, 2023

This document is a set of standards for Minecraft server user interfaces. The purpose of this document is to help provide consistency amongst the plugin ecosystem and to help newer developers understand best practices when it comes to user experience.

Core Concepts

It is important for all in-game interfaces to meet the following criteria, from highest to lowest priority:

  • Confirm potentially dangerous and/or permanent actions with the user.
  • Respond to the user's inputs as quickly as possible.
  • Reduce the total effort required to navigate the interface.
  • Avoid incompatibilities and allow compatibilities with other plugins.
  • Have a comfortable look and feel, with affirming sounds and pleasing visuals.
  • Allow an alternative to using a graphical UI, i.e. commands.

We'll now touch on the various implementations of all core concepts. Non-graphical environments will be referred to as headless environments.

An example of a non-graphical environment is the server console, while a graphical environment would be what an in-game player sees.

Confirmation Dialogs

To confirm that a user has meant to perform a certain action, they should be given a prompt requiring an explicit "yes" or "no" response. Regardless of the implementation, the action and the consequences of that action should always be detailed.

In a graphical environment, dialogs are represented as chest GUIs, with the response given through two buttons (items) representing "yes" and "no" respectively. The "yes" action should always be coloured green, while the "no" action should always be coloured red.

If an interface already contains a "yes" and "no" action, a new dialog should not be spawned. Rather, the "yes" action should require two presses. The icon (item) of the action should be updated on the first press to show that confirmation is needed, and the name or description (lore) of the action should be updated to explicitly state that confirmation is needed and to press the "yes" action again to confirm. This edge case exists in situations such as shop UIs, where the user may also need to specify the amount of an item they want to purchase.

Chat Prompt

In a headless environment, one implementation of confirmation is through chat prompts. After executing a command, the next chat input is given to the command as a confirmation input. The command should state that confirmation is necessary through a message. This message should also state y or n as being valid terms.

The confirmation input is either one of two necessary sets of terms, as defined below:

  • Yes: y, yes, true, accept, confirm
  • No: n, no, false, deny, cancel

These sets can be changed depending on the language of the server, although in most cases it works to only support y and n, as those are the only terms that are stated by the confirmation message. Other terms are only included as edge cases.

If an improper term is given, then the only proper course of action is to cancel the prompt, thereby not performing the action, and to display an error message stating that the term was not accepted.

One issue with this system is that it makes automated tools less harder to use. This may be a benefit depending on the goal of the command, but in the case of complex UIs, users may want to develop helper tools that allow simplifying the execution of these commands. The introduction of the chat prompt therefore slightly complicates matters for automated tooling, but not severely.

This is the recommended solution due to the decreased probability of false positives.

An additional, optional detail is that, since this command can still be run in a graphical environment, it may be helpful to display a title or statusbar stating that the command is awaiting a confirmation input, if and only if the command was run in a graphical environment.

Confirmation Argument

An automation-friendly alternative to chat prompts is a confirmation argument. If the confirmation argument is not given, the command will refuse to execute the action, instead giving a message that the confirmation argument is needed.

The confirmation argument should never be mistaken for another argument of the command. A simple way of ensuring this is requiring it to be placed at the start or end of the command, with some irregular syntax that would otherwise be unused.

In most cases, a ! should work as a confirmation argument, as it is unlikely to be used by command frameworks (- and -- are usually reserved for command arguments) and it is impossible to include in usernames.

Ensure that the ! symbol is used freestandingly, meaning it is surrounded by spaces and not any other characters. This could otherwise cause an issue with string arguments, such as in hello!.

Do not use words such as confirm. In rare cases these can end up being player names, or possibly part of a string argument.

Example: /ban Notch "ban message here" "ban duration here" !

One major issue with this system is if a user does not include quotation marks around text like hello, world !, the text will be misunderstood as multiple arguments, with the ! being misunderstood as the confirmation argument, leading to a false positive execution. It should not expected that every user knows about the quotation marks functionality.

Confirmation Command

Rather than use an argument, a separate command can be used to confirm the action. If your command were ban, this would be named banconfirm and take no arguments, simply approving the ban command that was issued prior.

However, this can quickly bloat your command list, assuming you have multiple commands that need to be confirmed, and it would require storing, on each player, the previous command issued.

Simple Navigation

The third core concept of a well-designed UI is that UIs should not take much effort to navigate. In other words, keep it simple, stupid.

Returning

Almost all menus should support a back button or cancellation through pressing Esc. There are few exceptions to this rule. A back button should not be included in menus that do not have a parent, such as confirmation dialogs. You should not be able to cancel a menu that is, for example, used for player authentication.

Interactions

For most button actions, such as entering a menu, left-click should be used. In the case where you want one action to have a simpler default, that default can be done with left-click, right-clicking providing the full functionality.

Shift-clicking has a "take" or "take all" semantic attached to it, and shouldn't be used for other purposes.

Sub-Menus

Sub-menus are useful for enhanced organization. If you have a series of categories, each category can be represented as a sub-menu. However, if your navigation is inherently difficult and complicated, it does not help to hide everything behind sub-menus. Doing so actually increases the effort required to navigate, as commonly used functionality will be hidden behind multiple menus.

In the case of button interactions, if the default is not sensible, users will almost always use the right-click interaction, which may be a sub-menu containing expanded functionality. As such, the left-click interaction becomes effectively useless.

Information

The lore of an item can be used to store helpful, relevant information. In the case of a shop menu, a "buy" button should include the balance of a player. This eliminates the need to exit the menu temporarily to check your balance.

Additionally, the interactions a button provides should be described in its lore.

Pagination

For interfaces requiring an arbitrary, unknown amount of items, such as an auction house, a paginated menu should be used. Paginated menus are comprised of multiple pages of items, allowing you to navigate back and forth using two buttons. These buttons should either have the icon of an arrow, representing left/right arrows, or paper, representing a page.

Additionally, it may be beneficial to have buttons that allow you to navigate to the first or last page, and a button for navigating to the page at a specific index. Specifying the index can be done through a separate dialog, possibly using a counter that you increment/decrement, or through a chat prompt, requiring the user to type in the index.

Counters

While there's not much use for a counter, one can be implemented through the item count number. If your number exceeds the maximum the game allows, it may be necessary to use the item name or lore.

Incrementing and decrementing the counter should be done through clicking either the counter or an increment/decrement button. In the case of directly clicking the counter, left click should be an increment and right click should be a decrement.

Pinning

For large, complicated menus that are heavily intertwined with gameplay, users should be allowed to "pin" certain menus they use frequently. These can be accessed through a separate menu that displays each pinned menu they have.

Left-clicking opens that menu, right-clicking unpins the menu.

Incompatibilities

Plugins that use the same sections of the game can cause visual incompatibilities which lead to a more incohesive and unfriendly server experience. This can be prevented through the configuration file, where a server operator can decide which element to use to display which information from your plugin.

Your configuration file should support specifying, per message, which element to use. This can be the statusbar, bossbar, title, or, in some cases, the playerlist or scoreboard. The plugin should also allow disabling that message.

The message itself should be customizable through a language file, with sensible defaults already provided.

Compatibilities

For greater intercompatibility, you should utilize certain plugin APIs. The two primary APIs to support are Vault and PlaceholderAPI, to allow plugins to hook into your economy, or to expose placeholders that can be used by display plugins.

If possible, use Spigot's official APIs rather than NMS or ProtocolLib, as these are guaranteed not to break as much across version changes.

Look and Feel

While not a high priority target, the look and feel of a menu provides a benefit to the servers using that menu. By having a menu with nice visuals, sound effects, and possibly even particle effects, the server looks much more high-quality than it would if the menus were quiet and figuratively dead.

Design tips and guidelines:

  • Empty space should be filled by stained glass items, as these items are flat and fill the full width and height of a slot.
  • Certain actions should provide a sound effect.
    • A successful action can use a "ding" or other positive sound.
    • A failed action can use a buzzer or other negative sound.
    • Navigation may optionally use a neutral sound.
    • Sounds like an ender dragon roar can be used for major accomplishments.
    • Server-wide menu sounds must be toggleable in a player options menu of some kind.
  • Rather than limit the menus to using existing items for buttons, you can also use player heads.
  • Text, including button names, lore, and the menu title, can be coloured and customized to make it stand out more.
  • Minecraft's default font supports a few special emoji characters, which can be used by menus.
  • Menus can include animations, although this may introduce server lag if they're handled improperly.
    • Animations should be toggleable.

Commands

Rather than force your users to use the menus all the time, allowing an alternative in the form of commands also works. Adding a player to your friends list through a menu would require opening the menu, clicking the add friend button, and then typing the player's name. In comparison, /friend add <name> is simple.

Each individual part of your menu's functionality should also be accessible through a command. This command should be straight-forward in syntax and support enhanced completion and highlighting through Brigadier.

Not only is this useful as a shortcut, but headless environments cannot support UIs, so this is their only option.

Closing Notes

Taking all of the above principles and implementations into account, a well-designed menu can be achieved. Thanks for reading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment