Info variable system in Artemis
kristofbolyai opened this issue ยท 15 comments
The time has come to deal with this.
My idea is to have features expose variables (to an InfoVariableManager?) and the user can use all enabled info variables. This is clear and easy for not so basic variables, but the question comes, where do we put the simple info variables (FPS, player coordinates). Simple info variables do not require processing, so making a feature for all of them seems unnecessary. My idea would be to put them into a singular InternalFeature (as disabling them would not give any performance benefit).
I hope to hear your opinion.
@magicus @HighCrit @Incompleteusern @P0keDev @DonkeyBlaster
Do the features that expose variables need to be enabled in config just like any other feature, or is it possible to have the info boxes work out which features are required and have them automatically enable/disable? I believe this would save a lot of headache with users wondering why we "removed" certain info variables.
It would also be good to see something like math(%dry_boxes%/%dry_streak%)
where it would return the math result. This was requested a few times in legacy.
We could perhaps add automatic management of feature state, yes.
As for math, format could be more limiting (add,div,etc).
I'll give it a shot separately, if it doesn't work out as you imagined you could always let me know and take over
@DonkeyBlaster do you plan on working this yourself (in the info overlay PR or separately) or should I work on this after vacation?
You would want something like that but dependant=variable and dependency=feature.
I have quite a lot of opinions on this. I get the feeling I approach this from a somewhat different angle, so I'll just give my little speech listing what I think is important characteristics, and leave it to you how to turn that into useful code. ;-)
First of all, I think we should talk about "functions" instead. Let's have a low-level interface like this:
public interface Function {
String get(String argument);
}
This will allow us to have info "variables" with arguments. I think this can come in handy. For instance, a speed function could take in the unit type (block/second, etc) as argument. Most "variables" will be just functions without argument, but that's fine. We should support such as we do "normal" variables in legacy.
Secondly, and this is implied by the interface above, the functions should operate at a very basic level. They have a name, and return a string. They should be usable in other contexts than the "info overlays". As a concrete example, I do think that the very first implementation of these functions should be as a command, just like how configs work right now.
Examples: '/wynntils function mana should print your current mana level, or '/wynntils function speed m/s
would print your speed in meters per second.
We need to have a registry of some kind, where we list all instaces of Function
. (If that name is too general, we can name it WynntilsFunction, WFunction, or maybe even InfoFunction, in keeping with the old name). The implementations need to extract the data necessary to provide their result. Typically I assume that means dependency on Managers; hopefully not on Features. (I'd really like to avoid that.) Functions that need to have callbacks to stay updated will only have to be registered as listener if someone is observing them. That means, if they are added to an info overlay, they should be activated as listener. But that means a "one shot" read-out using /wynntils function
is allowed to return "N/A". (We might need a command to start listening, if it turns out that we need that kind of functions, if not for anything else, so for testing them.)
(Cont'd...)
The info overlay needs to have a better syntax for handling functions. I suggest we can have two forms of info overlays:
-
simple
-
template
-
means that we just give the name of a single function (possibly with a constant argument), which is then watched. As a bonus, we should also be able to set the color of this value. As a bonus bonus, the
Function
interface can be extended with apublic String name()
, which we can choose to display in front, so you can get like:Emeralds: 122
or just122
, or so. -
Means the user get full control. A string with template patterns, where we keep the & as synonom for ยง. And we make sure we have a parsable and unambigous syntax for functions, meaning we need paired delimiters for metadata.
Examples:
&1{name:speed}: &3{speed:m/s}&1 m/s
would call the special function name
which gets the name of the function given as argument, then the speed function with m/s
as argument, and then print the literal m/s
, all color coded.
&q{emeralds}
will just print emeralds with "q" formatting. (Probably easier expressed as a simple info box)
(Cont'd...)
I'd also like to see the possibility to display functions with numerical return values differently, perhaps as bars or meters or something. Maybe we should even make a basic distinction between functions returning strings and functions returning a number. (Don't need the entire int/float division, just have strings or double). Such values could e.g. have formatting built in: {[email protected]:m/s}
would print speed using any needed number of integer digits, and always print two decimals. Or suchlike.
Or we can in the future have not only textual representations, but perhaps different kinds of graphical measures.
(Cont'd...)
Finally, I think that these functions is such an important part in itself (if done right, these can possibly replace some specialized overlays from legacy, and may open up for all kinds of cool things in the future, like scripting!), that they need to have their own top level package, com.wynntils.functions
, with the framework for handling them in com.wynntils.core.functions
, in analogy with to features.
(And perhaps needless to say, having a function concept makes it easy to add non-Wynncrafty functions, like averages, evaluation of mathematical expressions, etc.)
I don't think it need to be that complicated. As long as we kind of agree on the direction, we can start very simple, and then expand. For instance, let's start without arguments, then we can add that going forward. I'll setup a simple example in a PR with just a few basic variables, to show what it could look like.
I've implemented my ideas in #291. This will set the foundation for functions, but not fully resolve all @DonkeyBlaster's needs. For instance, the info boxes still need to keep track of which functions are EnableableFunctions, and make sure these are enabled and disabled as appropriate. (This is trivial for the "simple" style, but will need a bit of thought for the "template" strings.)