Forums » Community Projects

Plugin manager request

Jan 15, 2013 tinbot link
Hello all,

I am working on a number of plugins, some of which are unrelated to each other. I am also using some plugins written by others.

I currently manage plugins manually. To disable a plugin I move it to another directory. I add notes about usage in the plugin directory.

It would be nice if there was a plugin manager.

I would like a plugin manager to add a button to the options menu, named "Plugins". The plugin button would take you to a plugin window, with tabs for each plugin.

I would like the plugin manager to have a public API, so that other people's plugins can add a tab to the manager, and populate that tab with what ever options are relevant to their plugin.

I would like for there to be a standard plugin template, that assisted new plugin writers to conform not only with the plugin manager, but with good practices in general. For example, encouraging each plugin to have an option to be enabled/disabled, an "about" button to display plugin credits, etc, and presenting those options to the plugin manager. The template should also encourage plugin writers to not depend on there being a plugin manager, and presenting other methods to the user to access options, because not every one might want to use the plugin manager.

I would also like to add the ability for users to manually add a tab for legacy plugins, manually add notes/documentation to each tab, and manually add commands to a tab, to control options on legacy plugins. This could be powerful enough such that a user might add a tab and set it up to do trivial commands like turning their radar on/off, managing alias/binds, or otherwise naming, recording, and accessing alias/binds that they would normally have to type in chat.

I would like the plugin to be open source or creative commons.

Who here would be interested in collaborating on this plugin?
Jan 15, 2013 draugath link
I've given thought to the same thing in the past. Unfortunately, without it being implemented in the client, any ability for a plugin to be managed must be programmed into the plugin itself. There's really no way to add legacy support unless you edit each older plugin to add the necessary support.

On the subject of implementation, there are a number of things that need to be considered.

Will the API be centrally managed, requiring the user to update to the latest version manually, or decentralized, allowing the plugin to package a version and then auto-update if a newer version is packaged with another plugin? (Library Framework Discussion)

The user-interface should obviously be as friendly to operate as possible. Are tabs necessarily the best approach? Tabs add extra clicks to enable or disable things, but make it possibly a little nicer to add more information.

My suggestion for the user-interface is, as you already suggested to add a button to the Options dialog labeled "Plugins". This button would then open a new dialog that utilizes a list of controls to display all of the immediately pertinent information ([en|dis]able, name, author, version) with the options to display detailed information.

How will the information be stored? Remember that we have no access to direct IO, and thusly can't create our own files on the fly. We are therefore currently limited to using either the config.ini or system notes.

The main limitation of the config.ini is that each line can be no longer than 767 characters, including the key name, separator character (=), and value. Additionally, you can't remove lines that are added to the config.ini, only blank them. This leads to bloat, which could potentially cause issues down the road. The nice thing about using config.ini is that it's accessible from the login screen and the data is not character dependent.

Using system notes allows for much more data to be easily stored, modified, and deleted. They, however, have two drawbacks. They are only accessible when logged on, and the data is not shared between characters.

The decision on data storage becomes rather obvious, considering the limitations of system notes, but it still isn't optimal.

I've started writing some notes about creating lists of controls that I'd be more than happy to share.
Jan 15, 2013 tinbot link
Thank you for your input.

I would like to support legacy plugins, but the priority is new plugins. If it can not support legacy, that is a tolerable situation. However, my rational for a user to be able to manually add tabs/commands, is that they could manually build support for a legacy plugin from the manager side.

I suggest that until the plugin is actually useful in some context, issues of centralized/decentralized default to the easiest to implement option.

Tabs where the interface I envisioned, but I am open to options. The manager itself could have it's own tab, and even subtabs, and one of those subtabs could be a table view. Another options is that some other plugin could come along, and create a table view, or some other view. I suggest that we pick the simplest implementation, and leave some of the eye candy to other plugins.

Most information storage issues are not the problem of the manager. The manager primarily provides a user interface. Storing option settings is the problem of the plugin that offers the option. For any manager specific storage needs, the method of storage could be an option in the manager tab.

I am used to a rapid development approach, of building the minimum, and expanding on it.

Can we make a plugin that adds the button to the options menu "Plugins", that opens a window, with a "Close" button, and one tab:"Plugin Manager", with that one tab having an "About" button: That opens a new window with credits and other information?

And also make a plugin template, that is not just a template, but a working plugin, that adds a tab:"Plugin template", and adds a button:"About", that opens a window with some information? I would like the template to start with variables that define the Tab name, and the "About" text.

I am not sure of plugin load order, so can we have the template isolate all the manager setup to a single function, have the template check if the manager is already loaded, and if so, call the setup function, and if not, load it's setup function into a table, and then when the manager loads, it checks if the table exist, and if so, starts running the functions in it?
Jan 15, 2013 draugath link
Under normal conditions, plugins are loaded in ASCIIbetical order. The big thing to remember is that plugins will always be loaded if they exist and have a main.lua, unless something in the main.lua stops it. This is why plugins that aren't programmed to support the plugin manager can't simply be shoe-horned in.

The first time the plugin manager is installed and run, all plugins that support it would be loaded as per usual. From there users would be able to use the manager to start (en|dis)abling support plugins. When a plugin's state is toggled, it should write a value to config.ini which is used on later loads to determine if execution of main.lua should continue.

I think the best approach for initializing the manager would be to simply have each plugin that supports it register itself in a table. During the initial load sequence the manager won't do anything specific to supported plugins. When the PLUGINS_LOADED event triggers, this would likely be the best time to read the table of registered plugins and initialize the lists/tabs.

In addition to everything that's already been discussed, an important element that has been glossed over is the subject of metadata. What descriptors should be supported and how should they be stored/read. Some obvious descriptors I've already mentioned in my previous post: (Plugin name, author, version, description). How to store them is slightly trickier.

The seemingly obvious solution would be to create another file (e.g. metadata.lua) which could be dofile()ed and have it simply return a table with the descriptors and their values. For a plugin acting as a manager, this should be acceptable. When I originally wrote my mockup for a client-side plugin loader this would be unacceptable since it could introduce extra code before any is supposed to be loaded.

While I understand your desire to get things moving, I'd caution waiting for more input if you want this to be community driven. Mockups of the interface and API can definitely be started on, but there are still some rather knowledgeable people in the plugin coding community that may have something else to add.

Here's a very quick mockup of how I think the main interface should look.
I wasn't trying to make it look pretty, just get the idea across.
Jan 16, 2013 meridian link
I like the idea of a plug-in manager, but it really needs to be something built-in to the client to be done right. The biggest advantage being that it would support enabling/disabling all plug-ins without requiring the plug-in author to add code specifically to that end. A plug-in manager is less useful when only half the plug-ins present support it.

Storing the enabled state of all plug-ins in the config.ini is okay, but plug-ins shouldn't read the value from the config directly to check if they should enable themselves. A better approach would be to querry the plugin manager, which reads the config.ini and returns the result, allowing the method of storing the state data to be changed in the future transparently to other plugins.

EDIT: Plus you wouldn't want a plug-in other than the manager writing the values in the config.ini, so better to not include the config.ini details in the API.

When a plugin's state is toggled, it should write a value to config.ini which is used on later loads to determine if execution of main.lua should continue.

Maybe I misread, but that seems to imply to me that changes to the enable/disable state of a plug-in would be written to the config.ini, but there'd not actually be any change to the active plug-ins until the player manually triggers an interface reload. I would make it so a reload is triggered automatically when the manager dialog is closed if there had been any state changes. Otherwise it could be confusing since the next time the manager dialog is opened (assuming no reload occurred), the state of the checkboxes wouldn't match the plug-ins that are actually enabled.

Storing metadata in an xml file would probably be the best approach (though would require the devs to add support for such a feature, and would make sense more for a plug-in manager built-in to the client). Keeping it in a separate lua file is a reasonable compromise for a community designed plug-in manager.

The one metadata entry I would add would be some sort of unique identifier to each plug-in (think about how many different versions of Autojett there are out there). I suppose it could work to concatenate the plug-in name with the author name or somesuch. If the latter approach is used, it would be a good idea to think about which text characters should be allowed for plugin name and author.

Using the name of the directory containing the main.lua of each plug-in is a good way to ensure uniqueness, but I don't believe there is any way for a plug-in (i.e. the plug-in manager) to access what the directory names are. It would also lead to bloat in the config.ini each time a directory name is changed.


As far as the interface goes, I would not display the description in the mockup matrix of plugins above. A description of three words isn't so bad, but anything longer would stress the interface. Checkout the plug-in list at VOUPR: very few descriptions contain fewer than six words, and some are considerably longer.

I would propose something more like the mock-up below. Have a matrix on the left to enable/disable plug-ins, and on the right give more detailed info about the selected plug-in. I would keep author as an entry in the matrix to allow sorting, and keep version as a matrix entry in case multiple versions of the same plug-in are present (maybe you want to toggle between two or more versions?).

Including an options button in the detailed info on the right side would be a good way to standardize accessing a plug-in's main dialog (and not require having to remember a bunch of console commands). I'm torn as to whether it would be a better idea to include more detailed info about the plug-in (e.g. a list of available commands or help text) in the description text or to have a separate info/help button that would open an additional dialog (in which case an F1 hotkey would be standard).

Jan 19, 2013 tinbot link
I can see where I may have started overly ambitious.

In further pursuit of a minimalist solution:

How about a table, named "plugin gui entries", where any plugin can make a single entry {"button text","label text"}, that our plugin will use to present a strait forward table (with scroll bar) like the display in draugath's last post, or the table on the left side of meridian's last post.

This makes for a very simple implementation.

The idea here is that a plugin might show nothing more than usage notes, having no other gui to speak of, while other plugin have the option of having a gui anyway they like.

I also hope someone can think of a better name for the table, and this plugin.

edit: opps. I messed up. I meant a table with {"text",function}, where the table is just a single column of buttons, with each button showing "text".
Jan 19, 2013 draugath link
Here's the code I used to make that mockup.

It uses a template I wrote which can be found here.
Jan 20, 2013 tinbot link
thanks draugath.

anyone know how to add a button to vo's options menu?
Jan 20, 2013 draugath link
It's not easy. TCS does it though
Feb 19, 2013 Scuba Steve 9.0 link
It's relatively easy. TCS does this. TCS also acts as its own plugin manger for each component. Feel free to poach code from it if you'd like.
Feb 20, 2013 draugath link
Relative to what? Anytime you start monkeying with IUP, especially controls that were created by someone else, you run a strong chance of creating client instabilities. Remember VOClock, Scuba?

Does it have to be like that? No, but our documentation explaining all of the intricacies and pitfalls is a little lacking.
Feb 20, 2013 abortretryfail link
TCS also acts as its own plugin manger for each component. Feel free to poach code from it if you dare.
Feb 21, 2013 Kierky link
It would be better if we had a plugin manager which is built into the game. That way plugins wouldn't be so unknown, and would give a better way to test bugs, etc.
Feb 21, 2013 Scuba Steve 9.0 link
Hooking into the menu iup controls took, like, ten minutes to do the first time and worked fine forever so far. VOClock is wholly different case, in that I originally made TCS to enhance my experience and only shared it with everyone else to prevent accusations of unfair play, and being able to rescale the HUD never enhanced my own play (since I never did it), so I didn't put much effort into finding a solution. Doing stuff like making the MakeFriends MakeFriends main window have all the fancy-looking colors was mostly because they made things easier for me to read at a glance.

That saaid, my plugins ended up going the route of hooking themselves into default iup controls anyway, so my idea of "relatively easy" might be more than a bit warped. That was the most unobtrusive way I figured out how to do it and, if my total shunning of targetless is any hint, I've got a fetish for things being unobtrusive. Central being built up and around the existing UI elements in the center of the HUD and AlertMachine just spitting a naturally-colored line or two into chat when necessary. Or even the Itan encryption decoder I made a long while ago when (poorly) coded channels was all the rage-- that decrypted the messages in-place into the chat box with a single character indicating it was ever encrypted in the first place.

Kierky: Probably. TCS seems to do this in a relatively straightforward way (at least to me) that'd be cool, but it doesn't account for collisions or anything that'd surely up the overall complexity of a solution.
Feb 25, 2013 abortretryfail link
Yeah, the VOclock problem is reallly easy to avoid. Just unbind F5 and you're golden. :)
Jun 11, 2013 zak.wilson link
This thread has a high probability of remaining relevant. I have nothing to add, but the devs insist on autolocking threads when they haven't had a reply in a while, so I'm replying.
Dec 13, 2015 Michael144 link
Can some one start working on a alpha plugin manager
Dec 13, 2015 draugath link
I already have a working manager that just needs to be reviewed. But it's been waiting for review for about a year or two now.