Currently on Roblox, it’s too hard to meaningfully convey information through a plugin button - plugin icons can only display limited state information.
The case for dynamic plugin icons
There are already plenty of examples of where plugin button icons are used to convey state. Here are a couple of quick examples from my plugins tab:
Pick - the plugin icon for the ‘Pin UI’ button indicates whether the plugin UI is currently ‘pinned’ on screen
Hidden/Infection Script Remover - changes icon to a loading spinner to show it’s scanning for scripts
Those are just from the plugins immediately available for me; I’ve seen it used for other things such as indicating when plugins have updates, or reflecting the current state of a background task, or reflecting which ‘mode’ a plugin is currently in.
The reason why this is often preferred is that it allows useful information to be displayed visibly to the user without taking up extra screen real estate, e.g. by using CoreGui or widgets to display the same information. In many cases, taking up that extra space wouldn’t be worth it for such a small amount of information.
Of course, this traditional image-based approach has its limitations. It’s extremely tedious to create and maintain several variations of the same icon. When flipping between images to create an animation, some frames are invisible, causing annoying flickering and constant UI reflow. Working with sprite sheets, or incorporating dynamic content into plugin icons, is impossible.
A solution for plugin icons
To facilitate this kind of information display, I propose a system to enable dynamic plugin button icons. While I’m not a Roblox engineer, here’s a proposition for how a possible implementation might look:
This could be achieved using a specialised GUI container, similar to how plugin widgets already work. Within this container, various UI instances can be arranged to create a customised plugin icon. You could obtain this container via a new method in PluginButton:
PluginButton:GetButtonGui(iconSize: Enum.PluginIconSize) => PluginButtonGui
This would return the GUI container for the button at the given icon size (16x16 for quick access bar, 32x32 for ribbon).
By default, if the GUI container for a given icon size is empty, the Icon property of the PluginButton is used instead, ensuring backwards compatibility. Additionally, disabling the GUI container would also revert the icon to using the Icon property of the PluginButton.
The absolute size of the GUI container would reflect the icon size, and the final rendered composition of all the instances in the GUI container would be used in all places in Studio where the icon would normally be shown.
What would this enable? Here’s a case study for one of my own plugins, Reclass.
Reclass has an ‘Automatic’ button, which automatically converts whatever you’ve selected to the top suggested class type. I’d like to display the explorer icon for the class type it’ll convert to directly on the button, but that’s impossible to do - the Studio-provided method of getting the explorer icon of a class type returns sprite sheet information, which is incompatible with plugin icons. This means you’re essentially left to guess what happens when you press it:
Have I selected something that can be converted? If so, what will it convert to? Who knows.
With dynamic plugin icons, I could display more meaningful state information:
It’s now immediately obvious what it’s going to do - it’ll convert my selection to an ImageLabel! This also demonstrates how the differentiation between different icon sizes is useful - the 16x16 icon is optimised for smaller display size, whereas the larger icon has more room to work with, so has a more complete design.
What do you think of this idea? Please leave any ideas or feedback about this, including points I might have missed